action_tree 0.1.1 → 0.2.0
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/.yardopts +3 -5
- data/README.md +6 -77
- data/Rakefile +16 -3
- data/TODO +84 -26
- data/VERSION +1 -1
- data/lib/action_tree.rb +46 -27
- data/lib/action_tree/basic.rb +36 -0
- data/lib/action_tree/basic/helpers.rb +20 -0
- data/lib/action_tree/basic/node.rb +294 -103
- data/lib/action_tree/basic/query.rb +211 -0
- data/lib/action_tree/basic/shared.rb +25 -0
- data/lib/action_tree/capture_hash.rb +28 -3
- data/lib/action_tree/components/rack.rb +52 -0
- data/lib/action_tree/components/rack/request.rb +59 -0
- data/lib/action_tree/components/rack/response.rb +10 -0
- data/lib/action_tree/components/tilt.rb +65 -0
- data/lib/action_tree/errors.rb +12 -0
- data/lib/action_tree/eval_scope.rb +18 -16
- data/spec/00_foundations/capture_hash_spec.rb +47 -0
- data/spec/00_foundations/eval_scope_spec.rb +80 -0
- data/spec/{02_node_spec.rb → 01_node/02_node_spec.rb} +8 -13
- data/spec/{03_match_spec.rb → 02_query/query_spec.rb} +5 -4
- data/spec/{04_integration_spec.rb → 03_action_tree_basic/04_integration_spec.rb} +10 -8
- data/spec/{p01_tilt_spec.rb → 04_components/template_spec.rb} +5 -9
- metadata +66 -20
- data/MANUAL.md +0 -277
- data/lib/action_tree/basic/match.rb +0 -132
- data/lib/action_tree/dialect_helper.rb +0 -12
- data/lib/action_tree/plugins/tilt.rb +0 -65
- data/spec/01_support_lib_spec.rb +0 -41
@@ -1,22 +1,24 @@
|
|
1
1
|
|
2
|
-
# The scope
|
2
|
+
# The execution scope for running matches. Built dynamically for each match by mixing in modules and setting variables.
|
3
|
+
# @api private
|
3
4
|
|
4
5
|
class ActionTree::EvalScope
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
6
|
+
|
7
|
+
# Build a new EvalScope from the given sources. The
|
8
|
+
# sources can be:
|
9
|
+
#
|
10
|
+
# * Hash: instance variable names and values (:name becomes @name)
|
11
|
+
# * Module: will be extended
|
12
|
+
# * Array: flattened and used just the same
|
13
|
+
#
|
14
|
+
def initialize(*sources)
|
15
|
+
Array(sources).flatten.each do |s|
|
16
|
+
case s
|
17
|
+
when Hash
|
18
|
+
s.each {|k,v| instance_variable_set(:"@#{k}", v) }
|
19
|
+
when Module then extend s
|
20
|
+
else
|
21
|
+
raise 'invalid scope source ' + s.inspect
|
20
22
|
end
|
21
23
|
end
|
22
24
|
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
|
2
|
+
require 'action_tree'
|
3
|
+
|
4
|
+
|
5
|
+
EXTRA_FAMILY_INFO = {
|
6
|
+
:brother => 'Smerdyakov',
|
7
|
+
:father => 'Fyodor'
|
8
|
+
}
|
9
|
+
|
10
|
+
describe ActionTree::CaptureHash do
|
11
|
+
|
12
|
+
describe '#add' do
|
13
|
+
it 'once adds item as itself' do
|
14
|
+
subject.add :canoe_color, 'green'
|
15
|
+
subject[:canoe_color].should == 'green'
|
16
|
+
end
|
17
|
+
|
18
|
+
it 'more than once becomes an Array' do
|
19
|
+
subject.add :sister, 'Arleta'
|
20
|
+
subject.add :sister, 'Maud'
|
21
|
+
subject[:sister].should == ['Arleta', 'Maud']
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
describe '#merge' do
|
26
|
+
|
27
|
+
before do
|
28
|
+
subject.add :brother, 'Dmitry'
|
29
|
+
subject.add :brother, 'Ivan'
|
30
|
+
subject.add :brother, 'Alexey'
|
31
|
+
end
|
32
|
+
|
33
|
+
it 'merges with array, accumulating on equal keys' do
|
34
|
+
family = subject.merge(EXTRA_FAMILY_INFO)
|
35
|
+
family[:brother].should ==
|
36
|
+
%w{Dmitry Ivan Alexey Smerdyakov}
|
37
|
+
family[:father].should == 'Fyodor'
|
38
|
+
end
|
39
|
+
|
40
|
+
it 'is non-destructive' do
|
41
|
+
family = subject.dup
|
42
|
+
family.merge(EXTRA_FAMILY_INFO)
|
43
|
+
family.should == subject
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
@@ -0,0 +1,80 @@
|
|
1
|
+
|
2
|
+
require 'action_tree'
|
3
|
+
|
4
|
+
module Hooga
|
5
|
+
def peace
|
6
|
+
'is valuable'
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
module Booga
|
11
|
+
def get_name
|
12
|
+
'Melchior'
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
module Shooga
|
17
|
+
def get_name
|
18
|
+
'Baltazar'
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
LIFE_MEMO = {
|
23
|
+
:love => :free,
|
24
|
+
:world => :good
|
25
|
+
}
|
26
|
+
|
27
|
+
DEATH_MEMO = {
|
28
|
+
:world => :over,
|
29
|
+
:worries => :none
|
30
|
+
}
|
31
|
+
|
32
|
+
describe ActionTree::EvalScope do
|
33
|
+
|
34
|
+
describe 'when created' do
|
35
|
+
|
36
|
+
subject do
|
37
|
+
ActionTree::EvalScope.new(
|
38
|
+
Hooga, Booga, LIFE_MEMO
|
39
|
+
)
|
40
|
+
end
|
41
|
+
|
42
|
+
it 'sets instance variables given a hash' do
|
43
|
+
LIFE_MEMO.each do |k,v|
|
44
|
+
subject.instance_eval("@#{k.to_s}").should == v
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
it 'given a module, extends it' do
|
49
|
+
subject.get_name.should == 'Melchior'
|
50
|
+
subject.peace.should == 'is valuable'
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
54
|
+
|
55
|
+
describe 'prioritizes' do
|
56
|
+
|
57
|
+
subject do
|
58
|
+
ActionTree::EvalScope.new(
|
59
|
+
[[Hooga], Booga, Shooga],
|
60
|
+
[LIFE_MEMO, DEATH_MEMO]
|
61
|
+
)
|
62
|
+
end
|
63
|
+
|
64
|
+
it 'and recursively reads arrays' do
|
65
|
+
subject.peace.should == 'is valuable'
|
66
|
+
end
|
67
|
+
|
68
|
+
it 'latest variables over first' do
|
69
|
+
LIFE_MEMO.merge(DEATH_MEMO).each do |k,v|
|
70
|
+
subject.instance_eval("@#{k.to_s}").should == v
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
it 'latest extensions over first' do
|
75
|
+
subject.get_name.should == 'Baltazar'
|
76
|
+
end
|
77
|
+
|
78
|
+
end
|
79
|
+
|
80
|
+
end
|
@@ -3,45 +3,40 @@ require 'action_tree'
|
|
3
3
|
|
4
4
|
describe ActionTree::Basic::Node do
|
5
5
|
|
6
|
-
|
7
6
|
# PATH PARSING AND DESCENDING
|
8
7
|
|
9
|
-
it 'can be inspected' do
|
10
|
-
subject.inspect
|
11
|
-
end
|
12
|
-
|
13
8
|
describe 'descend' do
|
14
9
|
it 'returns self when descending to nil, "", "/" or []' do
|
15
10
|
[nil, '', '/', []].each do |location|
|
16
|
-
subject.
|
11
|
+
subject.locate(location).should == subject
|
17
12
|
end
|
18
13
|
end
|
19
14
|
|
20
15
|
it 'returns a new node when descending one level' do
|
21
|
-
n = subject.
|
16
|
+
n = subject.locate('/the')
|
22
17
|
n.should be_a(ActionTree::Basic::Node)
|
23
18
|
n.should_not == subject
|
24
19
|
end
|
25
20
|
|
26
21
|
it 'returns a new node when descending two levels' do
|
27
|
-
n = subject.
|
22
|
+
n = subject.locate('/the/world')
|
28
23
|
n.should be_a(ActionTree::Basic::Node)
|
29
24
|
n.should_not == subject
|
30
|
-
n.should_not == subject.
|
25
|
+
n.should_not == subject.locate('/the')
|
31
26
|
end
|
32
27
|
|
33
28
|
it 'gives same node when descending two times, one level' do
|
34
|
-
subject.
|
29
|
+
subject.locate('/the').should == subject.locate('/the')
|
35
30
|
end
|
36
31
|
|
37
32
|
it 'gives same node when descending two times, three levels' do
|
38
|
-
subject.
|
33
|
+
subject.locate('/the/world/is').should == subject.locate('/the/world/is')
|
39
34
|
end
|
40
35
|
|
41
36
|
it 'gives birth recursively and selectively when descending' do
|
42
|
-
n = subject.
|
37
|
+
n = subject.locate('/the/world/is/good')
|
43
38
|
n.token.should == 'good'
|
44
|
-
n.should == subject.
|
39
|
+
n.should == subject.locate('the').locate('world/is').locate('good')
|
45
40
|
end
|
46
41
|
end
|
47
42
|
|
@@ -5,7 +5,7 @@ require 'action_tree'
|
|
5
5
|
|
6
6
|
|
7
7
|
|
8
|
-
describe ActionTree::Basic::
|
8
|
+
describe ActionTree::Basic::Query do
|
9
9
|
|
10
10
|
it 'can be inspected' do
|
11
11
|
ActionTree.new.match.inspect
|
@@ -25,8 +25,9 @@ describe ActionTree::Basic::Match do
|
|
25
25
|
end
|
26
26
|
end
|
27
27
|
|
28
|
-
it '
|
29
|
-
subject.match('/one/two/three/bobsleigh').run.
|
28
|
+
it 'raises NotFound when no match' do
|
29
|
+
expect { subject.match('/one/two/three/bobsleigh').run }.
|
30
|
+
to raise_error(ActionTree::NotFound)
|
30
31
|
end
|
31
32
|
|
32
33
|
it 'one value' do
|
@@ -54,7 +55,7 @@ describe ActionTree::Basic::Match do
|
|
54
55
|
after { @boring = false }
|
55
56
|
action { "no sound at #{@altitude} altitudes" }
|
56
57
|
helpers { def infinite?; true; end }
|
57
|
-
|
58
|
+
handle(NotFound) { 'nix nada zip' }
|
58
59
|
route :world do
|
59
60
|
before { @status = :threatened }
|
60
61
|
helpers { def infinite?; false; end }
|
@@ -25,7 +25,9 @@ describe ActionTree do
|
|
25
25
|
before('/a/b') { @v4 = @v3 + '5' }
|
26
26
|
before('/a/b') { @v5 = @v4 }
|
27
27
|
a('/a/b') { @v5 }
|
28
|
-
|
28
|
+
route('a/b') do
|
29
|
+
handle(NotFound) { 'not_found' }
|
30
|
+
end
|
29
31
|
end
|
30
32
|
end
|
31
33
|
|
@@ -39,7 +41,7 @@ describe ActionTree do
|
|
39
41
|
|
40
42
|
it 'works with not_found' do
|
41
43
|
subject.match('a/b/y').run.should ==
|
42
|
-
'
|
44
|
+
'not_found'
|
43
45
|
end
|
44
46
|
end
|
45
47
|
|
@@ -88,19 +90,19 @@ describe ActionTree do
|
|
88
90
|
end
|
89
91
|
|
90
92
|
it 'matches a first level request' do
|
91
|
-
subject.match('/houses').node.should == subject.
|
93
|
+
subject.match('/houses').node.should == subject.locate('houses')
|
92
94
|
end
|
93
95
|
|
94
96
|
it 'matches a second level request' do
|
95
|
-
subject.match('/houses/create').node.should == subject.
|
97
|
+
subject.match('/houses/create').node.should == subject.locate('houses/create')
|
96
98
|
end
|
97
99
|
|
98
100
|
it 'matches a second level capture' do
|
99
|
-
subject.match('/houses/4').node.should == subject.
|
101
|
+
subject.match('/houses/4').node.should == subject.locate('houses/:id')
|
100
102
|
end
|
101
103
|
|
102
104
|
it 'matches beneath second level capture' do
|
103
|
-
subject.match('/houses/4/edit').node.should == subject.
|
105
|
+
subject.match('/houses/4/edit').node.should == subject.locate('houses/:id/edit')
|
104
106
|
end
|
105
107
|
|
106
108
|
it 'returns nil for nonexistant node beneath capture' do
|
@@ -121,7 +123,7 @@ describe ActionTree do
|
|
121
123
|
end
|
122
124
|
|
123
125
|
it 'matches regexp in root scope' do
|
124
|
-
subject.match('/346').node.should == subject.
|
126
|
+
subject.match('/346').node.should == subject.locate([/[0-9]+/])
|
125
127
|
end
|
126
128
|
|
127
129
|
it 'fills in path for regexp in root scope' do
|
@@ -129,7 +131,7 @@ describe ActionTree do
|
|
129
131
|
end
|
130
132
|
|
131
133
|
it 'matches regexp in capture scope' do
|
132
|
-
subject.match('/houses/5/4').node.should == subject.
|
134
|
+
subject.match('/houses/5/4').node.should == subject.locate(['houses', :id, /[0-9]+/])
|
133
135
|
end
|
134
136
|
|
135
137
|
it 'fills in path for regexp in capture scope' do
|
@@ -3,13 +3,14 @@ require 'action_tree'
|
|
3
3
|
require 'haml'
|
4
4
|
|
5
5
|
module Templated
|
6
|
-
extend ActionTree::
|
6
|
+
extend ActionTree::Basic
|
7
7
|
class Node < ActionTree::Basic::Node; end
|
8
|
-
class
|
9
|
-
|
8
|
+
class Query < ActionTree::Basic::Query; end
|
9
|
+
#use ActionTree::Components::Templating
|
10
10
|
end
|
11
11
|
|
12
12
|
|
13
|
+
=begin
|
13
14
|
describe Templated::Node do
|
14
15
|
|
15
16
|
pending 'still passes normal specs'
|
@@ -51,10 +52,5 @@ describe Templated::Node do
|
|
51
52
|
|
52
53
|
end
|
53
54
|
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
55
|
+
=end
|
60
56
|
|
metadata
CHANGED
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
|
|
4
4
|
prerelease: false
|
5
5
|
segments:
|
6
6
|
- 0
|
7
|
-
-
|
8
|
-
-
|
9
|
-
version: 0.
|
7
|
+
- 2
|
8
|
+
- 0
|
9
|
+
version: 0.2.0
|
10
10
|
platform: ruby
|
11
11
|
authors:
|
12
12
|
- jbe
|
@@ -14,7 +14,7 @@ autorequire:
|
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
16
|
|
17
|
-
date: 2011-
|
17
|
+
date: 2011-03-28 00:00:00 +02:00
|
18
18
|
default_executable:
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
@@ -30,7 +30,46 @@ dependencies:
|
|
30
30
|
version: "0"
|
31
31
|
type: :runtime
|
32
32
|
version_requirements: *id001
|
33
|
-
|
33
|
+
- !ruby/object:Gem::Dependency
|
34
|
+
name: rspec
|
35
|
+
prerelease: false
|
36
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
37
|
+
none: false
|
38
|
+
requirements:
|
39
|
+
- - ">="
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
segments:
|
42
|
+
- 0
|
43
|
+
version: "0"
|
44
|
+
type: :development
|
45
|
+
version_requirements: *id002
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: yard
|
48
|
+
prerelease: false
|
49
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
50
|
+
none: false
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
segments:
|
55
|
+
- 0
|
56
|
+
version: "0"
|
57
|
+
type: :development
|
58
|
+
version_requirements: *id003
|
59
|
+
- !ruby/object:Gem::Dependency
|
60
|
+
name: yard-rspec
|
61
|
+
prerelease: false
|
62
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
63
|
+
none: false
|
64
|
+
requirements:
|
65
|
+
- - ">="
|
66
|
+
- !ruby/object:Gem::Version
|
67
|
+
segments:
|
68
|
+
- 0
|
69
|
+
version: "0"
|
70
|
+
type: :development
|
71
|
+
version_requirements: *id004
|
72
|
+
description: ActionTree is a DRY request router. It provides a compact DSL for defining actions and mapping requests to invoke them.
|
34
73
|
email: post@jostein.be
|
35
74
|
executables: []
|
36
75
|
|
@@ -45,26 +84,32 @@ files:
|
|
45
84
|
- .rspec
|
46
85
|
- .yardopts
|
47
86
|
- LICENSE
|
48
|
-
- MANUAL.md
|
49
87
|
- README.md
|
50
88
|
- Rakefile
|
51
89
|
- TODO
|
52
90
|
- VERSION
|
53
91
|
- lib/action_tree.rb
|
54
|
-
- lib/action_tree/basic
|
92
|
+
- lib/action_tree/basic.rb
|
93
|
+
- lib/action_tree/basic/helpers.rb
|
55
94
|
- lib/action_tree/basic/node.rb
|
95
|
+
- lib/action_tree/basic/query.rb
|
96
|
+
- lib/action_tree/basic/shared.rb
|
56
97
|
- lib/action_tree/capture_hash.rb
|
57
|
-
- lib/action_tree/
|
98
|
+
- lib/action_tree/components/rack.rb
|
99
|
+
- lib/action_tree/components/rack/request.rb
|
100
|
+
- lib/action_tree/components/rack/response.rb
|
101
|
+
- lib/action_tree/components/tilt.rb
|
102
|
+
- lib/action_tree/errors.rb
|
58
103
|
- lib/action_tree/eval_scope.rb
|
59
|
-
-
|
60
|
-
- spec/
|
61
|
-
- spec/02_node_spec.rb
|
62
|
-
- spec/
|
63
|
-
- spec/04_integration_spec.rb
|
104
|
+
- spec/00_foundations/capture_hash_spec.rb
|
105
|
+
- spec/00_foundations/eval_scope_spec.rb
|
106
|
+
- spec/01_node/02_node_spec.rb
|
107
|
+
- spec/02_query/query_spec.rb
|
108
|
+
- spec/03_action_tree_basic/04_integration_spec.rb
|
109
|
+
- spec/04_components/template_spec.rb
|
64
110
|
- spec/fixtures/test.haml
|
65
111
|
- spec/fixtures/test_layout.haml
|
66
112
|
- spec/log
|
67
|
-
- spec/p01_tilt_spec.rb
|
68
113
|
has_rdoc: true
|
69
114
|
homepage: http://github.com/jbe/action_tree
|
70
115
|
licenses: []
|
@@ -96,10 +141,11 @@ rubyforge_project:
|
|
96
141
|
rubygems_version: 1.3.7
|
97
142
|
signing_key:
|
98
143
|
specification_version: 3
|
99
|
-
summary: Versatile
|
144
|
+
summary: Versatile and DRY controllers and routing.
|
100
145
|
test_files:
|
101
|
-
- spec/
|
102
|
-
- spec/
|
103
|
-
- spec/
|
104
|
-
- spec/
|
105
|
-
- spec/
|
146
|
+
- spec/00_foundations/capture_hash_spec.rb
|
147
|
+
- spec/00_foundations/eval_scope_spec.rb
|
148
|
+
- spec/01_node/02_node_spec.rb
|
149
|
+
- spec/02_query/query_spec.rb
|
150
|
+
- spec/03_action_tree_basic/04_integration_spec.rb
|
151
|
+
- spec/04_components/template_spec.rb
|