crudtree 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.
@@ -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