runo 0.1.1 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/lib/_parser.rb +2 -2
- data/lib/_path.rb +2 -2
- data/lib/_storage/file.rb +1 -1
- data/lib/_storage/sequel.rb +2 -2
- data/lib/_widget/submit.rb +1 -1
- data/lib/meta/id.rb +1 -1
- data/lib/meta/timestamp.rb +1 -1
- data/lib/runo.rb +3 -3
- data/lib/scalar/checkbox.rb +2 -2
- data/lib/scalar/file.rb +1 -1
- data/lib/scalar/img.rb +1 -1
- data/lib/scalar/password.rb +2 -2
- data/lib/scalar/radio.rb +2 -2
- data/lib/scalar/select.rb +2 -2
- data/lib/scalar/text.rb +1 -1
- data/lib/scalar/textarea.rb +1 -1
- data/lib/set/dynamic.rb +1 -1
- data/lib/set/static.rb +2 -2
- data/lib/set/static_folder.rb +3 -3
- data/skel/skin/examples/index.html +0 -2
- data/skel/skin/index.html +0 -2
- data/t/skin/foo/qux/index.html +8 -0
- data/t/skin/foo/qux/moo/index.html +6 -0
- data/t/test_runo.rb +26 -0
- data/t/test_runo_call.rb +5 -10
- metadata +5 -3
data/lib/_parser.rb
CHANGED
@@ -86,7 +86,7 @@ module Runo::Parser
|
|
86
86
|
s = StringScanner.new html
|
87
87
|
until s.eos?
|
88
88
|
if s.scan /\$\((\w+)(?:\s+|\s*=\s*)([\w\-]+)\s*/m
|
89
|
-
out << block.call(s[1], {:klass => s[2]}.merge(scan_tokens
|
89
|
+
out << block.call(s[1], {:klass => s[2]}.merge(scan_tokens(s)))
|
90
90
|
else
|
91
91
|
out << s.scan(/.+?(?=\$|\w|<|\z)/m)
|
92
92
|
end
|
@@ -180,7 +180,7 @@ module Runo::Parser
|
|
180
180
|
'default' => item_meta,
|
181
181
|
},
|
182
182
|
}
|
183
|
-
(inner_html =~ /\A\s*<!--(.+?)-->/m) ? sd.merge(scan_tokens
|
183
|
+
(inner_html =~ /\A\s*<!--(.+?)-->/m) ? sd.merge(scan_tokens(StringScanner.new($1))) : sd
|
184
184
|
end
|
185
185
|
|
186
186
|
def parse_token(prefix, token, meta = {})
|
data/lib/_path.rb
CHANGED
@@ -19,9 +19,9 @@ module Runo::Path
|
|
19
19
|
end
|
20
20
|
|
21
21
|
def base_of(path)
|
22
|
-
base = Runo::Set::Static::Folder.root.item(
|
22
|
+
base = Runo::Set::Static::Folder.root.item steps_of(path)
|
23
23
|
if base.is_a? Runo::Set::Static::Folder
|
24
|
-
base.item
|
24
|
+
base.item('main') || base.find {|item| item.is_a? Runo::Set::Dynamic } || base
|
25
25
|
else
|
26
26
|
base
|
27
27
|
end
|
data/lib/_storage/file.rb
CHANGED
@@ -11,7 +11,7 @@ require 'fileutils'
|
|
11
11
|
class Runo::Storage::File < Runo::Storage
|
12
12
|
|
13
13
|
def self.traverse(dir = '/', root = Runo['storage']['File']['data_dir'], &block)
|
14
|
-
::Dir.glob(::File.join
|
14
|
+
::Dir.glob(::File.join(root, dir, '*')).sort.collect {|file|
|
15
15
|
ftype = ::File.ftype file
|
16
16
|
base_name = ::File.basename file
|
17
17
|
id, ext = base_name.split('.', 2)
|
data/lib/_storage/sequel.rb
CHANGED
@@ -76,7 +76,7 @@ class Runo::Storage::Sequel < Runo::Storage
|
|
76
76
|
end
|
77
77
|
|
78
78
|
def delete(id)
|
79
|
-
@dataset.filter(_conds
|
79
|
+
@dataset.filter(_conds(id)).delete &&
|
80
80
|
@dataset.grep(:full_name, _full_name("#{id}-%")).and(~:ext => 'yaml').delete &&
|
81
81
|
id
|
82
82
|
end
|
@@ -88,7 +88,7 @@ class Runo::Storage::Sequel < Runo::Storage
|
|
88
88
|
private
|
89
89
|
|
90
90
|
def _select_by_id(conds)
|
91
|
-
@dataset.filter(_conds
|
91
|
+
@dataset.filter(_conds(conds[:id])).collect {|v| _id v[:full_name] }
|
92
92
|
end
|
93
93
|
|
94
94
|
def _select_by_d(conds)
|
data/lib/_widget/submit.rb
CHANGED
@@ -36,7 +36,7 @@ _html
|
|
36
36
|
|
37
37
|
def _g_submit_preview_delete(arg)
|
38
38
|
if (
|
39
|
-
permit_get?(arg.merge
|
39
|
+
permit_get?(arg.merge(:action => :delete)) &&
|
40
40
|
collect_item(arg[:conds]).find {|item| item[:id] !~ Runo::REX::ID_NEW } &&
|
41
41
|
arg[:orig_action] != :preview
|
42
42
|
)
|
data/lib/meta/id.rb
CHANGED
@@ -16,7 +16,7 @@ class Runo::Meta::Id < Runo::Field
|
|
16
16
|
if (my[:max].to_i > 0) && (val.size > my[:max])
|
17
17
|
[_('too long: %{max} characters maximum') % {:max => my[:max]}]
|
18
18
|
elsif (my[:min].to_i == 1) && val.empty?
|
19
|
-
[_
|
19
|
+
[_('mandatory')]
|
20
20
|
elsif (my[:min].to_i > 0) && (val.size < my[:min])
|
21
21
|
[_('too short: %{min} characters minimum') % {:min => my[:min]}]
|
22
22
|
elsif val !~ /\A#{Runo::REX::ID_SHORT}\z/
|
data/lib/meta/timestamp.rb
CHANGED
data/lib/runo.rb
CHANGED
@@ -110,7 +110,7 @@ class Runo
|
|
110
110
|
Runo.current[:session] = env['rack.session']
|
111
111
|
|
112
112
|
if Runo.transaction[tid].is_a? Runo::Field
|
113
|
-
base = Runo.transaction[tid].item
|
113
|
+
base = Runo.transaction[tid].item Runo::Path.steps_of(path.sub(/\A.*#{Runo::REX::TID}/, ''))
|
114
114
|
else
|
115
115
|
base = Runo::Path.base_of path
|
116
116
|
end
|
@@ -271,10 +271,10 @@ class Runo
|
|
271
271
|
:action => Runo::Path.action_of(req.path_info),
|
272
272
|
:sub_action => Runo::Path.sub_action_of(req.path_info),
|
273
273
|
}
|
274
|
-
params.merge!(
|
274
|
+
params.merge! rebuild_params(req.params)
|
275
275
|
|
276
276
|
params[:conds] ||= {}
|
277
|
-
params[:conds].merge!
|
277
|
+
params[:conds].merge! Runo::Path.conds_of(req.path_info)
|
278
278
|
|
279
279
|
params
|
280
280
|
end
|
data/lib/scalar/checkbox.rb
CHANGED
@@ -19,9 +19,9 @@ class Runo::Checkbox < Runo::Field
|
|
19
19
|
|
20
20
|
def errors
|
21
21
|
if val.empty?
|
22
|
-
my[:mandatory] ? [_
|
22
|
+
my[:mandatory] ? [_('mandatory')] : []
|
23
23
|
else
|
24
|
-
(val - my[:options]).empty? ? [] : [_
|
24
|
+
(val - my[:options]).empty? ? [] : [_('no such option')]
|
25
25
|
end
|
26
26
|
end
|
27
27
|
|
data/lib/scalar/file.rb
CHANGED
@@ -54,7 +54,7 @@ class Runo::File < Runo::Field
|
|
54
54
|
elsif (my[:max].to_i > 0) && (val['size'].to_i > my[:max])
|
55
55
|
[_('too large: %{max} bytes maximum') % {:max => my[:max]}]
|
56
56
|
elsif (my[:min].to_i == 1) && val['size'].to_i < 1
|
57
|
-
[_
|
57
|
+
[_('mandatory')]
|
58
58
|
elsif (my[:min].to_i > 0) && (val['size'].to_i < my[:min])
|
59
59
|
[_('too small: %{min} bytes minimum') % {:min => my[:min]}]
|
60
60
|
else
|
data/lib/scalar/img.rb
CHANGED
data/lib/scalar/password.rb
CHANGED
@@ -16,7 +16,7 @@ class Runo::Password < Runo::Field
|
|
16
16
|
elsif (my[:max].to_i > 0) && (@size > my[:max])
|
17
17
|
[_('too long: %{max} characters maximum') % {:max => my[:max]}]
|
18
18
|
elsif (my[:min].to_i == 1) && (@size == 0)
|
19
|
-
[_
|
19
|
+
[_('mandatory')]
|
20
20
|
elsif (my[:min].to_i > 0) && (@size < my[:min])
|
21
21
|
[_('too short: %{min} characters minimum') % {:min => my[:min]}]
|
22
22
|
else
|
@@ -44,7 +44,7 @@ _html
|
|
44
44
|
@val = v
|
45
45
|
when :create, :update
|
46
46
|
if v.is_a?(::String) && !v.empty?
|
47
|
-
salt = ('a'..'z').to_a[rand
|
47
|
+
salt = ('a'..'z').to_a[rand(26)] + ('a'..'z').to_a[rand(26)]
|
48
48
|
@size = v.size
|
49
49
|
@val = v.crypt salt
|
50
50
|
elsif @val.nil?
|
data/lib/scalar/radio.rb
CHANGED
@@ -13,9 +13,9 @@ class Runo::Radio < Runo::Field
|
|
13
13
|
|
14
14
|
def errors
|
15
15
|
if val.empty?
|
16
|
-
my[:mandatory] ? [_
|
16
|
+
my[:mandatory] ? [_('mandatory')] : []
|
17
17
|
else
|
18
|
-
my[:options].include?(val) ? [] : [_
|
18
|
+
my[:options].include?(val) ? [] : [_('no such option')]
|
19
19
|
end
|
20
20
|
end
|
21
21
|
|
data/lib/scalar/select.rb
CHANGED
@@ -13,11 +13,11 @@ class Runo::Select < Runo::Field
|
|
13
13
|
|
14
14
|
def errors
|
15
15
|
if my[:mandatory] && val.empty?
|
16
|
-
[_
|
16
|
+
[_('mandatory')]
|
17
17
|
elsif my[:options].include?(val) || val.empty?
|
18
18
|
[]
|
19
19
|
else
|
20
|
-
[_
|
20
|
+
[_('no such option')]
|
21
21
|
end
|
22
22
|
end
|
23
23
|
|
data/lib/scalar/text.rb
CHANGED
@@ -14,7 +14,7 @@ class Runo::Text < Runo::Field
|
|
14
14
|
if (my[:max].to_i > 0) && (val.size > my[:max])
|
15
15
|
[_('too long: %{max} characters maximum') % {:max => my[:max]}]
|
16
16
|
elsif (my[:min].to_i == 1) && val.empty?
|
17
|
-
[_
|
17
|
+
[_('mandatory')]
|
18
18
|
elsif (my[:min].to_i > 0) && (val.size < my[:min])
|
19
19
|
[_('too short: %{min} characters minimum') % {:min => my[:min]}]
|
20
20
|
else
|
data/lib/scalar/textarea.rb
CHANGED
@@ -9,7 +9,7 @@ class Runo::Textarea < Runo::Field
|
|
9
9
|
if (my[:max].to_i > 0) && (val.size > my[:max])
|
10
10
|
[_('too long: %{max} characters maximum') % {:max => my[:max]}]
|
11
11
|
elsif (my[:min].to_i == 1) && val.empty?
|
12
|
-
[_
|
12
|
+
[_('mandatory')]
|
13
13
|
elsif (my[:min].to_i > 0) && (val.size < my[:min])
|
14
14
|
[_('too short: %{min} characters minimum') % {:min => my[:min]}]
|
15
15
|
else
|
data/lib/set/dynamic.rb
CHANGED
data/lib/set/static.rb
CHANGED
@@ -11,7 +11,7 @@ class Runo::Set::Static < Runo::Field
|
|
11
11
|
|
12
12
|
def initialize(meta = {})
|
13
13
|
@meta = meta
|
14
|
-
@meta.merge!(Runo::Parser.parse_html
|
14
|
+
@meta.merge!(Runo::Parser.parse_html(meta[:html])) if meta[:html]
|
15
15
|
@meta[:item] ||= {}
|
16
16
|
@item_object = {}
|
17
17
|
end
|
@@ -87,7 +87,7 @@ _html
|
|
87
87
|
def collect_item(conds = {}, &block)
|
88
88
|
items = my[:item].keys
|
89
89
|
items &= conds[:id].to_a if conds[:id] # select item(s) by id
|
90
|
-
items.collect {|id|
|
90
|
+
items.sort.collect {|id|
|
91
91
|
item = @item_object[id] ||= Runo::Field.instance(
|
92
92
|
my[:item][id].merge(:id => id, :parent => self)
|
93
93
|
)
|
data/lib/set/static_folder.rb
CHANGED
@@ -14,11 +14,11 @@ class Runo::Set::Static::Folder < Runo::Set::Static
|
|
14
14
|
meta[:html] = load_html(meta[:dir], meta[:parent])
|
15
15
|
super
|
16
16
|
|
17
|
-
::Dir.glob(::File.join
|
17
|
+
::Dir.glob(::File.join(Runo['skin_dir'], my[:html_dir].to_s, '*.html')).each {|f|
|
18
18
|
action = ::File.basename(f, '.*').intern
|
19
19
|
merge_tmpl(@meta, Runo::Parser.parse_html(::File.read(f), action)) if action != :index
|
20
20
|
}
|
21
|
-
::Dir.glob(::File.join
|
21
|
+
::Dir.glob(::File.join(Runo['skin_dir'], my[:html_dir].to_s, '*.xml')).each {|f|
|
22
22
|
action = ::File.basename(f, '.*').intern
|
23
23
|
merge_tmpl(@meta, Runo::Parser.parse_xml(::File.read(f), action)) if action != :index
|
24
24
|
}
|
@@ -59,7 +59,7 @@ class Runo::Set::Static::Folder < Runo::Set::Static
|
|
59
59
|
return sd.instance_eval { collect_item(conds, &block) }
|
60
60
|
elsif (
|
61
61
|
conds[:id] =~ /\A\w+\z/ &&
|
62
|
-
::File.directory?(::File.join
|
62
|
+
::File.directory?(::File.join(Runo['skin_dir'], my[:dir], conds[:id]))
|
63
63
|
)
|
64
64
|
my[:item][conds[:id]] = {:klass => 'set-static-folder'}
|
65
65
|
end
|
data/skel/skin/index.html
CHANGED
@@ -27,8 +27,6 @@
|
|
27
27
|
This is your homepage of the Runo app.<br />
|
28
28
|
You can play with <a href="./examples/">the examples</a> before making your first Runo app.
|
29
29
|
</p>
|
30
|
-
<div id="main" class="app-blog"></div>
|
31
|
-
<!-- $(main.action_create) -->
|
32
30
|
</div>
|
33
31
|
|
34
32
|
<div id="right" class="column">
|
data/t/test_runo.rb
CHANGED
@@ -350,6 +350,18 @@ class TC_Runo < Test::Unit::TestCase
|
|
350
350
|
"Runo::Path.base_of should return the item('main') if the given steps point at a folder"
|
351
351
|
)
|
352
352
|
|
353
|
+
sd = Runo::Path.base_of '/foo/qux/index.html'
|
354
|
+
assert_instance_of(
|
355
|
+
Runo::Set::Dynamic,
|
356
|
+
sd,
|
357
|
+
"Runo::Path.base_of should return an available set_dynamic if there is no 'main' in the folder"
|
358
|
+
)
|
359
|
+
assert_equal(
|
360
|
+
'-foo-qux-abc',
|
361
|
+
sd[:full_name],
|
362
|
+
"Runo::Path.base_of should return the first set_dynamic if there is no 'main' in the folder"
|
363
|
+
)
|
364
|
+
|
353
365
|
sd = Runo::Path.base_of '/foo/bar/20091120_0001/comment/index.html'
|
354
366
|
assert_instance_of(
|
355
367
|
Runo::Text,
|
@@ -376,6 +388,20 @@ class TC_Runo < Test::Unit::TestCase
|
|
376
388
|
)
|
377
389
|
end
|
378
390
|
|
391
|
+
def test_base_of_empty_folder
|
392
|
+
f = Runo::Path.base_of '/foo/qux/moo/index.html'
|
393
|
+
assert_instance_of(
|
394
|
+
Runo::Set::Static::Folder,
|
395
|
+
f,
|
396
|
+
'Runo::Path.base_of should return an folder if there is no SD in it'
|
397
|
+
)
|
398
|
+
assert_equal(
|
399
|
+
'-foo-qux-moo',
|
400
|
+
f[:full_name],
|
401
|
+
'Runo::Path.base_of should return an folder if there is no SD in it'
|
402
|
+
)
|
403
|
+
end
|
404
|
+
|
379
405
|
def test_path_of
|
380
406
|
assert_equal(
|
381
407
|
'20091224/123/',
|
data/t/test_runo_call.rb
CHANGED
@@ -1136,29 +1136,24 @@ _html
|
|
1136
1136
|
'Runo#call should return both the base path and tid at :done'
|
1137
1137
|
)
|
1138
1138
|
|
1139
|
-
|
1140
|
-
|
1139
|
+
location = res.headers['Location']
|
1140
|
+
location =~ Runo::REX::PATH_ID
|
1141
|
+
new_id = sprintf('%.8d_%.4d', $1, $2)
|
1141
1142
|
|
1142
|
-
res = Rack::MockRequest.new(@runo).get
|
1143
|
-
res.headers['Location']
|
1144
|
-
)
|
1143
|
+
res = Rack::MockRequest.new(@runo).get location
|
1145
1144
|
assert_match(
|
1146
1145
|
/created 1 entry\./,
|
1147
1146
|
res.body,
|
1148
1147
|
'Runo#call should include the current message'
|
1149
1148
|
)
|
1150
1149
|
|
1151
|
-
res = Rack::MockRequest.new(@runo).get
|
1152
|
-
"http://example.com/#{tid}/#{new_id}index.html"
|
1153
|
-
)
|
1150
|
+
res = Rack::MockRequest.new(@runo).get location
|
1154
1151
|
assert_no_match(
|
1155
1152
|
/created 1 entry\./,
|
1156
1153
|
res.body,
|
1157
1154
|
'Runo#call should not include the message twice'
|
1158
1155
|
)
|
1159
1156
|
|
1160
|
-
res.headers['Location'] =~ Runo::REX::PATH_ID
|
1161
|
-
new_id = sprintf('%.8d_%.4d', $1, $2)
|
1162
1157
|
res = Rack::MockRequest.new(@runo).post(
|
1163
1158
|
'http://example.com/t_store/main/update.html',
|
1164
1159
|
{
|
metadata
CHANGED
@@ -5,8 +5,8 @@ version: !ruby/object:Gem::Version
|
|
5
5
|
segments:
|
6
6
|
- 0
|
7
7
|
- 1
|
8
|
-
-
|
9
|
-
version: 0.1.
|
8
|
+
- 2
|
9
|
+
version: 0.1.2
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- Akira FUNAI
|
@@ -14,7 +14,7 @@ autorequire:
|
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
16
|
|
17
|
-
date: 2010-07-
|
17
|
+
date: 2010-07-10 00:00:00 +09:00
|
18
18
|
default_executable: runo
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
@@ -247,6 +247,8 @@ files:
|
|
247
247
|
- t/skin/foo/index.html
|
248
248
|
- t/skin/foo/index.yaml
|
249
249
|
- t/skin/foo/not_css/foo.css
|
250
|
+
- t/skin/foo/qux/index.html
|
251
|
+
- t/skin/foo/qux/moo/index.html
|
250
252
|
- t/skin/foo/sub-20100306_0001.yaml
|
251
253
|
- t/skin/index.yaml
|
252
254
|
- t/skin/t_attachment/index.html
|