crudtree 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,44 @@
1
+ class Model0
2
+ def id
3
+ 0
4
+ end
5
+ end
6
+ class Model1
7
+ end
8
+ class Model2
9
+ def id
10
+ 2
11
+ end
12
+ def model0
13
+ Model0.new
14
+ end
15
+ end
16
+ class Klass0
17
+ end
18
+ class Klass1
19
+ end
20
+ class Klass2
21
+ end
22
+
23
+ class Mod0
24
+ def id
25
+ 0
26
+ end
27
+ end
28
+ class Mod1
29
+ def id
30
+ 1
31
+ end
32
+ def mod0
33
+ Mod0.new
34
+ end
35
+ end
36
+ class Mod2
37
+ def id
38
+ 2
39
+ end
40
+ def initialize(parent = Mod0)
41
+ instance_variable_set("@#{parent.to_s.downcase}", parent.new)
42
+ end
43
+ attr_accessor :mod0, :mod1, :mod2
44
+ end
@@ -0,0 +1,9 @@
1
+ module Usher
2
+ module Interface
3
+ def self.class_for(interface)
4
+ Rack
5
+ end
6
+ class Rack
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,36 @@
1
+ def results_in(path, klass, call, params)
2
+ klass.expects(:dispatcher).with(call).returns(:yeah!)
3
+ to_mock = mock('to')
4
+ to_mock.expects(:to).with(:yeah!).returns(true)
5
+ Usher::Interface.class_for(:rack).any_instance.expects(:path).with(path, params).returns(to_mock)
6
+ end
7
+
8
+ module Usher; module Interface; class Rack;
9
+ include CRUDtree::Interface::Usher::Rack
10
+ def initialize(app = nil, options = nil, &block)
11
+ instance_eval(&block) if block
12
+ end
13
+ end; end; end
14
+ class TestObj0; end
15
+ class TestObj1; end
16
+ class TestObj2; end
17
+
18
+ def default_routes(number=0)
19
+ default_route(TestObj0)
20
+ default_route(TestObj1, "/testobj0/:id") if number > 0
21
+ default_route(TestObj2, "/testobj0/:id/testobj1/:id") if number > 1
22
+ end
23
+
24
+ def default_route(klass, pre_path=nil)
25
+ results_in("#{pre_path}/#{klass.to_s.downcase}", klass, :index, :conditions => {:request_method => "GET"})
26
+ results_in("#{pre_path}/#{klass.to_s.downcase}/:id", klass, :show, :conditions => {:request_method => "GET"})
27
+ end
28
+ module Usher
29
+ module Interface
30
+ def self.class_for(interface)
31
+ Rack
32
+ end
33
+ class Rack
34
+ end
35
+ end
36
+ end
data/test/setup.rb ADDED
@@ -0,0 +1,6 @@
1
+ $LOAD_PATH.unshift(File.expand_path("#{__FILE__}/../../lib")) # Add PROJECT/lib to $LOAD_PATH
2
+ require 'crudtree'
3
+ require 'baretest/mocha'
4
+ include CRUDtree
5
+ include Mocha::API
6
+ require 'ruby-debug'
@@ -0,0 +1,244 @@
1
+ require 'ostruct'
2
+ BareTest.suite do
3
+
4
+ suite "CRUDtree" do
5
+
6
+ suite "Generator" do
7
+
8
+ suite "#generate_url_from_node" do
9
+
10
+ setup :node, "a simple node" do
11
+ @node = Node.new(nil, :paths => ["foo"], klass: Object, model: Object ){:foo}
12
+ @path = "/foo/23"
13
+ @identifiers = [23]
14
+ end
15
+
16
+ setup :node, "a node with multiple parents" do
17
+ master = Master.new
18
+ master.node(klass: Object, model: Object, paths: ["foo"]) do
19
+ node(klass: Object, model: Object, paths: ["bar"]) do
20
+ node(klass: Object, model: Object, paths: ["baz"]) {:foo}
21
+ end
22
+ end
23
+ @node = master.nodes.first.nodes.first.nodes.first
24
+ @path = "/foo/1/bar/2/baz/3"
25
+ @identifiers = [1,2,3]
26
+ end
27
+
28
+ assert ":node goes to the right path" do
29
+ equal(@path, CRUDtree::Generator.allocate.send(:generate_url_from_node, @node, @identifiers))
30
+ end
31
+
32
+ end
33
+
34
+ suite "#model_to_node" do
35
+
36
+ setup do
37
+ class TestObj0; end
38
+ class TestObj1; end
39
+ end
40
+
41
+ setup :master, "a simple master" do
42
+ master = CRUDtree::Master.new
43
+ master.node(klass: Object, model: ::TestObj0) {:foo}
44
+ @generator = CRUDtree::Generator.new(master)
45
+ @node = master.nodes.first
46
+ @model = ::TestObj0
47
+ end
48
+
49
+ setup :master, "a complex master" do
50
+ master = CRUDtree::Master.new
51
+ master.node(klass: Object, model: ::TestObj1){
52
+ node(klass: Object, model: ::TestObj0){:foo}
53
+ }
54
+ @generator = CRUDtree::Generator.new(master)
55
+ @node = master.nodes.first.nodes.first
56
+ @model = ::TestObj0
57
+ end
58
+
59
+ setup :master, "a master with duplicate models" do
60
+ master = CRUDtree::Master.new
61
+ master.node(klass: Object, model: TestObj1){
62
+ node(klass: Object, model: ::TestObj0){:foo}
63
+ node(klass: Object, model: ::TestObj0){:foo}
64
+ }
65
+ @generator = CRUDtree::Generator.new(master)
66
+ @node = master.nodes.first.nodes
67
+ @model = ::TestObj0
68
+ end
69
+
70
+ assert "The right model is found on :master." do
71
+ equal(@node, @generator.instance_variable_get(:@model_to_node)[@model])
72
+ end
73
+
74
+ end
75
+
76
+ suite "node finding" do
77
+
78
+ suite "without duplicates" do
79
+
80
+ setup do
81
+ @master = CRUDtree::Master.new
82
+ end
83
+
84
+ setup :master, "a simple master" do
85
+ @node = @master.node(klass: Klass0, model: Model0){:foo}
86
+ @resource = Model0.new
87
+ @valid = [[Model0.new, @node, ["0"]]]
88
+ @invalid = [[Model2.new, @node], [Model1.new, @node]]
89
+ end
90
+
91
+ setup :master, "a complex master" do
92
+ @master.node(klass: Klass0, model: Model0) do
93
+ node(klass: Klass1, model: Model1){:foo}
94
+ node(klass: Klass2, model: Model2){:foo}
95
+ end
96
+ @node = @master.nodes.first.nodes.last
97
+ @resource = Model2.new
98
+ @valid = [[Model2.new, @node, ["0","2"]], [Model0.new, @master.nodes.first, ["0"]]]
99
+ @invalid = [[Model0.new, @node], [Model1.new, @node]]
100
+ end
101
+
102
+ assert "#identifiers_returns the corret identifiers with :master" do
103
+ generator = CRUDtree::Generator.new(@master)
104
+ @valid.all?{|model, node, ary| generator.send(:identifiers_to_node, model, node) == ary}
105
+ end
106
+
107
+ assert "#identifiers returns false invalid with :master" do
108
+ generator = CRUDtree::Generator.new(@master)
109
+ @invalid.all?{|model, node| ! generator.send(:identifiers_to_node, model, node)}
110
+ end
111
+
112
+ assert "#find_node gets the correct node from :master" do
113
+ same(@node, CRUDtree::Generator.new(@master).send(:find_node, @resource).first)
114
+ end
115
+
116
+ end
117
+
118
+ suite "with duplicates" do
119
+
120
+ setup do
121
+ @master = Master.new
122
+ @master.node(klass: Klass0, model: Mod0) do
123
+ node(klass: Klass1, model: Mod1){:foo}
124
+ node(klass: Klass2, model: Mod2) do
125
+ node(klass: Klass2, model: Mod2){:foo}
126
+ end
127
+ end
128
+ @generator = CRUDtree::Generator.new(@master)
129
+ end
130
+
131
+ setup :node, "nested node" do
132
+ @node = @master.nodes.first.nodes.last.nodes.first
133
+ @resource = Mod2.new(Mod2)
134
+ @identifier = %w(0 2 2)
135
+ end
136
+
137
+ setup :node, "first node" do
138
+ @node = @master.nodes.first.nodes.last
139
+ @resource = Mod2.new(Mod0)
140
+ @identifier = %w(0 2)
141
+ end
142
+
143
+ assert "#identifiers_to_node returns an Array of identifiers for the :node" do
144
+ equal(@identifier, @generator.send(:identifiers_to_node, @resource, @node))
145
+ end
146
+
147
+ assert "#find_node gets :node based on the model" do
148
+ same(@node, @generator.send(:find_node, @resource).first)
149
+ end
150
+
151
+ end
152
+
153
+ end
154
+
155
+ suite "#generate_from_sub" do
156
+
157
+ setup do
158
+ @foo = OpenStruct.new(:name => :foo, :path => "foo")
159
+ @bar = OpenStruct.new(:name => :bar, :path => "bar")
160
+ end
161
+
162
+ setup :names, "one name" do
163
+ @node = OpenStruct.new(:subs => [@foo, @bar])
164
+ @names = [:foo]
165
+ @path = "/foo"
166
+ end
167
+
168
+ setup :names, "stacked names" do
169
+ @node = OpenStruct.new(:subs => [OpenStruct.new(:subs => [@foo, @bar], :name => :foo, :path => "foo"), @bar])
170
+ @names = [:foo, :bar]
171
+ @path = "/foo/bar"
172
+ end
173
+
174
+ assert "generates the correct url from :names" do
175
+ url = ""
176
+ Generator.allocate.send(:generate_from_sub, @node, @names, url)
177
+ equal(@path, url)
178
+ end
179
+
180
+ end
181
+
182
+ suite "blackbox" do
183
+
184
+ setup do
185
+ @master = Master.new
186
+ @master.node(klass: Klass0, model: Mod0) do
187
+ collection(call: :new)
188
+ member(call: :delete)
189
+ node(klass: Klass1, model: Mod1){:foo}
190
+ node(klass: Klass2, model: Mod2) do
191
+ member(call: :edit)
192
+ collection(call: :post)
193
+ node(klass: Klass2, model: Mod2){:foo}
194
+ end
195
+ end
196
+ @generator = CRUDtree::Generator.new(@master)
197
+ end
198
+
199
+ setup :model, "model for the nested node" do
200
+ @resource = Mod2.new(Mod2)
201
+ @path = "/klass0/0/klass2/2/klass2/2"
202
+ end
203
+
204
+ setup :model, "model for the first node" do
205
+ @resource = Mod2.new(Mod0)
206
+ @path = "/klass0/0/klass2/2"
207
+ end
208
+
209
+ setup :model, "model for the simplest node" do
210
+ @resource = Mod0.new
211
+ @path = "/klass0/0"
212
+ end
213
+
214
+ setup :model, "collection on base node" do
215
+ @resource = [:klass0, :new]
216
+ @path = "/klass0/new"
217
+ end
218
+
219
+ setup :model, "member on base node" do
220
+ @resource = [:klass0, :delete]
221
+ @path = "/klass0/delete"
222
+ end
223
+
224
+ setup :model, "member on simple node" do
225
+ @resource = [Mod2.new, :edit]
226
+ @path = "/klass0/0/klass2/2/edit"
227
+ end
228
+
229
+ setup :model, "collection on simple node" do
230
+ @resource = [Mod2.new, :post]
231
+ @path = "/klass0/0/klass2/post"
232
+ end
233
+
234
+ assert "#generate with :model" do
235
+ equal(@path, @generator.generate(*@resource))
236
+ end
237
+
238
+ end
239
+
240
+ end
241
+
242
+ end
243
+
244
+ end
@@ -0,0 +1,33 @@
1
+ require 'crudtree/interface/usher/rack'
2
+ module Usher
3
+ module Interface
4
+ class Rack
5
+ def initialize(app = nil, options = nil, &blk)
6
+ end
7
+ end
8
+ end
9
+ end
10
+
11
+ BareTest.suite do
12
+
13
+ suite "CRUDtree" do
14
+
15
+ suite "integartion" do
16
+
17
+ suite "inclusion" do
18
+
19
+ setup do
20
+ CRUDtree::Interface.for(:usher_rack)
21
+ end
22
+
23
+ assert "the module gets included and the methods are avaible" do
24
+ Usher::Interface.class_for(:rack).new.respond_to? :node
25
+ end
26
+
27
+ end
28
+
29
+ end
30
+
31
+ end
32
+
33
+ end
@@ -0,0 +1,132 @@
1
+ BareTest.suite "CRUDtree" do
2
+
3
+ suite "blackbox" do
4
+
5
+ setup :tree, "a simple tree" do
6
+ @block = proc {
7
+ node(model: Object, klass: TestObj0) do
8
+ collection(call: :index, rest: :get)
9
+ end
10
+ }
11
+ results_in("/testobj0/index", TestObj0, :index, :conditions => {:request_method => "GET"})
12
+ # default routes
13
+ default_routes
14
+ end
15
+
16
+ setup :tree, "a nested tree" do
17
+ @block = proc {
18
+ node(model: Object, klass: TestObj0) do
19
+ node(model: Object, klass: TestObj1) do
20
+ member(call: :show, rest: :get)
21
+ end
22
+ end
23
+ }
24
+ results_in("/testobj0/:id/testobj1/:id/show", TestObj1, :show, :conditions => {:request_method => "GET"})
25
+ # default routes
26
+ default_routes(1)
27
+ end
28
+
29
+ setup :tree, "a twice nested tree" do
30
+ @block = proc {
31
+ node(model: Object, klass: TestObj0) do
32
+ node(model: Object, klass: TestObj1) do
33
+ node(model: Object, klass: TestObj2) do
34
+ collection(call: :create, rest: :post)
35
+ end
36
+ end
37
+ end
38
+ }
39
+ results_in("/testobj0/:id/testobj1/:id/testobj2/create", TestObj2, :create, :conditions => {:request_method => "POST"})
40
+ # default routes
41
+ default_routes(2)
42
+ end
43
+
44
+ setup :tree, "a tree with some subnodes" do
45
+ @block = proc {
46
+ node(model: Object, klass: TestObj0) do
47
+ collection(call: :index, rest: :get)
48
+ member(call: :show, rest: :get)
49
+ member(call: :update, path: "edit", rest: :put)
50
+ end
51
+ }
52
+ results_in("/testobj0/index", TestObj0, :index, :conditions => {:request_method => "GET"})
53
+ results_in("/testobj0/:id/edit", TestObj0, :update, :conditions => {:request_method => "PUT"})
54
+ results_in("/testobj0/:id/show", TestObj0, :show, :conditions => {:request_method => "GET"})
55
+ # default routes
56
+ default_routes
57
+ end
58
+
59
+ setup :tree, "a nested tree with some subnodes" do
60
+ @block = proc {
61
+ node(model: Object, klass: TestObj0) do
62
+ member(call: :show, rest: :get)
63
+ node(model: Object, klass: TestObj1) do
64
+ collection(call: :index, rest: :get)
65
+ member(call: :show, rest: :get)
66
+ member(call: :update, path: "edit", rest: :put)
67
+ end
68
+ end
69
+ }
70
+ results_in("/testobj0/:id/show", TestObj0, :show, :conditions => {:request_method => "GET"})
71
+ results_in("/testobj0/:id/testobj1/index", TestObj1, :index, :conditions => {:request_method => "GET"})
72
+ results_in("/testobj0/:id/testobj1/:id/show", TestObj1, :show, :conditions => {:request_method => "GET"})
73
+ results_in("/testobj0/:id/testobj1/:id/edit", TestObj1, :update, :conditions => {:request_method => "PUT"})
74
+ # default routes
75
+ default_routes(1)
76
+ end
77
+
78
+ setup :tree, "a tree with multiple paths" do
79
+ @block = proc {
80
+ node(model: Object, paths: ["test", "foo", "bar"], klass: TestObj0) do
81
+ collection(call: :index, rest: :get)
82
+ end
83
+ }
84
+ results_in("/test/index", TestObj0, :index, :conditions => {:request_method => "GET"})
85
+ results_in("/foo/index", TestObj0, :index, :conditions => {:request_method => "GET"})
86
+ results_in("/bar/index", TestObj0, :index, :conditions => {:request_method => "GET"})
87
+ # default routes
88
+ results_in("/test", TestObj0, :index, :conditions => {:request_method => "GET"})
89
+ results_in("/foo", TestObj0, :index, :conditions => {:request_method => "GET"})
90
+ results_in("/bar", TestObj0, :index, :conditions => {:request_method => "GET"})
91
+ results_in("/test/:id", TestObj0, :show, :conditions => {:request_method => "GET"})
92
+ results_in("/foo/:id", TestObj0, :show, :conditions => {:request_method => "GET"})
93
+ results_in("/bar/:id", TestObj0, :show, :conditions => {:request_method => "GET"})
94
+ end
95
+
96
+ setup :tree, "a nested tree with multiple paths" do
97
+ @block = proc {
98
+ node(model: Object, paths: ["foo", "bar"], klass: TestObj0) do
99
+ collection(call: :index, rest: :get)
100
+ node(model: Object, paths: ["test", "baz"], klass: TestObj1) do
101
+ member(call: :edit, rest: :get)
102
+ end
103
+ end
104
+ }
105
+ results_in("/foo/index", TestObj0, :index, :conditions => {:request_method => "GET"})
106
+ results_in("/bar/index", TestObj0, :index, :conditions => {:request_method => "GET"})
107
+ results_in("/foo/:id/test/:id/edit", TestObj1, :edit, :conditions => {:request_method => "GET"})
108
+ results_in("/bar/:id/test/:id/edit", TestObj1, :edit, :conditions => {:request_method => "GET"})
109
+ results_in("/foo/:id/baz/:id/edit", TestObj1, :edit, :conditions => {:request_method => "GET"})
110
+ results_in("/bar/:id/baz/:id/edit", TestObj1, :edit, :conditions => {:request_method => "GET"})
111
+ # default routes
112
+ results_in("/foo", TestObj0, :index, :conditions => {:request_method => "GET"})
113
+ results_in("/bar", TestObj0, :index, :conditions => {:request_method => "GET"})
114
+ results_in("/foo/:id", TestObj0, :show, :conditions => {:request_method => "GET"})
115
+ results_in("/bar/:id", TestObj0, :show, :conditions => {:request_method => "GET"})
116
+ results_in("/foo/:id/test", TestObj1, :index, :conditions => {:request_method => "GET"})
117
+ results_in("/bar/:id/test", TestObj1, :index, :conditions => {:request_method => "GET"})
118
+ results_in("/foo/:id/baz", TestObj1, :index, :conditions => {:request_method => "GET"})
119
+ results_in("/bar/:id/baz", TestObj1, :index, :conditions => {:request_method => "GET"})
120
+ results_in("/foo/:id/test/:id", TestObj1, :show, :conditions => {:request_method => "GET"})
121
+ results_in("/bar/:id/test/:id", TestObj1, :show, :conditions => {:request_method => "GET"})
122
+ results_in("/foo/:id/baz/:id", TestObj1, :show, :conditions => {:request_method => "GET"})
123
+ results_in("/bar/:id/baz/:id", TestObj1, :show, :conditions => {:request_method => "GET"})
124
+ end
125
+
126
+ assert "compilation of :tree" do
127
+ Usher::Interface.class_for(:rack).new(&@block)
128
+ end
129
+
130
+ end
131
+
132
+ end