gorillib-model 0.0.1
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/.gitignore +4 -0
- data/Gemfile +12 -0
- data/README.md +21 -0
- data/Rakefile +15 -0
- data/gorillib-model.gemspec +27 -0
- data/lib/gorillib/builder.rb +239 -0
- data/lib/gorillib/core_ext/datetime.rb +23 -0
- data/lib/gorillib/core_ext/exception.rb +153 -0
- data/lib/gorillib/core_ext/module.rb +10 -0
- data/lib/gorillib/core_ext/object.rb +14 -0
- data/lib/gorillib/model/base.rb +273 -0
- data/lib/gorillib/model/collection/model_collection.rb +157 -0
- data/lib/gorillib/model/collection.rb +200 -0
- data/lib/gorillib/model/defaults.rb +115 -0
- data/lib/gorillib/model/errors.rb +24 -0
- data/lib/gorillib/model/factories.rb +555 -0
- data/lib/gorillib/model/field.rb +168 -0
- data/lib/gorillib/model/lint.rb +24 -0
- data/lib/gorillib/model/named_schema.rb +53 -0
- data/lib/gorillib/model/positional_fields.rb +35 -0
- data/lib/gorillib/model/schema_magic.rb +163 -0
- data/lib/gorillib/model/serialization/csv.rb +60 -0
- data/lib/gorillib/model/serialization/json.rb +44 -0
- data/lib/gorillib/model/serialization/lines.rb +30 -0
- data/lib/gorillib/model/serialization/to_wire.rb +54 -0
- data/lib/gorillib/model/serialization/tsv.rb +53 -0
- data/lib/gorillib/model/serialization.rb +41 -0
- data/lib/gorillib/model/type/extended.rb +83 -0
- data/lib/gorillib/model/type/ip_address.rb +153 -0
- data/lib/gorillib/model/type/url.rb +11 -0
- data/lib/gorillib/model/validate.rb +22 -0
- data/lib/gorillib/model/version.rb +5 -0
- data/lib/gorillib/model.rb +34 -0
- data/spec/builder_spec.rb +193 -0
- data/spec/core_ext/datetime_spec.rb +41 -0
- data/spec/core_ext/exception.rb +98 -0
- data/spec/core_ext/object.rb +45 -0
- data/spec/model/collection_spec.rb +290 -0
- data/spec/model/defaults_spec.rb +104 -0
- data/spec/model/factories_spec.rb +323 -0
- data/spec/model/lint_spec.rb +28 -0
- data/spec/model/serialization/csv_spec.rb +30 -0
- data/spec/model/serialization/tsv_spec.rb +28 -0
- data/spec/model/serialization_spec.rb +41 -0
- data/spec/model/type/extended_spec.rb +166 -0
- data/spec/model/type/ip_address_spec.rb +141 -0
- data/spec/model_spec.rb +261 -0
- data/spec/spec_helper.rb +15 -0
- data/spec/support/capture_output.rb +28 -0
- data/spec/support/nuke_constants.rb +9 -0
- data/spec/support/shared_context_for_builders.rb +59 -0
- data/spec/support/shared_context_for_models.rb +55 -0
- data/spec/support/shared_examples_for_factories.rb +71 -0
- data/spec/support/shared_examples_for_model_fields.rb +62 -0
- data/spec/support/shared_examples_for_models.rb +87 -0
- metadata +193 -0
@@ -0,0 +1,323 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe '', :model_spec => true, :factory_spec => true do
|
4
|
+
|
5
|
+
describe Gorillib::Factory do
|
6
|
+
describe 'Factory()' do
|
7
|
+
it 'turns a proc into an ApplyProcFactory' do
|
8
|
+
ff = Gorillib::Factory( ->(obj){ "bob says #{obj}" } )
|
9
|
+
ff.receive(3).should == "bob says 3"
|
10
|
+
end
|
11
|
+
it 'returns anything that responds to #receive directly' do
|
12
|
+
ff = Object.new ; ff.define_singleton_method(:receive){}
|
13
|
+
Gorillib::Factory(ff).should equal(ff)
|
14
|
+
end
|
15
|
+
it 'returns a factory directly' do
|
16
|
+
ff = Gorillib::Factory::SymbolFactory.new
|
17
|
+
Gorillib::Factory(ff).should equal(ff)
|
18
|
+
end
|
19
|
+
it 'does not look up factory **classes**' do
|
20
|
+
->{ Gorillib::Factory(Gorillib::Factory::SymbolFactory) }.should raise_error(ArgumentError, /Don\'t know which factory makes/)
|
21
|
+
end
|
22
|
+
it 'looks up factories by typename' do
|
23
|
+
Gorillib::Factory(:symbol ).should be_a(Gorillib::Factory::SymbolFactory)
|
24
|
+
Gorillib::Factory(:identical).should == (::Whatever)
|
25
|
+
end
|
26
|
+
it 'looks up factories by class' do
|
27
|
+
Gorillib::Factory(Symbol).should be_a(Gorillib::Factory::SymbolFactory)
|
28
|
+
Gorillib::Factory(String).should be_a(Gorillib::Factory::StringFactory)
|
29
|
+
end
|
30
|
+
it 'calls Gorillib::Factory.lookup' do
|
31
|
+
x = double
|
32
|
+
Gorillib::Factory.should_receive(:find).with(x)
|
33
|
+
Gorillib::Factory(x)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
# __________________________________________________________________________
|
39
|
+
#
|
40
|
+
#
|
41
|
+
#
|
42
|
+
describe Gorillib::Factory::StringFactory do
|
43
|
+
it_behaves_like :it_considers_native, 'foo', ''
|
44
|
+
it_behaves_like :it_converts, :foo => 'foo', 3 => '3', false => "false", [] => "[]"
|
45
|
+
it_behaves_like :it_considers_blankish, nil
|
46
|
+
it_behaves_like :it_is_registered_as, :string, String
|
47
|
+
its(:typename){ should == :string }
|
48
|
+
end
|
49
|
+
|
50
|
+
describe Gorillib::Factory::SymbolFactory do
|
51
|
+
it_behaves_like :it_considers_native, :foo, :"symbol :with weird chars"
|
52
|
+
it_behaves_like :it_converts, 'foo' => :foo
|
53
|
+
it_behaves_like :it_considers_blankish, nil, ""
|
54
|
+
it_behaves_like :it_is_a_mismatch_for, 3, false, []
|
55
|
+
it_behaves_like :it_is_registered_as, :symbol, Symbol
|
56
|
+
its(:typename){ should == :symbol }
|
57
|
+
end
|
58
|
+
|
59
|
+
describe Gorillib::Factory::RegexpFactory do
|
60
|
+
it_behaves_like :it_considers_native, /foo/, //
|
61
|
+
it_behaves_like :it_converts, 'foo' => /foo/, ".*" => /.*/
|
62
|
+
it_behaves_like :it_considers_blankish, nil, ""
|
63
|
+
it_behaves_like :it_is_a_mismatch_for, :foo, 3, false, []
|
64
|
+
it_behaves_like :it_is_registered_as, :regexp, Regexp
|
65
|
+
its(:typename){ should == :regexp }
|
66
|
+
end
|
67
|
+
|
68
|
+
describe Gorillib::Factory::IntegerFactory do
|
69
|
+
it_behaves_like :it_considers_native, 1, -1, 123_456_789_123_456_789_123_456_789_123_456_789
|
70
|
+
#
|
71
|
+
it_behaves_like :it_converts, '1' => 1, '0' => 0, '1234567' => 1234567
|
72
|
+
it_behaves_like :it_converts, '123456789123456789123456789123456789' => 123_456_789_123_456_789_123_456_789_123_456_789
|
73
|
+
it_behaves_like :it_converts, '1_234_567' => 1234567
|
74
|
+
it_behaves_like :it_converts, 1.0 => 1, 1.99 => 1, -0.9 => 0
|
75
|
+
it_behaves_like :it_converts, Complex(1,0) => 1, Complex(1.0,0) => 1, Rational(5,2) => 2
|
76
|
+
#
|
77
|
+
it_behaves_like :it_considers_blankish, nil, ''
|
78
|
+
it_behaves_like :it_is_a_mismatch_for, Complex(1,0.0), Complex(0,3), :foo, false, []
|
79
|
+
it_behaves_like :it_is_a_mismatch_for, '8_', 'one', '3blindmice', '_8_'
|
80
|
+
it_behaves_like :it_is_a_mismatch_for, Float::INFINITY, Float::NAN
|
81
|
+
# Does not accept floating-point-ish
|
82
|
+
it_behaves_like :it_is_a_mismatch_for, '1.0', '0.0', '1234567.0'
|
83
|
+
it_behaves_like :it_is_a_mismatch_for, '1e5', '1_234_567e-3', '1_234_567.0', '+11.123E+12'
|
84
|
+
# Handles hex
|
85
|
+
it_behaves_like :it_converts, '011' => 9, '0x10' => 16
|
86
|
+
# Intolerant of cruft, unlike GraciousIntegerFactory
|
87
|
+
it_behaves_like :it_is_a_mismatch_for, '0L', '1_234_567L', '1_234_567e-3f', '1,234,567'
|
88
|
+
#
|
89
|
+
it_behaves_like :it_is_registered_as, :int, :integer, Integer
|
90
|
+
its(:typename){ should == :integer }
|
91
|
+
end
|
92
|
+
|
93
|
+
describe Gorillib::Factory::GraciousIntegerFactory do
|
94
|
+
it_behaves_like :it_considers_native, 1, -1, 123_456_789_123_456_789_123_456_789_123_456_789
|
95
|
+
#
|
96
|
+
it_behaves_like :it_converts, '1' => 1, '0' => 0, '1234567' => 1234567
|
97
|
+
it_behaves_like :it_converts, '123456789123456789123456789123456789' => 123_456_789_123_456_789_123_456_789_123_456_789
|
98
|
+
it_behaves_like :it_converts, '1_234_567' => 1234567
|
99
|
+
it_behaves_like :it_converts, 1.0 => 1, 1.99 => 1, -0.9 => 0
|
100
|
+
it_behaves_like :it_converts, Complex(1,0) => 1, Complex(1.0,0) => 1, Rational(5,2) => 2
|
101
|
+
#
|
102
|
+
it_behaves_like :it_considers_blankish, nil, ''
|
103
|
+
it_behaves_like :it_is_a_mismatch_for, Complex(1,0.0), Complex(0,3), :foo, false, []
|
104
|
+
it_behaves_like :it_is_a_mismatch_for, '8_', 'one', '3blindmice', '_8_'
|
105
|
+
it_behaves_like :it_is_a_mismatch_for, Float::INFINITY, Float::NAN
|
106
|
+
# Handles floating-point well
|
107
|
+
it_behaves_like :it_converts, '1.0' => 1, '0.0' => 0, '1234567.0' => 1234567
|
108
|
+
it_behaves_like :it_converts, '1e5' => 100000, '1_234_567e-3' => 1234, '1_234.5e3' => 1_234_500, '+11.123E+12' => 11_123_000_000_000
|
109
|
+
# Silently confuses hex and octal
|
110
|
+
it_behaves_like :it_converts, '011' => 9, '0x10' => 16, '0x1.999999999999ap4' => 25
|
111
|
+
# Tolerates some cruft, unlike IntegerFactory
|
112
|
+
it_behaves_like :it_converts, '0L' => 0, '1_234_567L' => 1234567, '1234.5e3f' => 1_234_500, '1234567e-3f' => 1_234
|
113
|
+
it_behaves_like :it_converts, '1,234,567' => 1234567, ',,,,1,23,45.67e,-1,' => 1234
|
114
|
+
#
|
115
|
+
it_behaves_like :it_is_registered_as, :gracious_int
|
116
|
+
its(:typename){ should == :integer }
|
117
|
+
end
|
118
|
+
|
119
|
+
describe Gorillib::Factory::FloatFactory do
|
120
|
+
it_behaves_like :it_considers_native, 1.0, 1.234567e6, 123_456_789_123_456_789_123_456_789_123_456_789.0
|
121
|
+
it_behaves_like :it_considers_native, Float::INFINITY, Float::NAN
|
122
|
+
it_behaves_like :it_converts, '1' => 1.0, '0' => 0.0, '1234567' => 1234567.0
|
123
|
+
it_behaves_like :it_converts, '1.0' => 1.0, '0.0' => 0.0, '1234567.0' => 1234567.0
|
124
|
+
it_behaves_like :it_converts, '123456789123456789123456789123456789' => 123_456_789_123_456_789_123_456_789_123_456_789.0
|
125
|
+
it_behaves_like :it_converts, '1_234_567' => 1234567.0
|
126
|
+
it_behaves_like :it_converts, 1 => 1.0
|
127
|
+
it_behaves_like :it_converts, Complex(1,0) => 1.0, Complex(1.0,0) => 1.0, Rational(5,2) => 2.5
|
128
|
+
it_behaves_like :it_converts, '1e5' => 1e5, '1_234_567e-3' => 1234.567, '1_234_567.0' => 1234567.0, '+11.123E+700' => 11.123e700
|
129
|
+
#
|
130
|
+
it_behaves_like :it_considers_blankish, nil, ''
|
131
|
+
it_behaves_like :it_is_a_mismatch_for, Complex(1,0.0), Complex(0,3), :foo, false, []
|
132
|
+
#
|
133
|
+
# Different from #to_f
|
134
|
+
it_behaves_like :it_converts, '011' => 11.0, '0x10' => 16.0, '0x1.999999999999ap4' => 25.6
|
135
|
+
it_behaves_like :it_is_a_mismatch_for, '0L', '1_234_567L', '1_234_567e-3f'
|
136
|
+
it_behaves_like :it_is_a_mismatch_for, '_8_', 'one', '3blindmice', '8_'
|
137
|
+
#
|
138
|
+
it_behaves_like :it_is_registered_as, :float, Float
|
139
|
+
its(:typename){ should == :float }
|
140
|
+
end
|
141
|
+
|
142
|
+
describe Gorillib::Factory::GraciousFloatFactory do
|
143
|
+
it_behaves_like :it_considers_native, 1.0, 1.234567e6, 123_456_789_123_456_789_123_456_789_123_456_789.0
|
144
|
+
it_behaves_like :it_converts, '1' => 1.0, '0' => 0.0, '1234567' => 1234567.0
|
145
|
+
it_behaves_like :it_converts, '1.0' => 1.0, '0.0' => 0.0, '1234567.0' => 1234567.0
|
146
|
+
it_behaves_like :it_converts, '123456789123456789123456789123456789' => 123_456_789_123_456_789_123_456_789_123_456_789.0
|
147
|
+
it_behaves_like :it_converts, '1_234_567' => 1234567.0
|
148
|
+
it_behaves_like :it_converts, 1 => 1.0
|
149
|
+
it_behaves_like :it_converts, Complex(1,0) => 1.0, Complex(1.0,0) => 1.0, Rational(5,2) => 2.5
|
150
|
+
it_behaves_like :it_converts, '1e5' => 1e5, '1_234_567e-3' => 1234.567, '1_234_567.0' => 1234567.0, '+11.123E+700' => 11.123e700
|
151
|
+
#
|
152
|
+
it_behaves_like :it_considers_blankish, nil, ''
|
153
|
+
it_behaves_like :it_is_a_mismatch_for, Complex(1,0.0), Complex(0,3), :foo, false, []
|
154
|
+
#
|
155
|
+
# Different from stricter FloatFactory or laxer #to_f
|
156
|
+
it_behaves_like :it_converts, '011' => 11.0, '0x10' => 16.0, '0x1.999999999999ap4' => 25.6
|
157
|
+
it_behaves_like :it_converts, '0L' => 0.0, '1_234_567L' => 1234567.0, '1_234_567e-3f' => 1234.567
|
158
|
+
it_behaves_like :it_is_a_mismatch_for, '_8_', 'one', '3blindmice', '8_'
|
159
|
+
it_behaves_like :it_converts, '1,234,567e-3' => 1234.567, ',,,,1,23,45.67e,-1,' => 1234.567, '+11.123E+700' => 11.123e700
|
160
|
+
#
|
161
|
+
it_behaves_like :it_is_registered_as, :gracious_float
|
162
|
+
its(:typename){ should == :float }
|
163
|
+
end
|
164
|
+
|
165
|
+
describe Gorillib::Factory::ComplexFactory do
|
166
|
+
cplx0 = Complex(0) ; cplx1 = Complex(1) ; cplx1234500 = Complex(1_234_500,0) ; cplx1234500f = Complex(1_234_500.0,0) ;
|
167
|
+
it_behaves_like :it_considers_native, Complex(1,3), Complex(1,0)
|
168
|
+
it_behaves_like :it_converts, '1234.5e3' => cplx1234500f, '1234500' => cplx1234500, '0' => cplx0
|
169
|
+
it_behaves_like :it_converts, 1234.5e3 => cplx1234500f, 1 => cplx1, -1 => Complex(-1), Rational(3,2) => Complex(Rational(3,2),0)
|
170
|
+
it_behaves_like :it_converts, [1,0] => Complex(1), [1,2] => Complex(1,2)
|
171
|
+
it_behaves_like :it_converts, ['1234.5e3','98.6'] => Complex(1234.5e3, 98.6)
|
172
|
+
it_behaves_like :it_considers_blankish, nil, ''
|
173
|
+
it_behaves_like :it_is_a_mismatch_for, 'one', '3blindmice', '0x10', '1234.5e3f', '1234L', :foo, false, []
|
174
|
+
it_behaves_like :it_is_registered_as, :complex, Complex
|
175
|
+
its(:typename){ should == :complex }
|
176
|
+
end
|
177
|
+
|
178
|
+
describe Gorillib::Factory::RationalFactory do
|
179
|
+
rat_0 = Rational(0) ; rat1 = Rational(1) ; rat3_2 = Rational(3, 2) ;
|
180
|
+
it_behaves_like :it_considers_native, Rational(1, 3), Rational(1, 7)
|
181
|
+
it_behaves_like :it_converts, '1.5' => rat3_2, '1' => rat1, '0' => rat_0, '1_234_567' => Rational(1234567), '1_234_567.0' => Rational(1234567)
|
182
|
+
it_behaves_like :it_converts, 1.5 => rat3_2, 1 => rat1, -1 => Rational(-1), Complex(1.5) => rat3_2
|
183
|
+
it_behaves_like :it_considers_blankish, nil, ''
|
184
|
+
it_behaves_like :it_is_a_mismatch_for, 'one', '3blindmice', '0x10', '1234.5e3f', '1234L', :foo, false, [], Complex(1.5,3)
|
185
|
+
it_behaves_like :it_is_registered_as, :rational, Rational
|
186
|
+
its(:typename){ should == :rational }
|
187
|
+
end
|
188
|
+
|
189
|
+
describe Gorillib::Factory::TimeFactory do
|
190
|
+
fuck_wit_dre_day = Time.new(1993, 2, 18, 8, 8, 0, '-08:00') # and Everybody's Celebratin'
|
191
|
+
ice_cubes_good_day = Time.utc(1992, 1, 20, 0, 0, 0)
|
192
|
+
it_behaves_like :it_considers_native, Time.now.utc, ice_cubes_good_day
|
193
|
+
it_behaves_like :it_converts, fuck_wit_dre_day => fuck_wit_dre_day.getutc
|
194
|
+
it_behaves_like :it_converts, '19930218160800' => fuck_wit_dre_day.getutc, '19920120000000Z' => ice_cubes_good_day
|
195
|
+
it_behaves_like :it_converts, Date.new(1992, 1, 20) => ice_cubes_good_day
|
196
|
+
before('behaves like it_converts "an unparseable time" to nil'){ subject.stub(:warn) }
|
197
|
+
it_behaves_like :it_converts, "an unparseable time" => nil, :non_native_ok => true
|
198
|
+
it_behaves_like :it_considers_blankish, nil, ''
|
199
|
+
it_behaves_like :it_is_a_mismatch_for, :foo, false, []
|
200
|
+
it_behaves_like :it_is_registered_as, :time, Time
|
201
|
+
it('always returns a UTC timezoned time') do
|
202
|
+
subject.convert(fuck_wit_dre_day).utc_offset.should == 0
|
203
|
+
fuck_wit_dre_day.utc_offset.should == (-8 * 3600)
|
204
|
+
end
|
205
|
+
its(:typename){ should == :time }
|
206
|
+
end
|
207
|
+
|
208
|
+
describe Gorillib::Factory::BooleanFactory do
|
209
|
+
it_behaves_like :it_considers_native, true, false
|
210
|
+
it_behaves_like :it_considers_blankish, nil
|
211
|
+
it_behaves_like :it_converts, 'false' => false, :false => false
|
212
|
+
it_behaves_like :it_converts, 'true' => true, :true => true, '0' => true, 0 => true, [] => true, :foo => true, [] => true, Complex(1.5,3) => true, Object.new => true
|
213
|
+
it_behaves_like :it_is_registered_as, :boolean
|
214
|
+
its(:typename){ should == :boolean }
|
215
|
+
end
|
216
|
+
|
217
|
+
describe ::Whatever do
|
218
|
+
it_behaves_like :it_considers_native, true, false, nil, 3, '', 'a string', :a_symbol, [], {}, ->(){ 'a proc' }, Module.new, Complex(1,3), Object.new
|
219
|
+
it 'it is itself the factory for :identical and :whatever' do
|
220
|
+
keys = [Whatever, :identical, :whatever]
|
221
|
+
keys.each do |key|
|
222
|
+
Gorillib::Factory(key).should equal(described_class)
|
223
|
+
end
|
224
|
+
its_factory = ::Whatever
|
225
|
+
Gorillib::Factory.send(:factories).to_hash.select{|key,val| val.equal?(its_factory) }.keys.should == keys
|
226
|
+
end
|
227
|
+
end
|
228
|
+
describe Gorillib::Factory::IdenticalFactory do
|
229
|
+
it{ described_class.should equal(Whatever) }
|
230
|
+
end
|
231
|
+
|
232
|
+
describe Gorillib::Factory::ModuleFactory do
|
233
|
+
it_behaves_like :it_considers_blankish, nil
|
234
|
+
it_behaves_like :it_considers_native, Module, Module.new, Class, Class.new, Object, String, BasicObject
|
235
|
+
it_behaves_like :it_is_a_mismatch_for, true, false, 3, '', 'a string', :a_symbol, [], {}, ->(){ 'a proc' }, Complex(1,3), Object.new
|
236
|
+
it_behaves_like :it_is_registered_as, :module, Module
|
237
|
+
its(:typename){ should == :module }
|
238
|
+
end
|
239
|
+
|
240
|
+
describe Gorillib::Factory::ClassFactory do
|
241
|
+
it_behaves_like :it_considers_blankish, nil
|
242
|
+
it_behaves_like :it_considers_native, Module, Class, Class.new, Object, String, BasicObject
|
243
|
+
it_behaves_like :it_is_a_mismatch_for, true, false, 3, '', 'a string', :a_symbol, [], {}, ->(){ 'a proc' }, Module.new, Complex(1,3), Object.new
|
244
|
+
it_behaves_like :it_is_registered_as, :class, Class
|
245
|
+
its(:typename){ should == :class }
|
246
|
+
end
|
247
|
+
|
248
|
+
describe Gorillib::Factory::NilFactory do
|
249
|
+
it_behaves_like :it_considers_native, nil
|
250
|
+
it_behaves_like :it_is_a_mismatch_for, true, false, 3, '', 'a string', :a_symbol, [], {}, ->(){ 'a proc' }, Module.new, Complex(1,3), Object.new
|
251
|
+
it_behaves_like :it_is_registered_as, :nil, NilClass
|
252
|
+
its(:typename){ should == :nil_class }
|
253
|
+
end
|
254
|
+
|
255
|
+
describe Gorillib::Factory::TrueFactory do
|
256
|
+
it_behaves_like :it_considers_native, true
|
257
|
+
it_behaves_like :it_is_a_mismatch_for, false, 3, '', 'a string', :a_symbol, [], {}, ->(){ 'a proc' }, Module.new, Complex(1,3), Object.new
|
258
|
+
it_behaves_like :it_is_registered_as, :true, TrueClass
|
259
|
+
end
|
260
|
+
|
261
|
+
describe Gorillib::Factory::FalseFactory do
|
262
|
+
it_behaves_like :it_considers_native, false
|
263
|
+
it_behaves_like :it_is_a_mismatch_for, true, 3, '', 'a string', :a_symbol, [], {}, ->(){ 'a proc' }, Module.new, Complex(1,3), Object.new
|
264
|
+
it_behaves_like :it_is_registered_as, :false, FalseClass
|
265
|
+
end
|
266
|
+
|
267
|
+
describe Gorillib::Factory::RangeFactory do
|
268
|
+
it_behaves_like :it_considers_blankish, nil, []
|
269
|
+
it_behaves_like :it_considers_native, (1..2), ('a'..'z')
|
270
|
+
it_behaves_like :it_is_a_mismatch_for, true, 3, '', 'a string', :a_symbol, [1,2], {}, ->(){ 'a proc' }, Module.new, Complex(1,3), Object.new
|
271
|
+
it_behaves_like :it_is_registered_as, :range, Range
|
272
|
+
its(:typename){ should == :range }
|
273
|
+
end
|
274
|
+
|
275
|
+
# __________________________________________________________________________
|
276
|
+
|
277
|
+
describe Gorillib::Factory::HashFactory do
|
278
|
+
let(:collection_123){ { 'a' => 1, :b => 2, 'c' => 3 } }
|
279
|
+
let(:empty_collection){ {} }
|
280
|
+
|
281
|
+
it_behaves_like :it_considers_blankish, nil
|
282
|
+
it_behaves_like :it_converts, { {} => {}, { "a" => 2 } => { 'a' => 2 }, { :a => 2 } => { :a => 2 }, :non_native_ok => true }
|
283
|
+
it_behaves_like :it_is_a_mismatch_for, [1,2,3]
|
284
|
+
it_behaves_like :an_enumerable_factory
|
285
|
+
|
286
|
+
it 'follows examples' do
|
287
|
+
described_class.new.receive(collection_123).should == { 'a' => 1, :b => 2, 'c' => 3}
|
288
|
+
described_class.new(:keys => :symbol).receive({'a' => 'x', :b => 'y', 'c' => :z}).should == {:a => 'x', :b => 'y', :c => :z}
|
289
|
+
described_class.new(:items => :symbol).receive({'a' => 'x', :b => 'y', 'c' => :z}).should == {'a' => :x, :b => :y, 'c' => :z}
|
290
|
+
autov_factory = described_class.new(:empty_product => Hash.new{|h,k| h[k] = {} })
|
291
|
+
result = autov_factory.receive({:a => :b}) ; result.should == { :a => :b }
|
292
|
+
result[:flanger][:modacity] = 11 ; result.should == { :a => :b, :flanger => { :modacity => 11 }}
|
293
|
+
result2 = autov_factory.receive({:x => :y}) ; result2.should == { :x => :y } ; result.should == { :a => :b, :flanger => { :modacity => 11 }}
|
294
|
+
end
|
295
|
+
|
296
|
+
it "accepts a factory for the keys" do
|
297
|
+
mock_factory = double('factory')
|
298
|
+
mock_factory.should_receive(:receive).with(3).and_return("converted!")
|
299
|
+
factory = described_class.new(:keys => mock_factory)
|
300
|
+
factory.receive( { 3 => 4 } ).should == { 'converted!' => 4 }
|
301
|
+
end
|
302
|
+
it_behaves_like :it_is_registered_as, :hash, Hash
|
303
|
+
its(:typename){ should == :hash }
|
304
|
+
end
|
305
|
+
|
306
|
+
describe Gorillib::Factory::ArrayFactory do
|
307
|
+
let(:collection_123){ [1,2,3] }
|
308
|
+
let(:empty_collection){ [] }
|
309
|
+
|
310
|
+
it 'follows examples' do
|
311
|
+
described_class.new.receive([1,2,3]).should == [1,2,3]
|
312
|
+
described_class.new(:items => :symbol).receive(['a', 'b', :c]).should == [:a, :b, :c]
|
313
|
+
described_class.new(:empty_product => [1,2,3]).receive([:a, :b, :c]).should == [1, 2, 3, :a, :b, :c]
|
314
|
+
end
|
315
|
+
|
316
|
+
it_behaves_like :it_considers_blankish, nil
|
317
|
+
it_behaves_like :it_converts, { [] => [], {} => [], [1,2,3] => [1,2,3], {:a => :b} => [[:a, :b]], [:a] => [:a], [[]] => [[]], :non_native_ok => true }
|
318
|
+
it_behaves_like :an_enumerable_factory
|
319
|
+
it_behaves_like :it_is_registered_as, :array, Array
|
320
|
+
its(:typename){ should == :array }
|
321
|
+
end
|
322
|
+
|
323
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
require 'gorillib/model/lint'
|
4
|
+
|
5
|
+
describe Gorillib::Model::Lint, :model_spec => true do
|
6
|
+
subject do
|
7
|
+
klass = Class.new{ include Gorillib::Model ; include Gorillib::Model::Lint ; field :bob, Integer }
|
8
|
+
klass.new
|
9
|
+
end
|
10
|
+
|
11
|
+
context '#read_attribute' do
|
12
|
+
it "raises an error if the field does not exist" do
|
13
|
+
->{ subject.read_attribute(:fnord) }.should raise_error(Gorillib::Model::UnknownFieldError, /unknown field: fnord/)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
context '#write_attribute' do
|
18
|
+
it "raises an error if the field does not exist" do
|
19
|
+
->{ subject.write_attribute(:fnord, 8) }.should raise_error(Gorillib::Model::UnknownFieldError, /unknown field: fnord/)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
context '#attribute_set?' do
|
24
|
+
it "raises an error if the field does not exist" do
|
25
|
+
->{ subject.attribute_set?(:fnord) }.should raise_error(Gorillib::Model::UnknownFieldError, /unknown field: fnord/)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
require 'gorillib/model/serialization'
|
4
|
+
|
5
|
+
describe Gorillib::Model::LoadFromCsv, :model_spec => true, :builder_spec => true do
|
6
|
+
|
7
|
+
context ".load_csv" do
|
8
|
+
|
9
|
+
let(:expected_engine) do
|
10
|
+
{:name=>:Wankel, :carburetor=>:no, :volume=>1, :cylinders=>982, :owner=>"who_am_i"}
|
11
|
+
end
|
12
|
+
|
13
|
+
before :each do
|
14
|
+
engine_class.class_eval { include Gorillib::Model::LoadFromCsv }
|
15
|
+
csv_file = double('csv_file')
|
16
|
+
csv_file.stub(:shift) {}
|
17
|
+
csv_file.stub(:each).and_yield(expected_engine.values)
|
18
|
+
CSV.should_receive(:open).and_yield(csv_file)
|
19
|
+
end
|
20
|
+
|
21
|
+
it "loads from file" do
|
22
|
+
engine_class.load_csv('test').to_wire().first.keep_if{|k,| k != :_type}.should
|
23
|
+
eql(expected_engine)
|
24
|
+
end
|
25
|
+
|
26
|
+
it "loads from file with block" do
|
27
|
+
expect { |b| engine_class.load_csv('test', &b) }.to yield_with_args(engine_class)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
require 'gorillib/model/serialization'
|
4
|
+
|
5
|
+
describe Gorillib::Model::LoadFromTsv, :model_spec => true, :builder_spec => true do
|
6
|
+
|
7
|
+
context ".load_tsv" do
|
8
|
+
|
9
|
+
let(:expected_engine) do
|
10
|
+
{:name=>:Wankel, :carburetor=>:no, :volume=>1, :cylinders=>982, :owner=>"who_am_i"}
|
11
|
+
end
|
12
|
+
|
13
|
+
before :each do
|
14
|
+
engine_class.class_eval { include Gorillib::Model::LoadFromTsv }
|
15
|
+
engine_class.should_receive(:_each_raw_line).with(:test, {}).
|
16
|
+
and_yield(expected_engine.values.join("\t"))
|
17
|
+
end
|
18
|
+
|
19
|
+
it "loads from file" do
|
20
|
+
engine_class.load_tsv(:test).to_wire().first.keep_if{|k,| k != :_type}.should
|
21
|
+
eql(expected_engine)
|
22
|
+
end
|
23
|
+
|
24
|
+
it "loads from file with block" do
|
25
|
+
expect { |b| engine_class.load_tsv(:test, &b) }.to yield_with_args(engine_class)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
require 'gorillib/model/serialization'
|
4
|
+
|
5
|
+
describe Gorillib::Model, :model_spec => true, :builder_spec => true do
|
6
|
+
subject do
|
7
|
+
garage.cars << wildcat
|
8
|
+
garage.cars << ford_39
|
9
|
+
garage
|
10
|
+
end
|
11
|
+
let :wired_garage_hash do
|
12
|
+
{ :cars => [
|
13
|
+
{:name=>:wildcat, :make_model=>"Buick Wildcat", :year=>1968, :doors=>2, :engine=>{:volume=>455, :cylinders=>8, :_type => "gorillib.test.engine"}, :_type => "gorillib.test.car"},
|
14
|
+
{:name=>:ford_39, :make_model=>"Ford Tudor Sedan", :year=>1939, :doors=>2, :_type => "gorillib.test.car"}, ], :_type => "gorillib.test.garage" }
|
15
|
+
end
|
16
|
+
|
17
|
+
describe 'to_json' do
|
18
|
+
it 'recursively serializes' do
|
19
|
+
MultiJson.load(wildcat.to_json).should == {"name"=>"wildcat","make_model"=>"Buick Wildcat","year"=>1968,"doors"=>2,"engine"=>{"volume"=>455,"cylinders"=>8, "_type"=>"gorillib.test.engine"},"_type"=>"gorillib.test.car"}
|
20
|
+
end
|
21
|
+
it 'recursively serializes' do
|
22
|
+
subject.to_json.should == MultiJson.dump(wired_garage_hash)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
describe 'to_wire' do
|
27
|
+
it 'calls to_wire recursively, passing options along' do
|
28
|
+
opts = {:dummy=>'options'}
|
29
|
+
ford_39.should_receive(:to_wire).with(opts)
|
30
|
+
wildcat.engine.should_receive(:to_wire).with(opts)
|
31
|
+
subject.to_wire(opts)
|
32
|
+
end
|
33
|
+
|
34
|
+
it 'returns a nested hash' do
|
35
|
+
subject.to_wire.should == wired_garage_hash
|
36
|
+
end
|
37
|
+
it 'aliases method as_json' do
|
38
|
+
subject.as_json.should == wired_garage_hash
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,166 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
require 'gorillib/model/type/extended'
|
4
|
+
|
5
|
+
describe ::Long do
|
6
|
+
it "is_a?(Integer)" do ::Long.should < ::Integer ; end
|
7
|
+
end
|
8
|
+
|
9
|
+
describe ::Double do
|
10
|
+
it "is_a?(Float)" do ::Double.should < ::Float ; end
|
11
|
+
end
|
12
|
+
|
13
|
+
describe ::Binary do
|
14
|
+
it "is_a?(String)" do ::Binary.should < ::String ; end
|
15
|
+
end
|
16
|
+
|
17
|
+
describe 'factory', :factory_spec => true do
|
18
|
+
describe Gorillib::Factory::DateFactory do
|
19
|
+
fuck_wit_dre_day = Date.new(1993, 2, 18) # and Everybody's Celebratin'
|
20
|
+
ice_cubes_good_day = Date.new(1992, 1, 20)
|
21
|
+
it_behaves_like :it_considers_native, Date.today, fuck_wit_dre_day, ice_cubes_good_day
|
22
|
+
it_behaves_like :it_converts, '19930218' => fuck_wit_dre_day, '19920120' => ice_cubes_good_day
|
23
|
+
it_behaves_like :it_converts, Time.utc(1992, 1, 20, 8, 8, 8) => ice_cubes_good_day
|
24
|
+
before('behaves like it_converts "an unparseable date" to nil'){ subject.stub(:warn) }
|
25
|
+
it_behaves_like :it_converts, "an unparseable date" => nil, :non_native_ok => true
|
26
|
+
it_behaves_like :it_considers_blankish, nil, ""
|
27
|
+
it_behaves_like :it_is_a_mismatch_for, :foo, false, []
|
28
|
+
it_behaves_like :it_is_registered_as, :date, Date
|
29
|
+
its(:typename){ should == :date }
|
30
|
+
end
|
31
|
+
|
32
|
+
describe Gorillib::Factory::SetFactory do
|
33
|
+
let(:collection_123){ Set.new([1,2,3]) }
|
34
|
+
let(:empty_collection){ Set.new }
|
35
|
+
|
36
|
+
it 'follows examples' do
|
37
|
+
described_class.new.receive([1,2,3]).should == collection_123
|
38
|
+
described_class.new(:items => :symbol).receive(['a', 'b', :c]).should == [:a, :b, :c].to_set
|
39
|
+
described_class.new(:empty_product => [1,2,3].to_set).receive([:a, :b, :c]).should == [1, 2, 3, :a, :b, :c].to_set
|
40
|
+
|
41
|
+
has_an_empty_array = described_class.new.receive( [[]] )
|
42
|
+
has_an_empty_array.should == Set.new( [[]] )
|
43
|
+
has_an_empty_array.first.should == []
|
44
|
+
has_an_empty_array.size.should == 1
|
45
|
+
end
|
46
|
+
|
47
|
+
it_behaves_like :it_considers_blankish, nil
|
48
|
+
it_behaves_like :it_converts, { [] => Set.new, {} => Set.new, [1,2,3] => [1,2,3].to_set, {:a => :b} => Set.new({:a => :b}), [:a] => [:a].to_set, :non_native_ok => true }
|
49
|
+
it_behaves_like :an_enumerable_factory
|
50
|
+
it_behaves_like :it_is_registered_as, :set, Set
|
51
|
+
its(:typename){ should == :set }
|
52
|
+
end
|
53
|
+
|
54
|
+
describe Gorillib::Factory::Boolean10Factory do
|
55
|
+
it_behaves_like :it_considers_native, true, false
|
56
|
+
it_behaves_like :it_considers_blankish, nil
|
57
|
+
it_behaves_like :it_converts, "false" => false, :false => false, "0" => false, 0 => false
|
58
|
+
it_behaves_like :it_converts, "true" => true, :true => true, "1" => true, [] => true, :foo => true, [] => true, Complex(1.5,3) => true, Object.new => true
|
59
|
+
it_behaves_like :it_is_registered_as, :boolean_10
|
60
|
+
its(:typename){ should == :boolean_10 }
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
# describe ::Boolean, :model_spec => true do
|
65
|
+
# let(:true_bool ){ ::Boolean.new(true) }
|
66
|
+
# let(:false_bool){ ::Boolean.new(false) }
|
67
|
+
#
|
68
|
+
# def it_responds_same_as(test_obj, comparable, meth, *meth_args, &block)
|
69
|
+
# test_obj.send(meth, *meth_args, &block).should == comparable.send(meth, *meth_args, &block)
|
70
|
+
# end
|
71
|
+
#
|
72
|
+
# def it_responds_with_same_contents(test_obj, comparable, meth, *meth_args, &block)
|
73
|
+
# test_obj.send(meth, *meth_args, &block).sort.should == comparable.send(meth, *meth_args, &block).sort
|
74
|
+
# end
|
75
|
+
#
|
76
|
+
# it("has #class ::Boolean" ){ (true_bool.class).should == ::Boolean ; (false_bool.class).should == ::Boolean }
|
77
|
+
#
|
78
|
+
# it "#is_a?(Boolean)" do true_bool.should be_a(::Boolean) ; false_bool.should be_a(::Boolean) ; end
|
79
|
+
# it "#is_a?(True/False)" do true_bool.should be_a(::TrueClass) ; false_bool.should be_a(::FalseClass) ; end
|
80
|
+
# it "#kind_of?(Boolean)" do true_bool.should be_a_kind_of(::Boolean) ; false_bool.should be_a_kind_of(::Boolean) ; end
|
81
|
+
# it "#instance_of?(True/False)" do true_bool.should be_instance_of(::TrueClass) ; false_bool.should be_instance_of(::FalseClass) ; end
|
82
|
+
#
|
83
|
+
# describe 'mimics true/false' do
|
84
|
+
# [ :!, :to_s, :blank?, :frozen?, :nil?, :present?,
|
85
|
+
# ].each do |meth|
|
86
|
+
# it "##{meth}" do
|
87
|
+
# it_responds_same_as(true_bool, true, meth)
|
88
|
+
# it_responds_same_as(false_bool, false, meth)
|
89
|
+
# end
|
90
|
+
# end
|
91
|
+
#
|
92
|
+
# [ :private_methods, :protected_methods, :singleton_methods,
|
93
|
+
# ].each do |meth|
|
94
|
+
# it "##{meth}" do
|
95
|
+
# it_responds_with_same_contents(true_bool, true, meth)
|
96
|
+
# it_responds_with_same_contents(false_bool, false, meth)
|
97
|
+
# end
|
98
|
+
# end
|
99
|
+
# it "#methods" do ( true.methods - true_bool.methods ).should be_empty ; end
|
100
|
+
# it "#methods" do ( false.methods - false_bool.methods ).should be_empty ; end
|
101
|
+
# it "#public_methods" do ( true.public_methods - true_bool.public_methods ).should be_empty ; end
|
102
|
+
# it "#public_methods" do ( false.public_methods - false_bool.public_methods ).should be_empty ; end
|
103
|
+
#
|
104
|
+
# it ".methods" do (TrueClass.methods | [:true, :false, :new]).sort.should == Boolean.methods.sort ; end
|
105
|
+
#
|
106
|
+
# { :!= => [true, false, nil],
|
107
|
+
# :!~ => [true, false, nil],
|
108
|
+
# :& => [true, false, nil],
|
109
|
+
# :<=> => [true, false, nil],
|
110
|
+
# :== => [true, false, nil],
|
111
|
+
# :=== => [true, false, nil],
|
112
|
+
# :=~ => [true, false, nil],
|
113
|
+
# :^ => [true, false, nil],
|
114
|
+
# :| => [true, false, nil],
|
115
|
+
# :eql? => [true, false, nil],
|
116
|
+
# :equal? => [true, false, nil],
|
117
|
+
# :instance_of? => [::TrueClass, ::FalseClass, ::Object],
|
118
|
+
# :is_a? => [::TrueClass, ::FalseClass, ::Object],
|
119
|
+
# :kind_of? => [::TrueClass, ::FalseClass, ::Object],
|
120
|
+
# }.each do |meth, meth_args|
|
121
|
+
# meth_args.each do |meth_arg|
|
122
|
+
# it "##{meth}(#{meth_arg})" do
|
123
|
+
# it_responds_same_as(true_bool, true, meth, meth_arg)
|
124
|
+
# it_responds_same_as(false_bool, false, meth, meth_arg)
|
125
|
+
# end
|
126
|
+
# end
|
127
|
+
# end
|
128
|
+
#
|
129
|
+
# end
|
130
|
+
#
|
131
|
+
# [ :==, :===, :eql?, :equal?, :<=> ].each do |meth|
|
132
|
+
# it "Boolean.true #{meth} itself and true" do
|
133
|
+
# true_bool.send(meth, true_bool ).should be_true
|
134
|
+
# true_bool.send(meth, Boolean.true ).should be_true
|
135
|
+
# true_bool.send(meth, true ).should be_true
|
136
|
+
# true_bool.send(meth, false_bool ).should be_false
|
137
|
+
# true_bool.send(meth, Boolean.false ).should be_false
|
138
|
+
# true_bool.send(meth, false ).should be_false
|
139
|
+
# true_bool.send(meth, 0 ).should be_false
|
140
|
+
# end
|
141
|
+
# it "Boolean.false #{meth} itself and false" do
|
142
|
+
# false_bool.send(meth, false_bool ).should be_true
|
143
|
+
# false_bool.send(meth, Boolean.false ).should be_true
|
144
|
+
# false_bool.send(meth, false ).should be_true
|
145
|
+
# false_bool.send(meth, true_bool ).should be_false
|
146
|
+
# false_bool.send(meth, Boolean.true ).should be_false
|
147
|
+
# false_bool.send(meth, true ).should be_false
|
148
|
+
# false_bool.send(meth, 0 ).should be_false
|
149
|
+
# end
|
150
|
+
# it "!=" do
|
151
|
+
# (true_bool != true ).should be_false ; (true_bool != false ).should be_true
|
152
|
+
# (true_bool != true_bool ).should be_false ; (true_bool != false_bool ).should be_true
|
153
|
+
# (true_bool != Boolean.true ).should be_false ; (true_bool != Boolean.false).should be_true
|
154
|
+
# (true_bool != 0 ).should be_true ; (true_bool != "true" ).should be_true
|
155
|
+
# (false_bool != false ).should be_false ; (false_bool != true ).should be_true
|
156
|
+
# (false_bool != false_bool ).should be_false ; (false_bool != true_bool ).should be_true
|
157
|
+
# (false_bool != Boolean.false).should be_false ; (false_bool != Boolean.true ).should be_true
|
158
|
+
# (false_bool != 0 ).should be_true ; (false_bool != "true" ).should be_true
|
159
|
+
# end
|
160
|
+
# it "!~" do
|
161
|
+
# (true_bool !~ true ).should be_true
|
162
|
+
# (true_bool !~ true_bool ).should be_true
|
163
|
+
# (true_bool !~ Boolean.true).should be_true
|
164
|
+
# end
|
165
|
+
# end
|
166
|
+
# end
|