nested 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +1 -0
- data/Gemfile +6 -0
- data/Gemfile.lock +26 -0
- data/Rakefile +13 -0
- data/lib/nested.rb +270 -0
- data/nested.gemspec +19 -0
- data/test/nested_test.rb +401 -0
- metadata +78 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: f19e9d429c1ae06debc557e262539cf5817e1cde
|
4
|
+
data.tar.gz: 400c5102ec072ff320eec74aecff61dc8379e3d1
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 645f64ca4ad1229866c346ca2db9ff018272b4bccd9fd6df1245eb36453398a45b4d3e7396370dabec2f23250415323d4750154d3ab706ea70d9124d21240823
|
7
|
+
data.tar.gz: 8f839e12ec5cd696efb49a6d5412471032f6f94adff0615eee26518885605799b0dda229bbfd015d409a056ab349bfb12d2a0a1b46fb6aacc0936476cc18206d
|
data/.gitignore
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
*.gem
|
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
GEM
|
2
|
+
remote: https://rubygems.org/
|
3
|
+
specs:
|
4
|
+
activesupport (4.0.0)
|
5
|
+
i18n (~> 0.6, >= 0.6.4)
|
6
|
+
minitest (~> 4.2)
|
7
|
+
multi_json (~> 1.3)
|
8
|
+
thread_safe (~> 0.1)
|
9
|
+
tzinfo (~> 0.3.37)
|
10
|
+
atomic (1.1.14)
|
11
|
+
i18n (0.6.5)
|
12
|
+
metaclass (0.0.1)
|
13
|
+
minitest (4.7.5)
|
14
|
+
mocha (0.14.0)
|
15
|
+
metaclass (~> 0.0.1)
|
16
|
+
multi_json (1.8.2)
|
17
|
+
thread_safe (0.1.3)
|
18
|
+
atomic
|
19
|
+
tzinfo (0.3.38)
|
20
|
+
|
21
|
+
PLATFORMS
|
22
|
+
ruby
|
23
|
+
|
24
|
+
DEPENDENCIES
|
25
|
+
activesupport
|
26
|
+
mocha
|
data/Rakefile
ADDED
data/lib/nested.rb
ADDED
@@ -0,0 +1,270 @@
|
|
1
|
+
module Nested
|
2
|
+
|
3
|
+
class OneWithNameInManyError < StandardError
|
4
|
+
end
|
5
|
+
|
6
|
+
class ManyInManyError < StandardError
|
7
|
+
end
|
8
|
+
|
9
|
+
class SingletonAndCollectionError < StandardError
|
10
|
+
end
|
11
|
+
|
12
|
+
class Resource
|
13
|
+
FETCH = ->(resource, ctrl) do
|
14
|
+
raise "implement fetch for resource #{resource.name}" unless resource.parent
|
15
|
+
raise "implement fetch for singleton #{resource.name}" if resource.singleton?
|
16
|
+
|
17
|
+
parent_resource = resource.parent
|
18
|
+
parent_obj = ctrl.instance_variable_get("@#{parent_resource.instance_variable_name}")
|
19
|
+
|
20
|
+
if resource.name
|
21
|
+
scope = parent_obj.send(resource.name.to_s.pluralize.to_sym)
|
22
|
+
resource.collection? ? scope : scope.where(id: ctrl.params["#{resource.name.to_s.singularize}_id"]).first
|
23
|
+
else
|
24
|
+
parent_obj.where(id: ctrl.params["#{parent_resource.name.to_s.singularize}_id"]).first
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
attr_reader :name, :parent, :actions, :resources
|
29
|
+
|
30
|
+
def initialize(sinatra, name, singleton, collection, parent)
|
31
|
+
raise SingletonAndCollectionError.new if singleton && collection
|
32
|
+
|
33
|
+
@sinatra = sinatra
|
34
|
+
@name = name
|
35
|
+
@singleton = singleton
|
36
|
+
@collection = collection
|
37
|
+
@parent = parent
|
38
|
+
@resources = []
|
39
|
+
@actions = []
|
40
|
+
end
|
41
|
+
|
42
|
+
def singleton?
|
43
|
+
@singleton == true
|
44
|
+
end
|
45
|
+
|
46
|
+
def member?
|
47
|
+
!singleton? && !collection?
|
48
|
+
end
|
49
|
+
|
50
|
+
def collection?
|
51
|
+
@collection == true
|
52
|
+
end
|
53
|
+
|
54
|
+
def fetch(&block)
|
55
|
+
@__fetch = block
|
56
|
+
end
|
57
|
+
|
58
|
+
def fetch_object(ctrl)
|
59
|
+
(@__fetch || FETCH).call(self, ctrl)
|
60
|
+
end
|
61
|
+
|
62
|
+
def route(args={})
|
63
|
+
"".tap do |r|
|
64
|
+
r << @parent.route(args) if @parent
|
65
|
+
|
66
|
+
if singleton?
|
67
|
+
r << "/" + @name.to_s.singularize
|
68
|
+
elsif collection?
|
69
|
+
r << "/" + @name.to_s.pluralize
|
70
|
+
else
|
71
|
+
if @name
|
72
|
+
r << "/" + @name.to_s.pluralize
|
73
|
+
end
|
74
|
+
r << "/"
|
75
|
+
key = ((@name || @parent.name).to_s.singularize + "_id").to_sym
|
76
|
+
|
77
|
+
if args.key?(key)
|
78
|
+
r << args[key].to_s
|
79
|
+
else
|
80
|
+
r << ":#{key}"
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
def get(action=nil, &block)
|
87
|
+
create_sinatra_route :get, action, &(block || get_default)
|
88
|
+
end
|
89
|
+
|
90
|
+
def get_default
|
91
|
+
->(resource) { instance_variable_get("@#{resource.instance_variable_name}") }
|
92
|
+
end
|
93
|
+
|
94
|
+
def post(action=nil, &block)
|
95
|
+
create_sinatra_route :post, action, &block
|
96
|
+
end
|
97
|
+
|
98
|
+
def put(action=nil, &block)
|
99
|
+
create_sinatra_route :put, action, &block
|
100
|
+
end
|
101
|
+
|
102
|
+
def delete(action=nil, &block)
|
103
|
+
create_sinatra_route :delete, action, &block
|
104
|
+
end
|
105
|
+
|
106
|
+
def singleton(name, &block)
|
107
|
+
child_resource(name, true, false, &block)
|
108
|
+
end
|
109
|
+
|
110
|
+
def many(name, &block)
|
111
|
+
raise ManyInManyError.new "do not nest many in many" if collection?
|
112
|
+
child_resource(name, false, true, &block)
|
113
|
+
end
|
114
|
+
|
115
|
+
def one(name=nil, &block)
|
116
|
+
raise OneWithNameInManyError.new("call one (#{name}) without name argument when nested in a many (#{@name})") if name && collection?
|
117
|
+
child_resource(name, false, false, &block)
|
118
|
+
end
|
119
|
+
|
120
|
+
def child_resource(name, singleton, collection, &block)
|
121
|
+
Resource.new(@sinatra, name, singleton, collection, self)
|
122
|
+
.tap{|r| r.instance_eval(&block)}
|
123
|
+
.tap{|r| @resources << r}
|
124
|
+
end
|
125
|
+
|
126
|
+
def instance_variable_name
|
127
|
+
@name.to_s.send(collection? ? :pluralize : :singularize).to_sym
|
128
|
+
end
|
129
|
+
|
130
|
+
def parents
|
131
|
+
(@parent ? @parent.parents + [@parent] : [])
|
132
|
+
end
|
133
|
+
|
134
|
+
def self_and_parents
|
135
|
+
(self.parents + [self]).reverse
|
136
|
+
end
|
137
|
+
|
138
|
+
def create_sinatra_route(method, action, &block)
|
139
|
+
@actions << {method: method, actions: action}
|
140
|
+
|
141
|
+
resource = self
|
142
|
+
|
143
|
+
puts "sinatra router [#{method}] #{@sinatra.prefix}#{resource.route}"
|
144
|
+
|
145
|
+
@sinatra.send(method, resource.route) do
|
146
|
+
content_type :json
|
147
|
+
|
148
|
+
resource.self_and_parents.reverse.each do |res|
|
149
|
+
resource_obj = res.fetch_object(self)
|
150
|
+
|
151
|
+
puts "set @#{res.instance_variable_name} to #{resource_obj.inspect} for #{self}"
|
152
|
+
instance_variable_set("@#{res.instance_variable_name}", resource_obj)
|
153
|
+
end
|
154
|
+
|
155
|
+
case response = instance_exec(resource, &block)
|
156
|
+
when String then response
|
157
|
+
else response.to_json
|
158
|
+
end
|
159
|
+
end
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
module Angular
|
164
|
+
def self.extended(base)
|
165
|
+
base.send(:extend, Nested::Angular::Sinatra)
|
166
|
+
end
|
167
|
+
|
168
|
+
module Sinatra
|
169
|
+
def create_resource(name, singleton, collection, &block)
|
170
|
+
angularize(super)
|
171
|
+
end
|
172
|
+
end
|
173
|
+
|
174
|
+
def angular_add_functions(js, resource)
|
175
|
+
resource.actions.each do |e|
|
176
|
+
method, action = e.values_at :method, :action
|
177
|
+
|
178
|
+
fun_name = Nested::JsUtil::generate_function_name(resource, method, action)
|
179
|
+
|
180
|
+
args = Nested::JsUtil::function_arguments(resource)
|
181
|
+
|
182
|
+
route_args = args.inject({}) do |memo, e|
|
183
|
+
idx = args.index(e)
|
184
|
+
memo[:"#{e}_id"] = "'+(typeof(values[#{idx}]) == 'number' ? values[#{idx}].toString() : values[#{idx}].id)+'"
|
185
|
+
memo
|
186
|
+
end
|
187
|
+
route = "#{self.prefix}" + resource.route(route_args)
|
188
|
+
|
189
|
+
js << " impl.#{fun_name} = function(#{args.join(',')}){"
|
190
|
+
|
191
|
+
args = args.map{|a| "$q.when(#{a})"}
|
192
|
+
|
193
|
+
js << " return $q.all([#{args.join(',')}]).then(function(values){" unless args.empty?
|
194
|
+
js << (args.length > 1 ? " " : "") + " return $http({method: '#{method}', url: '#{route}'})"
|
195
|
+
js << " });" unless args.empty?
|
196
|
+
|
197
|
+
js << " }"
|
198
|
+
end
|
199
|
+
|
200
|
+
resource.resources.each {|r| angular_add_functions(js, r) }
|
201
|
+
end
|
202
|
+
|
203
|
+
def angularize(resource)
|
204
|
+
js = []
|
205
|
+
|
206
|
+
js << "angular.module('Nested-#{resource.name.to_s.gsub(/_/, '-')}', ['ngResource'])"
|
207
|
+
js << ".factory('#{resource.name.to_s.camelcase.capitalize}Service', function($http, $q){"
|
208
|
+
|
209
|
+
js << " var impl = {}"
|
210
|
+
angular_add_functions(js, resource)
|
211
|
+
js << " return impl"
|
212
|
+
|
213
|
+
js << "})"
|
214
|
+
|
215
|
+
get "/#{resource.name}.js" do
|
216
|
+
content_type :js
|
217
|
+
js.join("\n")
|
218
|
+
end
|
219
|
+
end
|
220
|
+
end
|
221
|
+
|
222
|
+
module JsUtil
|
223
|
+
def self.generate_function_name(resource, method, action)
|
224
|
+
arr = resource.self_and_parents
|
225
|
+
|
226
|
+
fun_name_arr = arr
|
227
|
+
.reject{|r| r == arr.last }
|
228
|
+
.map{|r| r.name || :one}
|
229
|
+
.reverse
|
230
|
+
|
231
|
+
fun_name_arr << action if action
|
232
|
+
fun_name_arr << method
|
233
|
+
|
234
|
+
fun_name_arr.map(&:to_s).join("_").camelcase(:lower)
|
235
|
+
end
|
236
|
+
|
237
|
+
def self.function_arguments(resource)
|
238
|
+
|
239
|
+
resource
|
240
|
+
.self_and_parents.select{|r| r.member?}
|
241
|
+
.map{|r| r.name || r.parent.name}
|
242
|
+
.map(&:to_s)
|
243
|
+
.map(&:singularize)
|
244
|
+
.reverse
|
245
|
+
end
|
246
|
+
end
|
247
|
+
|
248
|
+
module Sinatra
|
249
|
+
def prefix(prefix=nil)
|
250
|
+
if prefix
|
251
|
+
@prefix = prefix
|
252
|
+
else
|
253
|
+
@prefix
|
254
|
+
end
|
255
|
+
end
|
256
|
+
def singleton(name, &block)
|
257
|
+
create_resource(name, true, false, &block)
|
258
|
+
end
|
259
|
+
def many(name, &block)
|
260
|
+
create_resource(name, false, true, &block)
|
261
|
+
end
|
262
|
+
def one(name, &block)
|
263
|
+
create_resource(name, false, false, &block)
|
264
|
+
end
|
265
|
+
def create_resource(name, singleton, collection, &block)
|
266
|
+
::Nested::Resource.new(self, name, singleton, collection, nil).tap{|r| r.instance_eval(&block) }
|
267
|
+
end
|
268
|
+
end
|
269
|
+
|
270
|
+
end
|
data/nested.gemspec
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
Gem::Specification.new do |s|
|
2
|
+
s.name = "nested"
|
3
|
+
s.version = "0.0.1"
|
4
|
+
|
5
|
+
s.authors = ["Jan Zimmek"]
|
6
|
+
s.email = %q{jan.zimmek@web.de}
|
7
|
+
|
8
|
+
s.summary = %q{rest dsl}
|
9
|
+
s.description = %q{rest dsl}
|
10
|
+
|
11
|
+
|
12
|
+
s.files = `git ls-files`.split("\n")
|
13
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
14
|
+
|
15
|
+
s.require_paths = ["lib"]
|
16
|
+
|
17
|
+
s.add_runtime_dependency "activesupport"
|
18
|
+
s.add_runtime_dependency "sinatra"
|
19
|
+
end
|
data/test/nested_test.rb
ADDED
@@ -0,0 +1,401 @@
|
|
1
|
+
require "test/unit"
|
2
|
+
require "mocha/setup"
|
3
|
+
require "active_support/all"
|
4
|
+
require "nested"
|
5
|
+
|
6
|
+
class NestedTest < Test::Unit::TestCase
|
7
|
+
|
8
|
+
def singleton!
|
9
|
+
@r = Nested::Resource.new(@sinatra, :project, true, false, nil)
|
10
|
+
end
|
11
|
+
|
12
|
+
def collection!
|
13
|
+
@r = Nested::Resource.new(@sinatra, :project, false, true, nil)
|
14
|
+
end
|
15
|
+
|
16
|
+
def member!
|
17
|
+
@r = Nested::Resource.new(@sinatra, :project, false, false, nil)
|
18
|
+
end
|
19
|
+
|
20
|
+
def setup
|
21
|
+
@sinatra = mock
|
22
|
+
end
|
23
|
+
|
24
|
+
def test_is_singleton
|
25
|
+
singleton!
|
26
|
+
assert_equal true, @r.singleton?
|
27
|
+
|
28
|
+
collection!
|
29
|
+
assert_equal false, @r.singleton?
|
30
|
+
end
|
31
|
+
|
32
|
+
def test_is_collection
|
33
|
+
collection!
|
34
|
+
assert_equal true, @r.collection?
|
35
|
+
|
36
|
+
singleton!
|
37
|
+
assert_equal false, @r.collection?
|
38
|
+
end
|
39
|
+
|
40
|
+
def test_is_member
|
41
|
+
member!
|
42
|
+
assert_equal true, @r.member?
|
43
|
+
|
44
|
+
singleton!
|
45
|
+
assert_equal false, @r.member?
|
46
|
+
|
47
|
+
collection!
|
48
|
+
assert_equal false, @r.member?
|
49
|
+
end
|
50
|
+
|
51
|
+
def test_fetch
|
52
|
+
singleton!
|
53
|
+
|
54
|
+
fetch = -> { }
|
55
|
+
@r.fetch &fetch
|
56
|
+
|
57
|
+
assert_equal(fetch, @r.instance_variable_get("@__fetch"))
|
58
|
+
end
|
59
|
+
|
60
|
+
def test_fetch_object
|
61
|
+
singleton!
|
62
|
+
|
63
|
+
Nested::Resource::FETCH.expects(:call).with(@r, {})
|
64
|
+
@r.fetch_object({})
|
65
|
+
|
66
|
+
fetch = -> { }
|
67
|
+
@r.fetch &fetch
|
68
|
+
|
69
|
+
fetch.expects(:call).with(@r, {})
|
70
|
+
@r.fetch_object({})
|
71
|
+
end
|
72
|
+
|
73
|
+
def test_route
|
74
|
+
# no parent
|
75
|
+
singleton!
|
76
|
+
assert_equal "/project", @r.route
|
77
|
+
|
78
|
+
collection!
|
79
|
+
assert_equal "/projects", @r.route
|
80
|
+
|
81
|
+
member!
|
82
|
+
assert_equal "/projects/:project_id", @r.route
|
83
|
+
assert_equal "/projects/1", @r.route(project_id: 1)
|
84
|
+
|
85
|
+
# --- singleton
|
86
|
+
|
87
|
+
singleton!
|
88
|
+
@r2 = @r.singleton(:statistic) { }
|
89
|
+
assert_equal "/project/statistic", @r2.route
|
90
|
+
|
91
|
+
singleton!
|
92
|
+
@r2 = @r.many(:statistics) { }
|
93
|
+
assert_equal "/project/statistics", @r2.route
|
94
|
+
|
95
|
+
singleton!
|
96
|
+
@r2 = @r.one(:statistic) { }
|
97
|
+
assert_equal "/project/statistics/:statistic_id", @r2.route
|
98
|
+
assert_equal "/project/statistics/1", @r2.route(statistic_id: 1)
|
99
|
+
|
100
|
+
# --- collection
|
101
|
+
|
102
|
+
collection!
|
103
|
+
@r2 = @r.singleton(:statistic) { }
|
104
|
+
assert_equal "/projects/statistic", @r2.route
|
105
|
+
|
106
|
+
collection!
|
107
|
+
@r2 = @r.one { }
|
108
|
+
assert_equal "/projects/:project_id", @r2.route
|
109
|
+
assert_equal "/projects/1", @r2.route(project_id: 1)
|
110
|
+
|
111
|
+
# --- member
|
112
|
+
|
113
|
+
member!
|
114
|
+
@r2 = @r.singleton(:statistic) { }
|
115
|
+
assert_equal "/projects/:project_id/statistic", @r2.route
|
116
|
+
assert_equal "/projects/1/statistic", @r2.route(project_id: 1)
|
117
|
+
|
118
|
+
member!
|
119
|
+
@r2 = @r.many(:statistic) { }
|
120
|
+
assert_equal "/projects/:project_id/statistics", @r2.route
|
121
|
+
assert_equal "/projects/1/statistics", @r2.route(project_id: 1)
|
122
|
+
|
123
|
+
member!
|
124
|
+
@r2 = @r.one(:statistic) { }
|
125
|
+
assert_equal "/projects/:project_id/statistics/:statistic_id", @r2.route
|
126
|
+
assert_equal "/projects/1/statistics/2", @r2.route(project_id: 1, statistic_id: 2)
|
127
|
+
|
128
|
+
end
|
129
|
+
|
130
|
+
|
131
|
+
def test_singleton
|
132
|
+
singleton!
|
133
|
+
@r.expects(:child_resource).with(:statistic, true, false)
|
134
|
+
@r.singleton(:statistic)
|
135
|
+
|
136
|
+
member!
|
137
|
+
@r.expects(:child_resource).with(:statistic, true, false)
|
138
|
+
@r.singleton(:statistic)
|
139
|
+
|
140
|
+
collection!
|
141
|
+
@r.expects(:child_resource).with(:statistic, true, false)
|
142
|
+
@r.singleton(:statistic)
|
143
|
+
end
|
144
|
+
|
145
|
+
def test_one
|
146
|
+
singleton!
|
147
|
+
@r.expects(:child_resource).with(:statistic, false, false)
|
148
|
+
@r.one(:statistic)
|
149
|
+
|
150
|
+
member!
|
151
|
+
@r.expects(:child_resource).with(:statistic, false, false)
|
152
|
+
@r.one(:statistic)
|
153
|
+
|
154
|
+
collection!
|
155
|
+
@r.expects(:child_resource).with(nil, false, false)
|
156
|
+
@r.one
|
157
|
+
|
158
|
+
collection!
|
159
|
+
assert_raise ::Nested::OneWithNameInManyError do
|
160
|
+
@r.one :statistic
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
164
|
+
def test_many
|
165
|
+
singleton!
|
166
|
+
@r.expects(:child_resource).with(:statistics, false, true)
|
167
|
+
@r.many(:statistics)
|
168
|
+
|
169
|
+
member!
|
170
|
+
@r.expects(:child_resource).with(:statistics, false, true)
|
171
|
+
@r.many(:statistics)
|
172
|
+
|
173
|
+
collection!
|
174
|
+
assert_raise ::Nested::ManyInManyError do
|
175
|
+
@r.many :statistic
|
176
|
+
end
|
177
|
+
end
|
178
|
+
|
179
|
+
def test_get
|
180
|
+
singleton!
|
181
|
+
|
182
|
+
@r.expects(:create_sinatra_route).with(:get, nil)
|
183
|
+
@r.get
|
184
|
+
|
185
|
+
@r.expects(:create_sinatra_route).with(:get, :action)
|
186
|
+
@r.get :action
|
187
|
+
end
|
188
|
+
|
189
|
+
def test_post
|
190
|
+
singleton!
|
191
|
+
|
192
|
+
@r.expects(:create_sinatra_route).with(:post, nil)
|
193
|
+
@r.post
|
194
|
+
|
195
|
+
@r.expects(:create_sinatra_route).with(:post, :action)
|
196
|
+
@r.post :action
|
197
|
+
end
|
198
|
+
|
199
|
+
def test_put
|
200
|
+
singleton!
|
201
|
+
|
202
|
+
@r.expects(:create_sinatra_route).with(:put, nil)
|
203
|
+
@r.put
|
204
|
+
|
205
|
+
@r.expects(:create_sinatra_route).with(:put, :action)
|
206
|
+
@r.put :action
|
207
|
+
end
|
208
|
+
|
209
|
+
def test_delete
|
210
|
+
singleton!
|
211
|
+
|
212
|
+
@r.expects(:create_sinatra_route).with(:delete, nil)
|
213
|
+
@r.delete
|
214
|
+
|
215
|
+
@r.expects(:create_sinatra_route).with(:delete, :action)
|
216
|
+
@r.delete :action
|
217
|
+
end
|
218
|
+
|
219
|
+
def test_child_resource
|
220
|
+
singleton!
|
221
|
+
r = @r.child_resource(:statistic, false, false) { }
|
222
|
+
assert_equal :statistic, r.name
|
223
|
+
assert_equal false, r.instance_variable_get("@singleton")
|
224
|
+
assert_equal false, r.instance_variable_get("@collection")
|
225
|
+
|
226
|
+
singleton!
|
227
|
+
r = @r.child_resource(:statistic, true, false) { }
|
228
|
+
assert_equal :statistic, r.name
|
229
|
+
assert_equal true, r.instance_variable_get("@singleton")
|
230
|
+
assert_equal false, r.instance_variable_get("@collection")
|
231
|
+
|
232
|
+
singleton!
|
233
|
+
r = @r.child_resource(:statistic, false, true) { }
|
234
|
+
assert_equal :statistic, r.name
|
235
|
+
assert_equal false, r.instance_variable_get("@singleton")
|
236
|
+
assert_equal true, r.instance_variable_get("@collection")
|
237
|
+
|
238
|
+
singleton!
|
239
|
+
assert_raise Nested::SingletonAndCollectionError do
|
240
|
+
@r.child_resource(:statistic, true, true) { }
|
241
|
+
end
|
242
|
+
end
|
243
|
+
|
244
|
+
def test_instance_variable_name
|
245
|
+
singleton!
|
246
|
+
assert_equal :project, @r.instance_variable_name
|
247
|
+
|
248
|
+
member!
|
249
|
+
assert_equal :project, @r.instance_variable_name
|
250
|
+
|
251
|
+
collection!
|
252
|
+
assert_equal :projects, @r.instance_variable_name
|
253
|
+
end
|
254
|
+
|
255
|
+
def test_parents
|
256
|
+
singleton!
|
257
|
+
assert_equal [], @r.parents
|
258
|
+
|
259
|
+
r2 = @r.singleton(:statistic) { }
|
260
|
+
assert_equal [@r], r2.parents
|
261
|
+
|
262
|
+
r3 = r2.singleton(:statistic) { }
|
263
|
+
assert_equal [@r, r2], r3.parents
|
264
|
+
end
|
265
|
+
|
266
|
+
def test_self_and_parents
|
267
|
+
singleton!
|
268
|
+
assert_equal [@r], @r.self_and_parents
|
269
|
+
|
270
|
+
r2 = @r.singleton(:statistic) { }
|
271
|
+
assert_equal [r2, @r], r2.self_and_parents
|
272
|
+
|
273
|
+
r3 = r2.singleton(:statistic) { }
|
274
|
+
assert_equal [r3, r2, @r], r3.self_and_parents
|
275
|
+
end
|
276
|
+
|
277
|
+
def test_create_sinatra_route
|
278
|
+
@sinatra.expects(:prefix).at_least_once.returns(nil)
|
279
|
+
|
280
|
+
singleton!
|
281
|
+
|
282
|
+
@sinatra.expects(:send).with(:get, @r.route)
|
283
|
+
@r.create_sinatra_route(:get, nil) { }
|
284
|
+
assert_equal [{method: :get, actions: nil}], @r.actions
|
285
|
+
|
286
|
+
singleton!
|
287
|
+
|
288
|
+
@sinatra.expects(:send).with(:post, @r.route)
|
289
|
+
@r.create_sinatra_route(:post, nil) { }
|
290
|
+
assert_equal [{method: :post, actions: nil}], @r.actions
|
291
|
+
|
292
|
+
singleton!
|
293
|
+
|
294
|
+
@sinatra.expects(:send).with(:post, @r.route)
|
295
|
+
@r.create_sinatra_route(:post, :action) { }
|
296
|
+
assert_equal [{method: :post, actions: :action}], @r.actions
|
297
|
+
end
|
298
|
+
|
299
|
+
# ----
|
300
|
+
|
301
|
+
|
302
|
+
|
303
|
+
|
304
|
+
def test_function_name
|
305
|
+
singleton!
|
306
|
+
assert_equal "get", Nested::JsUtil::generate_function_name(@r, :get, nil)
|
307
|
+
|
308
|
+
collection!
|
309
|
+
assert_equal "get", Nested::JsUtil::generate_function_name(@r, :get, nil)
|
310
|
+
|
311
|
+
member!
|
312
|
+
assert_equal "get", Nested::JsUtil::generate_function_name(@r, :get, nil)
|
313
|
+
|
314
|
+
singleton!
|
315
|
+
assert_equal "myActionGet", Nested::JsUtil::generate_function_name(@r, :get, :my_action)
|
316
|
+
|
317
|
+
collection!
|
318
|
+
assert_equal "myActionGet", Nested::JsUtil::generate_function_name(@r, :get, :my_action)
|
319
|
+
|
320
|
+
member!
|
321
|
+
assert_equal "myActionGet", Nested::JsUtil::generate_function_name(@r, :get, :my_action)
|
322
|
+
|
323
|
+
singleton!
|
324
|
+
|
325
|
+
@sinatra.expects(:prefix).returns(nil)
|
326
|
+
@sinatra.expects(:get)
|
327
|
+
@r2 = @r.singleton(:statistic) { get }
|
328
|
+
|
329
|
+
assert_equal "statisticGet", Nested::JsUtil::generate_function_name(@r2, :get, nil)
|
330
|
+
|
331
|
+
member!
|
332
|
+
|
333
|
+
@sinatra.expects(:prefix).returns(nil)
|
334
|
+
@sinatra.expects(:get)
|
335
|
+
@r2 = @r.singleton(:statistic) { get }
|
336
|
+
|
337
|
+
assert_equal "statisticGet", Nested::JsUtil::generate_function_name(@r2, :get, nil)
|
338
|
+
|
339
|
+
collection!
|
340
|
+
|
341
|
+
@sinatra.expects(:prefix).returns(nil)
|
342
|
+
@sinatra.expects(:get)
|
343
|
+
@r2 = @r.singleton(:statistic) { get }
|
344
|
+
|
345
|
+
assert_equal "statisticGet", Nested::JsUtil::generate_function_name(@r2, :get, nil)
|
346
|
+
end
|
347
|
+
|
348
|
+
# -----------------
|
349
|
+
|
350
|
+
def test_function_arguments
|
351
|
+
# --- singleton
|
352
|
+
singleton!
|
353
|
+
assert_equal [], Nested::JsUtil.function_arguments(@r)
|
354
|
+
|
355
|
+
singleton!
|
356
|
+
assert_equal [], Nested::JsUtil.function_arguments(@r.singleton(:statistic) {})
|
357
|
+
|
358
|
+
singleton!
|
359
|
+
assert_equal [], Nested::JsUtil.function_arguments(@r.many(:statistics) {})
|
360
|
+
|
361
|
+
singleton!
|
362
|
+
assert_equal ["statistic"], Nested::JsUtil.function_arguments(@r.one(:statistic) {})
|
363
|
+
|
364
|
+
singleton!
|
365
|
+
r2 = @r.one(:statistic) {}
|
366
|
+
r3 = r2.singleton(:test) {}
|
367
|
+
assert_equal ["statistic"], Nested::JsUtil.function_arguments(r3)
|
368
|
+
|
369
|
+
# --- member
|
370
|
+
|
371
|
+
member!
|
372
|
+
assert_equal ["project"], Nested::JsUtil.function_arguments(@r)
|
373
|
+
|
374
|
+
member!
|
375
|
+
assert_equal ["project"], Nested::JsUtil.function_arguments(@r.singleton(:statistic) {})
|
376
|
+
|
377
|
+
member!
|
378
|
+
assert_equal ["project"], Nested::JsUtil.function_arguments(@r.many(:statistics) {})
|
379
|
+
|
380
|
+
member!
|
381
|
+
assert_equal ["project", "statistic"], Nested::JsUtil.function_arguments(@r.one(:statistic) {})
|
382
|
+
|
383
|
+
# --- collection
|
384
|
+
|
385
|
+
collection!
|
386
|
+
assert_equal [], Nested::JsUtil.function_arguments(@r)
|
387
|
+
|
388
|
+
collection!
|
389
|
+
assert_equal [], Nested::JsUtil.function_arguments(@r.singleton(:statistic) {})
|
390
|
+
|
391
|
+
collection!
|
392
|
+
assert_equal ["project"], Nested::JsUtil.function_arguments(@r.one {})
|
393
|
+
|
394
|
+
collection!
|
395
|
+
r2 = @r.one {}
|
396
|
+
r3 = r2.one(:statistic) {}
|
397
|
+
|
398
|
+
assert_equal ["project", "statistic"], Nested::JsUtil.function_arguments(r3)
|
399
|
+
end
|
400
|
+
|
401
|
+
end
|
metadata
ADDED
@@ -0,0 +1,78 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: nested
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Jan Zimmek
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2013-10-20 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: activesupport
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - '>='
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - '>='
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: sinatra
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - '>='
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - '>='
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
description: rest dsl
|
42
|
+
email: jan.zimmek@web.de
|
43
|
+
executables: []
|
44
|
+
extensions: []
|
45
|
+
extra_rdoc_files: []
|
46
|
+
files:
|
47
|
+
- .gitignore
|
48
|
+
- Gemfile
|
49
|
+
- Gemfile.lock
|
50
|
+
- Rakefile
|
51
|
+
- lib/nested.rb
|
52
|
+
- nested.gemspec
|
53
|
+
- test/nested_test.rb
|
54
|
+
homepage:
|
55
|
+
licenses: []
|
56
|
+
metadata: {}
|
57
|
+
post_install_message:
|
58
|
+
rdoc_options: []
|
59
|
+
require_paths:
|
60
|
+
- lib
|
61
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
62
|
+
requirements:
|
63
|
+
- - '>='
|
64
|
+
- !ruby/object:Gem::Version
|
65
|
+
version: '0'
|
66
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
67
|
+
requirements:
|
68
|
+
- - '>='
|
69
|
+
- !ruby/object:Gem::Version
|
70
|
+
version: '0'
|
71
|
+
requirements: []
|
72
|
+
rubyforge_project:
|
73
|
+
rubygems_version: 2.0.0.rc.2
|
74
|
+
signing_key:
|
75
|
+
specification_version: 4
|
76
|
+
summary: rest dsl
|
77
|
+
test_files:
|
78
|
+
- test/nested_test.rb
|