bound 2.1.0 → 2.1.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +21 -6
- data/Gemfile +4 -0
- data/README.md +27 -1
- data/Rakefile +1 -0
- data/benchmark.rb +15 -34
- data/bound.gemspec +2 -2
- data/lib/bound.rb +40 -56
- data/lib/bound/version.rb +1 -1
- data/spec/bound_spec.rb +60 -60
- data/spec/hash_object_spec.rb +8 -8
- data/spec/spec_helper.rb +1 -1
- metadata +6 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 54b4ed32ea856da58caa09c3199b803daadea9a0
|
4
|
+
data.tar.gz: bf05f45b4fe4dd8f0ff975d9230e10edb32db1fd
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: aa99229e9f674deada3272536d2229a49f8fdfb0bddb939191fe58c34845c350265accd612bee7035d39952a7bd1b81b8f7597c182b79b6320e6503361c5ebec
|
7
|
+
data.tar.gz: edbd4118c85dd704f1a279bec883b911ff982872b5bab20ac7f031a263514d9bc4410a6cebb1ecfe9cc5f23f6446e27b3fc6719d4b9d97aa3f6bb72e8902af6b
|
data/.travis.yml
CHANGED
@@ -1,8 +1,23 @@
|
|
1
1
|
language: ruby
|
2
|
+
sudo: false
|
3
|
+
cache: bundler
|
4
|
+
script:
|
5
|
+
- bundle exec rake
|
6
|
+
after_success:
|
7
|
+
- '[ -d coverage ] && bundle exec codeclimate-test-reporter'
|
2
8
|
rvm:
|
3
|
-
-
|
4
|
-
-
|
5
|
-
-
|
6
|
-
-
|
7
|
-
-
|
8
|
-
- jruby
|
9
|
+
- ruby-head
|
10
|
+
- 2.3.0
|
11
|
+
- 2.2
|
12
|
+
- 2.1
|
13
|
+
- 2.0
|
14
|
+
- jruby
|
15
|
+
- jruby-9.1.5.0
|
16
|
+
env:
|
17
|
+
global:
|
18
|
+
- JRUBY_OPTS='--dev -J-Xmx1024M'
|
19
|
+
matrix:
|
20
|
+
fast_finish: true
|
21
|
+
allow_failures:
|
22
|
+
- rvm: ruby-head
|
23
|
+
- rvm: jruby-head
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -1,6 +1,26 @@
|
|
1
|
+
[github]: https://github.com/neopoly/bound
|
2
|
+
[doc]: http://rubydoc.info/github/neopoly/bound/master/file/README.md
|
3
|
+
[gem]: https://rubygems.org/gems/bound
|
4
|
+
[gem-badge]: https://img.shields.io/gem/v/bound.svg
|
5
|
+
[travis]: https://travis-ci.org/neopoly/bound
|
6
|
+
[travis-badge]: https://img.shields.io/travis/neopoly/bound.svg?branch=master
|
7
|
+
[codeclimate]: https://codeclimate.com/github/neopoly/bound
|
8
|
+
[codeclimate-climate-badge]: https://img.shields.io/codeclimate/github/neopoly/bound.svg
|
9
|
+
[codeclimate-coverage-badge]: https://codeclimate.com/github/neopoly/bound/badges/coverage.svg
|
10
|
+
[inchpages]: https://inch-ci.org/github/neopoly/bound
|
11
|
+
[inchpages-badge]: https://inch-ci.org/github/neopoly/bound.svg?branch=master&style=flat
|
12
|
+
|
1
13
|
# Bound
|
2
14
|
|
3
|
-
[![
|
15
|
+
[![Travis][travis-badge]][travis]
|
16
|
+
[![Gem Version][gem-badge]][gem]
|
17
|
+
[![Code Climate][codeclimate-climate-badge]][codeclimate]
|
18
|
+
[![Test Coverage][codeclimate-coverage-badge]][codeclimate]
|
19
|
+
[![Inline docs][inchpages-badge]][inchpages]
|
20
|
+
|
21
|
+
[Gem][gem] |
|
22
|
+
[Source][github] |
|
23
|
+
[Documentation][doc]
|
4
24
|
|
5
25
|
**In short:** The mission: Bring the notion of interfaces to ruby.
|
6
26
|
|
@@ -117,6 +137,12 @@ become more rigid and solid. The mocking part on the consumer-side would only
|
|
117
137
|
occur for the actual `register_account` call, which is fairly trivial now from
|
118
138
|
the perspective of boundaries (known object in, known object out).
|
119
139
|
|
140
|
+
## Older versions
|
141
|
+
|
142
|
+
Because of legacy software we also support some older versions:
|
143
|
+
|
144
|
+
* [stable-1.1](https://github.com/neopoly/bound/tree/stable-1.1) with latest version 1.1.1
|
145
|
+
|
120
146
|
## Contributing
|
121
147
|
|
122
148
|
1. Fork it
|
data/Rakefile
CHANGED
data/benchmark.rb
CHANGED
@@ -2,27 +2,6 @@ $: << 'lib'
|
|
2
2
|
require 'bound'
|
3
3
|
require 'benchmark'
|
4
4
|
|
5
|
-
if ENV['PROFILE']
|
6
|
-
require 'perftools'
|
7
|
-
def start_perf(name)
|
8
|
-
@_perf_name_ = 'prof__' + name
|
9
|
-
PerfTools::CpuProfiler.start @_perf_name_
|
10
|
-
end
|
11
|
-
|
12
|
-
def finish_perf
|
13
|
-
PerfTools::CpuProfiler.stop
|
14
|
-
system "pprof.rb --pdf #@_perf_name_ > #{@_perf_name_}.pdf"
|
15
|
-
system "rm -f ./#{@_perf_name_} ./#{@_perf_name_}.symbols"
|
16
|
-
ensure
|
17
|
-
@_perf_name_ = nil
|
18
|
-
end
|
19
|
-
else
|
20
|
-
def start_perf(*);end
|
21
|
-
def finish_perf(*);end
|
22
|
-
end
|
23
|
-
|
24
|
-
|
25
|
-
|
26
5
|
TestBoundary = Bound.required(
|
27
6
|
:foo,
|
28
7
|
:bar => [Bound.required(:abc)],
|
@@ -101,12 +80,23 @@ def assert_correctness(bound)
|
|
101
80
|
end
|
102
81
|
|
103
82
|
def bench(key, &block)
|
104
|
-
|
83
|
+
profiled do
|
84
|
+
result = nil
|
85
|
+
|
86
|
+
time = Benchmark.realtime { result = block.call }
|
87
|
+
puts "Benchmarking '#{key}' --> #{time}ms"
|
105
88
|
|
106
|
-
|
107
|
-
|
89
|
+
result
|
90
|
+
end
|
91
|
+
end
|
108
92
|
|
109
|
-
|
93
|
+
def profiled
|
94
|
+
if ENV['PROFILE']
|
95
|
+
require 'hotch'
|
96
|
+
Hotch { yield }
|
97
|
+
else
|
98
|
+
yield
|
99
|
+
end
|
110
100
|
end
|
111
101
|
|
112
102
|
Provider = Class.new do
|
@@ -145,44 +135,35 @@ end
|
|
145
135
|
|
146
136
|
overwrite = {:foo => 'NOPE'}
|
147
137
|
|
148
|
-
|
149
|
-
start_perf 'bound.objt'
|
150
138
|
bench ' bound w/ objt' do
|
151
139
|
provider_objects.each do |provider|
|
152
140
|
result = TestBoundary.new(provider, overwrite)
|
153
141
|
assert_correctness result
|
154
142
|
end
|
155
143
|
end
|
156
|
-
finish_perf
|
157
144
|
|
158
|
-
start_perf 'bound.hash'
|
159
145
|
bench ' bound w/ hash' do
|
160
146
|
provider_hashes.each do |provider|
|
161
147
|
result = TestBoundary.new(provider, overwrite)
|
162
148
|
assert_correctness result
|
163
149
|
end
|
164
150
|
end
|
165
|
-
finish_perf
|
166
151
|
|
167
152
|
Bound.disable_validation
|
168
153
|
|
169
|
-
start_perf 'bound.noval.objt'
|
170
154
|
bench 'bound noval w/ objt' do
|
171
155
|
provider_objects.each do |provider|
|
172
156
|
result = TestBoundary.new(provider, overwrite)
|
173
157
|
assert_correctness result
|
174
158
|
end
|
175
159
|
end
|
176
|
-
finish_perf
|
177
160
|
|
178
|
-
start_perf 'bound.noval.hash'
|
179
161
|
bench 'bound noval w/ hash' do
|
180
162
|
provider_hashes.each do |provider|
|
181
163
|
result = TestBoundary.new(provider, overwrite)
|
182
164
|
assert_correctness result
|
183
165
|
end
|
184
166
|
end
|
185
|
-
finish_perf
|
186
167
|
|
187
168
|
bench 'staticbound w/ objt' do
|
188
169
|
provider_objects.each do |provider|
|
data/bound.gemspec
CHANGED
@@ -9,7 +9,7 @@ Gem::Specification.new do |spec|
|
|
9
9
|
spec.authors = ["Jakob Holderbaum", "Jan Owiesniak"]
|
10
10
|
spec.email = ["jh@neopoly.de", "jo@neopoly.de"]
|
11
11
|
spec.summary = %q{Implements a nice helper for fast boundary definitions}
|
12
|
-
spec.homepage = ""
|
12
|
+
spec.homepage = "https://github.com/neopoly/bound"
|
13
13
|
spec.license = "MIT"
|
14
14
|
|
15
15
|
spec.files = `git ls-files`.split($/)
|
@@ -19,7 +19,7 @@ Gem::Specification.new do |spec|
|
|
19
19
|
|
20
20
|
spec.add_development_dependency "bundler", "~> 1.3"
|
21
21
|
spec.add_development_dependency "rake"
|
22
|
-
spec.add_development_dependency "minitest", "~> 5.
|
22
|
+
spec.add_development_dependency "minitest", "~> 5.8"
|
23
23
|
|
24
24
|
spec.add_development_dependency "simplecov"
|
25
25
|
end
|
data/lib/bound.rb
CHANGED
@@ -35,8 +35,8 @@ class Bound
|
|
35
35
|
|
36
36
|
def initialize(bound, target, overwrite)
|
37
37
|
@bound = bound
|
38
|
-
@target = target
|
39
|
-
@overwrite = overwrite
|
38
|
+
@target = target || {}
|
39
|
+
@overwrite = overwrite || {}
|
40
40
|
end
|
41
41
|
|
42
42
|
def validate!
|
@@ -53,10 +53,11 @@ class Bound
|
|
53
53
|
private
|
54
54
|
|
55
55
|
def ensure_all_given_attributes_are_known!
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
56
|
+
a = overwritten_attrs + target_attrs
|
57
|
+
b = attributes + optional_attributes
|
58
|
+
a.each do |attr|
|
59
|
+
unless b.include? attr
|
60
|
+
message = "Unknown attribute: #{attr.inspect} in #{b}"
|
60
61
|
raise ArgumentError, message
|
61
62
|
end
|
62
63
|
end
|
@@ -92,17 +93,12 @@ class Bound
|
|
92
93
|
end
|
93
94
|
end
|
94
95
|
|
95
|
-
|
96
96
|
def overwritten_attrs
|
97
|
-
|
98
|
-
@overwrite.keys
|
99
|
-
else
|
100
|
-
[]
|
101
|
-
end
|
97
|
+
@overwrite.keys
|
102
98
|
end
|
103
99
|
|
104
100
|
def target_attrs
|
105
|
-
if @target
|
101
|
+
if @target.kind_of?(Hash)
|
106
102
|
@target.keys
|
107
103
|
else
|
108
104
|
[]
|
@@ -110,21 +106,19 @@ class Bound
|
|
110
106
|
end
|
111
107
|
|
112
108
|
def overwritten?(attr)
|
113
|
-
@overwrite
|
109
|
+
@overwrite.key?(attr)
|
114
110
|
end
|
115
111
|
|
116
112
|
def overwritten(attr)
|
117
|
-
@overwrite
|
113
|
+
@overwrite[attr]
|
118
114
|
end
|
119
115
|
|
120
116
|
def target_has?(attr)
|
121
|
-
@target
|
122
|
-
@target.kind_of?(Hash)?@target.key?(attr):@target.respond_to?(attr)
|
117
|
+
@target.kind_of?(Hash) ? @target.key?(attr) : @target.respond_to?(attr)
|
123
118
|
end
|
124
119
|
|
125
120
|
def target(attr)
|
126
|
-
@target
|
127
|
-
@target.kind_of?(Hash)?@target[attr]:@target.send(attr)
|
121
|
+
@target.kind_of?(Hash) ? @target[attr] : @target.send(attr)
|
128
122
|
end
|
129
123
|
|
130
124
|
def set?(attr)
|
@@ -152,13 +146,8 @@ class Bound
|
|
152
146
|
%s
|
153
147
|
end
|
154
148
|
EOR
|
155
|
-
if after_init
|
156
|
-
code = code % " #{after_init}"
|
157
|
-
else
|
158
|
-
code = code % ''
|
159
|
-
end
|
160
149
|
|
161
|
-
class_eval code
|
150
|
+
class_eval code % after_init
|
162
151
|
end
|
163
152
|
|
164
153
|
def self.define_attributes(*attributes)
|
@@ -190,15 +179,12 @@ class Bound
|
|
190
179
|
end
|
191
180
|
|
192
181
|
def self.define_validator
|
193
|
-
attributes = (@attributes
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
nested_array_attributes = (@nested_array_attributes || []).map do |attr|
|
200
|
-
":#{attr.to_s}"
|
201
|
-
end.join(',')
|
182
|
+
attributes = symbolize_attributes(@attributes ||= [])
|
183
|
+
optional_attributes = symbolize_attributes(@optional_attributes ||= [])
|
184
|
+
nested_array_attributes = symbolize_attributes(@nested_array_attributes ||= [])
|
185
|
+
|
186
|
+
undef_method :validate!
|
187
|
+
|
202
188
|
code = <<-EOR
|
203
189
|
def validate!
|
204
190
|
v = Bound::BoundValidator.new(self, @t, @o)
|
@@ -212,31 +198,36 @@ class Bound
|
|
212
198
|
class_eval code
|
213
199
|
end
|
214
200
|
|
201
|
+
def self.symbolize_attributes(attributes)
|
202
|
+
attributes.map { |attr| ":#{attr}" }.join(", ")
|
203
|
+
end
|
204
|
+
|
215
205
|
def self.set_required_attributes(attributes, nested_array_attributes)
|
216
206
|
@attributes ||= []
|
217
|
-
@attributes
|
218
|
-
@attributes
|
207
|
+
@attributes.concat attributes
|
208
|
+
@attributes.concat nested_array_attributes
|
219
209
|
@nested_array_attributes ||= []
|
220
|
-
@nested_array_attributes
|
210
|
+
@nested_array_attributes.concat nested_array_attributes
|
221
211
|
define_validator
|
222
212
|
end
|
223
213
|
|
224
214
|
def self.set_optional_attributes(attributes, nested_array_attributes)
|
225
215
|
@optional_attributes ||= []
|
226
|
-
@optional_attributes
|
227
|
-
@optional_attributes
|
216
|
+
@optional_attributes.concat attributes
|
217
|
+
@optional_attributes.concat nested_array_attributes
|
228
218
|
@nested_array_attributes ||= []
|
229
|
-
@nested_array_attributes
|
219
|
+
@nested_array_attributes.concat nested_array_attributes
|
230
220
|
define_validator
|
231
221
|
end
|
232
222
|
|
233
223
|
def self.define_equality(attr)
|
234
224
|
@equality ||= []
|
235
225
|
@equality << attr
|
226
|
+
undef_method :==
|
236
227
|
code = <<-EOR
|
237
|
-
def==(other)
|
228
|
+
def ==(other)
|
238
229
|
return false unless other
|
239
|
-
|
230
|
+
#{@equality.inspect}.all? do |attr|
|
240
231
|
other.respond_to?(attr) &&
|
241
232
|
other.send(attr) == send(attr)
|
242
233
|
end
|
@@ -249,7 +240,7 @@ class Bound
|
|
249
240
|
code = <<-EOR
|
250
241
|
def #{prefix}#{attr}
|
251
242
|
return @o[:#{attr}] if @o && @o.key?(:#{attr})
|
252
|
-
return @t.kind_of?(Hash)? @t[:#{attr}] : @t.#{attr} if @t
|
243
|
+
return @t.kind_of?(Hash) ? @t[:#{attr}] : @t.#{attr} if @t
|
253
244
|
nil
|
254
245
|
end
|
255
246
|
EOR
|
@@ -295,21 +286,14 @@ class Bound
|
|
295
286
|
end
|
296
287
|
|
297
288
|
def self.required(*attributes)
|
298
|
-
|
299
|
-
|
300
|
-
array_attributes = []
|
301
|
-
if attributes.last.kind_of? Hash
|
302
|
-
attributes.pop.each do |attr, nested_class|
|
303
|
-
array_attributes << attr if nested_class.kind_of? Array
|
304
|
-
attributes << attr
|
305
|
-
end
|
306
|
-
end
|
307
|
-
|
308
|
-
self.set_required_attributes(attributes, array_attributes)
|
309
|
-
self
|
289
|
+
set_attributes(:set_required_attributes, attributes)
|
310
290
|
end
|
311
291
|
|
312
292
|
def self.optional(*attributes)
|
293
|
+
set_attributes(:set_optional_attributes, attributes)
|
294
|
+
end
|
295
|
+
|
296
|
+
def self.set_attributes(type, attributes)
|
313
297
|
self.define_attributes(*attributes)
|
314
298
|
|
315
299
|
array_attributes = []
|
@@ -320,7 +304,7 @@ class Bound
|
|
320
304
|
end
|
321
305
|
end
|
322
306
|
|
323
|
-
self.
|
307
|
+
self.send(type, attributes, array_attributes)
|
324
308
|
self
|
325
309
|
end
|
326
310
|
|
data/lib/bound/version.rb
CHANGED
data/spec/bound_spec.rb
CHANGED
@@ -3,21 +3,21 @@ require 'spec_helper'
|
|
3
3
|
describe Bound do
|
4
4
|
User = Bound.required(:name, :age)
|
5
5
|
|
6
|
-
let(:object) { HashObject.new(
|
7
|
-
let(:
|
6
|
+
let(:object) { HashObject.new(the_hash) }
|
7
|
+
let(:the_hash) { {:name => 'foo', :age => 23} }
|
8
8
|
|
9
9
|
it 'sets all attributes' do
|
10
|
-
[
|
10
|
+
[the_hash, object].each do |subject|
|
11
11
|
user = User.new(subject)
|
12
12
|
|
13
|
-
assert_equal
|
14
|
-
assert_equal
|
13
|
+
assert_equal the_hash[:name], user.name
|
14
|
+
assert_equal the_hash[:age], user.age
|
15
15
|
end
|
16
16
|
end
|
17
17
|
|
18
18
|
it 'does not cache the set attributes' do
|
19
|
-
user = User.new(
|
20
|
-
|
19
|
+
user = User.new(the_hash)
|
20
|
+
the_hash[:name] = 'AAA'
|
21
21
|
assert_equal 'AAA', user.name
|
22
22
|
|
23
23
|
user = User.new(object)
|
@@ -26,9 +26,9 @@ describe Bound do
|
|
26
26
|
end
|
27
27
|
|
28
28
|
it 'fails if attribute is missing' do
|
29
|
-
|
29
|
+
the_hash.delete :age
|
30
30
|
|
31
|
-
[
|
31
|
+
[the_hash, object].each do |subject|
|
32
32
|
exception = assert_raises ArgumentError, subject.inspect do
|
33
33
|
User.new(subject)
|
34
34
|
end
|
@@ -38,16 +38,16 @@ describe Bound do
|
|
38
38
|
end
|
39
39
|
|
40
40
|
it 'works if attribute is nil' do
|
41
|
-
|
41
|
+
the_hash[:age] = nil
|
42
42
|
|
43
|
-
[
|
43
|
+
[the_hash, object].each do |subject|
|
44
44
|
User.new(subject)
|
45
45
|
end
|
46
46
|
end
|
47
47
|
|
48
48
|
it 'fails if attribute is unknown' do
|
49
|
-
|
50
|
-
subject =
|
49
|
+
the_hash[:gender] = "M"
|
50
|
+
subject = the_hash
|
51
51
|
|
52
52
|
exception = assert_raises ArgumentError, subject.inspect do
|
53
53
|
User.new(subject)
|
@@ -57,16 +57,16 @@ describe Bound do
|
|
57
57
|
end
|
58
58
|
|
59
59
|
describe 'equality' do
|
60
|
-
let(:user) { User.new(
|
60
|
+
let(:user) { User.new(the_hash) }
|
61
61
|
|
62
62
|
it 'is given if all the attributes are same' do
|
63
|
-
reference_user = User.new(
|
63
|
+
reference_user = User.new(the_hash)
|
64
64
|
|
65
65
|
assert_equal user, reference_user
|
66
66
|
end
|
67
67
|
|
68
68
|
it 'is not given if attributes differ' do
|
69
|
-
reference_user = User.new(
|
69
|
+
reference_user = User.new(the_hash.merge(:name => 'DIFF'))
|
70
70
|
|
71
71
|
refute_equal user, reference_user
|
72
72
|
end
|
@@ -98,7 +98,7 @@ describe Bound do
|
|
98
98
|
|
99
99
|
describe 'inspect' do
|
100
100
|
let(:inspection) { user.inspect }
|
101
|
-
let(:user) { User.new(
|
101
|
+
let(:user) { User.new(the_hash) }
|
102
102
|
|
103
103
|
it 'lists all attributes' do
|
104
104
|
assert_match(/name=>"foo"/, inspection)
|
@@ -116,25 +116,25 @@ describe Bound do
|
|
116
116
|
UserWithoutAge = Bound.required(:name).optional(:age)
|
117
117
|
|
118
118
|
it 'sets optional attributes' do
|
119
|
-
[
|
119
|
+
[the_hash, object].each do |subject|
|
120
120
|
user = UserWithoutAge.new(subject)
|
121
121
|
|
122
|
-
assert_equal
|
122
|
+
assert_equal the_hash[:age], user.age
|
123
123
|
end
|
124
124
|
end
|
125
125
|
|
126
126
|
it 'works if optional attribute is missing' do
|
127
|
-
|
127
|
+
the_hash.delete :age
|
128
128
|
|
129
|
-
[
|
129
|
+
[the_hash, object].each do |subject|
|
130
130
|
UserWithoutAge.new(subject)
|
131
131
|
end
|
132
132
|
end
|
133
133
|
|
134
134
|
it 'works if attribute is nil' do
|
135
|
-
|
135
|
+
the_hash[:age] = nil
|
136
136
|
|
137
|
-
[
|
137
|
+
[the_hash, object].each do |subject|
|
138
138
|
UserWithoutAge.new(subject)
|
139
139
|
end
|
140
140
|
end
|
@@ -144,7 +144,7 @@ describe Bound do
|
|
144
144
|
UserWithProfile = Bound.required(:id).optional(
|
145
145
|
:profile => Bound.required(:age)
|
146
146
|
)
|
147
|
-
let(:
|
147
|
+
let(:the_hash) do
|
148
148
|
{
|
149
149
|
:id => 12,
|
150
150
|
:profile => {
|
@@ -154,24 +154,24 @@ describe Bound do
|
|
154
154
|
end
|
155
155
|
|
156
156
|
it 'sets optional attributes' do
|
157
|
-
[
|
157
|
+
[the_hash, object].each do |subject|
|
158
158
|
user = UserWithProfile.new(subject)
|
159
159
|
|
160
|
-
assert_equal
|
160
|
+
assert_equal the_hash[:profile][:age], user.profile.age
|
161
161
|
end
|
162
162
|
end
|
163
163
|
|
164
164
|
it 'works if optional attribute is missing' do
|
165
|
-
|
165
|
+
the_hash.delete :profile
|
166
166
|
|
167
|
-
[
|
167
|
+
[the_hash, object].each do |subject|
|
168
168
|
UserWithProfile.new(subject)
|
169
169
|
end
|
170
170
|
end
|
171
171
|
|
172
172
|
it 'fails if argument of optional nested bound is missing' do
|
173
|
-
|
174
|
-
[
|
173
|
+
the_hash[:profile].delete(:age)
|
174
|
+
[the_hash, object].each do |subject|
|
175
175
|
error = assert_raises ArgumentError do
|
176
176
|
UserWithProfile.new(subject)
|
177
177
|
end
|
@@ -182,10 +182,10 @@ describe Bound do
|
|
182
182
|
|
183
183
|
describe 'no attributes' do
|
184
184
|
UserWithoutAttributes = Bound.new
|
185
|
-
let(:
|
185
|
+
let(:the_hash) { Hash.new }
|
186
186
|
|
187
187
|
it 'works without attributes' do
|
188
|
-
[
|
188
|
+
[the_hash, object, nil].each do |subject|
|
189
189
|
UserWithoutAttributes.new(subject)
|
190
190
|
end
|
191
191
|
end
|
@@ -198,31 +198,31 @@ describe Bound do
|
|
198
198
|
describe 'nested attribute' do
|
199
199
|
Company = Bound.required(:name, :address => Bound.required(:street))
|
200
200
|
EmployedUser = Bound.required(:uid, :company => Company)
|
201
|
-
let(:
|
201
|
+
let(:the_hash) { {:uid => '1', :company => {:name => 'featurepoly', :address => {:street => 'Germany'}}} }
|
202
202
|
|
203
203
|
it 'works with nested attributes' do
|
204
|
-
[
|
204
|
+
[the_hash, object].each do |subject|
|
205
205
|
user = EmployedUser.new(subject)
|
206
206
|
|
207
|
-
assert_equal
|
208
|
-
assert_equal
|
209
|
-
assert_equal
|
207
|
+
assert_equal the_hash[:uid], user.uid
|
208
|
+
assert_equal the_hash[:company][:name], user.company.name
|
209
|
+
assert_equal the_hash[:company][:address][:street], user.company.address.street
|
210
210
|
end
|
211
211
|
end
|
212
212
|
|
213
213
|
it 'fails if nested attributes are missing' do
|
214
|
-
|
215
|
-
[
|
214
|
+
the_hash[:company].delete(:name)
|
215
|
+
[the_hash, object].each do |subject|
|
216
216
|
error = assert_raises ArgumentError do
|
217
|
-
|
217
|
+
EmployedUser.new(subject)
|
218
218
|
end
|
219
219
|
assert_match(/missing/i, error.message)
|
220
220
|
end
|
221
221
|
end
|
222
222
|
|
223
223
|
it 'does not cache values in the nested bound' do
|
224
|
-
user = EmployedUser.new(
|
225
|
-
|
224
|
+
user = EmployedUser.new(the_hash)
|
225
|
+
the_hash[:company][:name] = 'AAA'
|
226
226
|
assert_equal 'AAA', user.company.name
|
227
227
|
|
228
228
|
user = EmployedUser.new(object)
|
@@ -234,7 +234,7 @@ describe Bound do
|
|
234
234
|
describe 'array of nested attribute' do
|
235
235
|
Post = Bound.required(:title)
|
236
236
|
BloggingUser = Bound.required(:name, :posts => [Post])
|
237
|
-
let(:
|
237
|
+
let(:the_hash) do
|
238
238
|
{
|
239
239
|
:name => 'Steve',
|
240
240
|
:posts => [
|
@@ -245,18 +245,18 @@ describe Bound do
|
|
245
245
|
end
|
246
246
|
|
247
247
|
it 'works with array of nested attributes' do
|
248
|
-
[
|
248
|
+
[the_hash, object].each do |subject|
|
249
249
|
user = BloggingUser.new(subject)
|
250
250
|
|
251
|
-
assert_equal
|
252
|
-
assert_equal
|
253
|
-
assert_equal
|
251
|
+
assert_equal the_hash[:name], user.name
|
252
|
+
assert_equal the_hash[:posts][0][:title], user.posts[0].title
|
253
|
+
assert_equal the_hash[:posts][1][:title], user.posts[1].title
|
254
254
|
end
|
255
255
|
end
|
256
256
|
|
257
257
|
it 'fails if nested bound is missing an attribute' do
|
258
|
-
|
259
|
-
[
|
258
|
+
the_hash[:posts][1].delete(:title)
|
259
|
+
[the_hash, object].each do |subject|
|
260
260
|
error = assert_raises ArgumentError do
|
261
261
|
BloggingUser.new(subject)
|
262
262
|
end
|
@@ -265,8 +265,8 @@ describe Bound do
|
|
265
265
|
end
|
266
266
|
|
267
267
|
it 'does not cache values in the array' do
|
268
|
-
user = BloggingUser.new(
|
269
|
-
|
268
|
+
user = BloggingUser.new(the_hash)
|
269
|
+
the_hash[:posts][0][:title] = 'AAA'
|
270
270
|
assert_equal 'AAA', user.posts[0].title
|
271
271
|
|
272
272
|
user = BloggingUser.new(object)
|
@@ -275,13 +275,13 @@ describe Bound do
|
|
275
275
|
end
|
276
276
|
|
277
277
|
describe 'equality' do
|
278
|
-
let(:user) { BloggingUser.new(
|
278
|
+
let(:user) { BloggingUser.new(the_hash) }
|
279
279
|
it 'is given if the nested attributes are equal' do
|
280
|
-
assert_equal BloggingUser.new(
|
280
|
+
assert_equal BloggingUser.new(the_hash), user
|
281
281
|
end
|
282
282
|
|
283
283
|
it 'is not given if nested attributes differ' do
|
284
|
-
second_hash = Marshal.load(Marshal.dump
|
284
|
+
second_hash = Marshal.load(Marshal.dump the_hash)
|
285
285
|
second_hash[:posts][0][:title] = 'DIFFERENT'
|
286
286
|
|
287
287
|
refute_equal BloggingUser.new(second_hash), user
|
@@ -289,9 +289,9 @@ describe Bound do
|
|
289
289
|
end
|
290
290
|
|
291
291
|
it 'fails if posts is no array' do
|
292
|
-
|
292
|
+
the_hash[:posts] = {:title => 'broken'}
|
293
293
|
|
294
|
-
[
|
294
|
+
[the_hash, object].each do |subject|
|
295
295
|
exception = assert_raises ArgumentError do
|
296
296
|
BloggingUser.new(subject)
|
297
297
|
end
|
@@ -323,10 +323,10 @@ describe Bound do
|
|
323
323
|
describe 'questionmark suffix' do
|
324
324
|
WonderingUser = Bound.required(:asked?)
|
325
325
|
|
326
|
-
let(:
|
326
|
+
let(:the_hash) { {:asked? => "YES"} }
|
327
327
|
|
328
328
|
it 'is assign- and readable' do
|
329
|
-
[
|
329
|
+
[the_hash, object].each do |subject|
|
330
330
|
user = WonderingUser.new(subject)
|
331
331
|
assert_equal "YES", user.asked?
|
332
332
|
end
|
@@ -352,12 +352,12 @@ describe Bound do
|
|
352
352
|
describe 'seeding with multiple seeds' do
|
353
353
|
FunnyUser = Bound.required(:joke, :nose_color)
|
354
354
|
|
355
|
-
let(:
|
355
|
+
let(:the_hash) { {:joke => 'Text', :nose_color => 'blue'} }
|
356
356
|
|
357
357
|
it 'overwrites attributes from first to last' do
|
358
358
|
overwriting_hash = {:nose_color => 'RED'}
|
359
359
|
|
360
|
-
[
|
360
|
+
[the_hash, object].each do |subject|
|
361
361
|
user = FunnyUser.new(subject, overwriting_hash)
|
362
362
|
|
363
363
|
assertion_description = [subject, overwriting_hash].inspect
|
data/spec/hash_object_spec.rb
CHANGED
@@ -3,8 +3,8 @@ require 'spec_helper'
|
|
3
3
|
# Test support object
|
4
4
|
describe HashObject do
|
5
5
|
|
6
|
-
subject { HashObject.new(
|
7
|
-
let(:
|
6
|
+
subject { HashObject.new(the_hash) }
|
7
|
+
let(:the_hash) do
|
8
8
|
{
|
9
9
|
:name => 'Steve',
|
10
10
|
:address => {:street => 'Mainstreet'},
|
@@ -17,11 +17,11 @@ describe HashObject do
|
|
17
17
|
end
|
18
18
|
|
19
19
|
it 'maps an intergalactic hash' do
|
20
|
-
assert_equal
|
21
|
-
assert_equal
|
22
|
-
assert_equal
|
23
|
-
assert_equal
|
24
|
-
assert_equal
|
25
|
-
assert_equal
|
20
|
+
assert_equal the_hash[:name], subject.name
|
21
|
+
assert_equal the_hash[:address][:street], subject.address.street
|
22
|
+
assert_equal the_hash[:posts].size, subject.posts.size
|
23
|
+
assert_equal the_hash[:posts][0][:title], subject.posts[0].title
|
24
|
+
assert_equal the_hash[:posts][1][:title], subject.posts[1].title
|
25
|
+
assert_equal the_hash[:living?], subject.living?
|
26
26
|
end
|
27
27
|
end
|
data/spec/spec_helper.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: bound
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.1.
|
4
|
+
version: 2.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jakob Holderbaum
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2016-12-16 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: bundler
|
@@ -45,14 +45,14 @@ dependencies:
|
|
45
45
|
requirements:
|
46
46
|
- - "~>"
|
47
47
|
- !ruby/object:Gem::Version
|
48
|
-
version: 5.
|
48
|
+
version: '5.8'
|
49
49
|
type: :development
|
50
50
|
prerelease: false
|
51
51
|
version_requirements: !ruby/object:Gem::Requirement
|
52
52
|
requirements:
|
53
53
|
- - "~>"
|
54
54
|
- !ruby/object:Gem::Version
|
55
|
-
version: 5.
|
55
|
+
version: '5.8'
|
56
56
|
- !ruby/object:Gem::Dependency
|
57
57
|
name: simplecov
|
58
58
|
requirement: !ruby/object:Gem::Requirement
|
@@ -91,7 +91,7 @@ files:
|
|
91
91
|
- spec/hash_object_spec.rb
|
92
92
|
- spec/spec_helper.rb
|
93
93
|
- spec/support/hash_object.rb
|
94
|
-
homepage:
|
94
|
+
homepage: https://github.com/neopoly/bound
|
95
95
|
licenses:
|
96
96
|
- MIT
|
97
97
|
metadata: {}
|
@@ -111,7 +111,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
111
111
|
version: '0'
|
112
112
|
requirements: []
|
113
113
|
rubyforge_project:
|
114
|
-
rubygems_version: 2.
|
114
|
+
rubygems_version: 2.5.2
|
115
115
|
signing_key:
|
116
116
|
specification_version: 4
|
117
117
|
summary: Implements a nice helper for fast boundary definitions
|