gorillib 0.1.11 → 0.4.0pre
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +1 -0
- data/.rspec +1 -2
- data/.yardopts +9 -0
- data/{CHANGELOG.textile → CHANGELOG.md} +35 -9
- data/Gemfile +21 -14
- data/Guardfile +19 -0
- data/{LICENSE.textile → LICENSE.md} +43 -29
- data/README.md +47 -52
- data/Rakefile +31 -30
- data/TODO.md +32 -0
- data/VERSION +1 -1
- data/examples/builder/ironfan.rb +133 -0
- data/examples/model/simple.rb +17 -0
- data/gorillib.gemspec +106 -86
- data/lib/alt/kernel/call_stack.rb +56 -0
- data/lib/gorillib/array/wrap.rb +53 -0
- data/lib/gorillib/base.rb +3 -3
- data/lib/gorillib/builder/field.rb +5 -0
- data/lib/gorillib/builder.rb +260 -0
- data/lib/gorillib/collection/has_collection.rb +31 -0
- data/lib/gorillib/collection.rb +129 -0
- data/lib/gorillib/configurable.rb +28 -0
- data/lib/gorillib/datetime/{flat.rb → to_flat.rb} +0 -0
- data/lib/gorillib/exception/confidence.rb +17 -0
- data/lib/gorillib/exception/raisers.rb +78 -0
- data/lib/gorillib/hash/mash.rb +202 -0
- data/lib/gorillib/hashlike/slice.rb +53 -19
- data/lib/gorillib/hashlike.rb +5 -3
- data/lib/gorillib/io/system_helpers.rb +30 -0
- data/lib/gorillib/logger/log.rb +18 -0
- data/lib/gorillib/metaprogramming/concern.rb +124 -0
- data/lib/gorillib/model/active_model_conversion.rb +68 -0
- data/lib/gorillib/model/active_model_naming.rb +87 -0
- data/lib/gorillib/model/active_model_shim.rb +33 -0
- data/lib/gorillib/model/base.rb +341 -0
- data/lib/gorillib/model/defaults.rb +71 -0
- data/lib/gorillib/model/errors.rb +14 -0
- data/lib/gorillib/model/factories.rb +372 -0
- data/lib/gorillib/model/field.rb +146 -0
- data/lib/gorillib/model/named_schema.rb +53 -0
- data/lib/gorillib/{struct/hashlike_iteration.rb → model/overlay.rb} +0 -0
- data/lib/gorillib/model/record_schema.rb +9 -0
- data/lib/gorillib/model/serialization.rb +23 -0
- data/lib/gorillib/model/validate.rb +22 -0
- data/lib/gorillib/model.rb +23 -0
- data/lib/gorillib/pathname.rb +78 -0
- data/lib/gorillib/{serialization.rb → serialization/to_wire.rb} +0 -0
- data/lib/gorillib/some.rb +11 -9
- data/lib/gorillib/string/constantize.rb +21 -14
- data/lib/gorillib/string/inflections.rb +6 -76
- data/lib/gorillib/string/inflector.rb +192 -0
- data/lib/gorillib/string/simple_inflector.rb +267 -0
- data/lib/gorillib/type/extended.rb +52 -0
- data/lib/gorillib/utils/capture_output.rb +28 -0
- data/lib/gorillib/utils/console.rb +131 -0
- data/lib/gorillib/utils/nuke_constants.rb +9 -0
- data/lib/gorillib/utils/stub_module.rb +33 -0
- data/spec/examples/builder/ironfan_spec.rb +37 -0
- data/spec/extlib/hash_spec.rb +64 -0
- data/spec/extlib/mash_spec.rb +312 -0
- data/spec/{array → gorillib/array}/compact_blank_spec.rb +2 -2
- data/spec/{array → gorillib/array}/extract_options_spec.rb +2 -2
- data/spec/gorillib/builder_spec.rb +187 -0
- data/spec/gorillib/collection_spec.rb +20 -0
- data/spec/gorillib/configurable_spec.rb +62 -0
- data/spec/{datetime → gorillib/datetime}/parse_spec.rb +3 -3
- data/spec/{datetime/flat_spec.rb → gorillib/datetime/to_flat_spec.rb} +4 -4
- data/spec/{enumerable → gorillib/enumerable}/sum_spec.rb +5 -5
- data/spec/gorillib/exception/raisers_spec.rb +60 -0
- data/spec/{hash → gorillib/hash}/compact_spec.rb +2 -2
- data/spec/{hash → gorillib/hash}/deep_compact_spec.rb +3 -3
- data/spec/{hash → gorillib/hash}/deep_merge_spec.rb +2 -2
- data/spec/{hash → gorillib/hash}/keys_spec.rb +2 -2
- data/spec/{hash → gorillib/hash}/reverse_merge_spec.rb +2 -2
- data/spec/{hash → gorillib/hash}/slice_spec.rb +2 -2
- data/spec/{hash → gorillib/hash}/zip_spec.rb +2 -2
- data/spec/{hashlike → gorillib/hashlike}/behave_same_as_hash_spec.rb +6 -3
- data/spec/{hashlike → gorillib/hashlike}/deep_hash_spec.rb +2 -2
- data/spec/{hashlike → gorillib/hashlike}/hashlike_behavior_spec.rb +32 -30
- data/spec/{hashlike → gorillib/hashlike}/hashlike_via_accessors_spec.rb +3 -3
- data/spec/{hashlike_spec.rb → gorillib/hashlike_spec.rb} +3 -3
- data/spec/{logger → gorillib/logger}/log_spec.rb +2 -2
- data/spec/{metaprogramming → gorillib/metaprogramming}/aliasing_spec.rb +3 -3
- data/spec/{metaprogramming → gorillib/metaprogramming}/class_attribute_spec.rb +3 -3
- data/spec/{metaprogramming → gorillib/metaprogramming}/delegation_spec.rb +3 -3
- data/spec/{metaprogramming → gorillib/metaprogramming}/singleton_class_spec.rb +3 -3
- data/spec/gorillib/model/record/defaults_spec.rb +108 -0
- data/spec/gorillib/model/record/factories_spec.rb +321 -0
- data/spec/gorillib/model/record/overlay_spec.rb +46 -0
- data/spec/gorillib/model/serialization_spec.rb +48 -0
- data/spec/gorillib/model_spec.rb +281 -0
- data/spec/{numeric → gorillib/numeric}/clamp_spec.rb +2 -2
- data/spec/{object → gorillib/object}/blank_spec.rb +2 -2
- data/spec/{object → gorillib/object}/try_dup_spec.rb +2 -2
- data/spec/{object → gorillib/object}/try_spec.rb +3 -2
- data/spec/gorillib/pathname_spec.rb +114 -0
- data/spec/{string → gorillib/string}/constantize_spec.rb +2 -2
- data/spec/{string → gorillib/string}/human_spec.rb +2 -2
- data/spec/{string → gorillib/string}/inflections_spec.rb +4 -3
- data/spec/{string → gorillib/string}/inflector_test_cases.rb +0 -0
- data/spec/{string → gorillib/string}/truncate_spec.rb +4 -10
- data/spec/gorillib/type/extended_spec.rb +120 -0
- data/spec/gorillib/utils/capture_output_spec.rb +71 -0
- data/spec/spec_helper.rb +8 -11
- data/spec/support/gorillib_test_helpers.rb +66 -0
- data/spec/support/hashlike_fuzzing_helper.rb +31 -33
- data/spec/support/hashlike_helper.rb +3 -3
- data/spec/support/model_test_helpers.rb +81 -0
- data/spec/support/shared_examples/included_module.rb +20 -0
- metadata +177 -158
- data/lib/gorillib/array/average.rb +0 -13
- data/lib/gorillib/array/sorted_median.rb +0 -11
- data/lib/gorillib/array/sorted_percentile.rb +0 -11
- data/lib/gorillib/array/sorted_sample.rb +0 -12
- data/lib/gorillib/dsl_object.rb +0 -64
- data/lib/gorillib/hash/indifferent_access.rb +0 -207
- data/lib/gorillib/hash/tree_merge.rb +0 -4
- data/lib/gorillib/hashlike/tree_merge.rb +0 -49
- data/lib/gorillib/metaprogramming/cattr_accessor.rb +0 -79
- data/lib/gorillib/metaprogramming/mattr_accessor.rb +0 -61
- data/lib/gorillib/receiver/active_model_shim.rb +0 -32
- data/lib/gorillib/receiver/acts_as_hash.rb +0 -195
- data/lib/gorillib/receiver/acts_as_loadable.rb +0 -42
- data/lib/gorillib/receiver/locale/en.yml +0 -27
- data/lib/gorillib/receiver/tree_diff.rb +0 -74
- data/lib/gorillib/receiver/validations.rb +0 -30
- data/lib/gorillib/receiver.rb +0 -402
- data/lib/gorillib/receiver_model.rb +0 -21
- data/lib/gorillib/struct/acts_as_hash.rb +0 -108
- data/notes/fancy_hashes_and_receivers.textile +0 -120
- data/notes/hash_rdocs.textile +0 -97
- data/spec/array/average_spec.rb +0 -24
- data/spec/array/sorted_median_spec.rb +0 -18
- data/spec/array/sorted_percentile_spec.rb +0 -24
- data/spec/array/sorted_sample_spec.rb +0 -28
- data/spec/dsl_object_spec.rb +0 -99
- data/spec/hash/indifferent_access_spec.rb +0 -391
- data/spec/metaprogramming/cattr_accessor_spec.rb +0 -43
- data/spec/metaprogramming/mattr_accessor_spec.rb +0 -45
- data/spec/receiver/acts_as_hash_spec.rb +0 -295
- data/spec/receiver_spec.rb +0 -551
- data/spec/struct/acts_as_hash_fuzz_spec.rb +0 -71
- data/spec/struct/acts_as_hash_spec.rb +0 -422
@@ -0,0 +1,281 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'model_test_helpers'
|
3
|
+
|
4
|
+
require 'gorillib/model'
|
5
|
+
|
6
|
+
describe Gorillib::Model, :model_spec => true do
|
7
|
+
|
8
|
+
let(:simple_model){ class Gorillib::Test::TestClass ; include Gorillib::Model ; field :my_field, Whatever ; self ; end }
|
9
|
+
let(:anon_class){ Class.new{ include Gorillib::Model ; field :my_field, :whatever } }
|
10
|
+
let(:example_inst){ subject.receive(:my_field => 69) }
|
11
|
+
let(:example_val){ mock('example val') }
|
12
|
+
|
13
|
+
let(:complex_class) do
|
14
|
+
class Gorillib::Test::ComplexModel
|
15
|
+
include Gorillib::Model
|
16
|
+
field :my_field, :whatever
|
17
|
+
field :str_field, String
|
18
|
+
field :sym_field, Symbol
|
19
|
+
self
|
20
|
+
end
|
21
|
+
end
|
22
|
+
let(:complex_subclass){ Gorillib::Test::TestSubclass = Class.new(complex_class){ field :zyzzyva, Integer; field :acme, Integer } }
|
23
|
+
|
24
|
+
subject{ complex_class }
|
25
|
+
|
26
|
+
context 'examples' do
|
27
|
+
let(:nested_class){ Class.new(complex_class){ field :another_model, self } }
|
28
|
+
it 'type-converts values' do
|
29
|
+
obj = complex_class.receive({
|
30
|
+
:my_field => 'accepted as-is', :str_field => :bob, :sym_field => 'converted_to_sym'
|
31
|
+
})
|
32
|
+
obj.attributes.should == { :my_field => 'accepted as-is', :str_field => 'bob', :sym_field=>:converted_to_sym }
|
33
|
+
end
|
34
|
+
it 'handles nested structures' do
|
35
|
+
obj = nested_class.receive({ :my_field => 69 })
|
36
|
+
obj.attributes.should == { :my_field => 69, :str_field => nil, :sym_field=>nil, :another_model => nil }
|
37
|
+
deep_obj = nested_class.receive(:my_field => 111, :str_field => 'deep, man',
|
38
|
+
:another_model => { :my_field => 69, :another_model => nil })
|
39
|
+
deep_obj.attributes.should == { :my_field => 111, :str_field => 'deep, man', :sym_field=>nil, :another_model => obj }
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
context ".field" do
|
44
|
+
subject{ simple_model }
|
45
|
+
it "describes an attribute" do
|
46
|
+
example_inst.attributes.should == { :my_field => 69 }
|
47
|
+
example_inst.write_attribute(:my_field, 3).should == 3
|
48
|
+
example_inst.attributes.should == { :my_field => 3 }
|
49
|
+
example_inst.read_attribute(:my_field).should == 3
|
50
|
+
end
|
51
|
+
it 'inherits fields from its parent class, even if they are added later' do
|
52
|
+
complex_class.field_names.should == [:my_field, :str_field, :sym_field]
|
53
|
+
complex_subclass.field_names.should == [:my_field, :str_field, :sym_field, :zyzzyva, :acme]
|
54
|
+
complex_class.field :banksy, String
|
55
|
+
complex_class.field_names.should == [:my_field, :str_field, :sym_field, :banksy ]
|
56
|
+
complex_subclass.field_names.should == [:my_field, :str_field, :sym_field, :banksy, :zyzzyva, :acme]
|
57
|
+
end
|
58
|
+
|
59
|
+
it "supplies a reader method #foo to call read_attribute(:foo)" do
|
60
|
+
example_inst.should_receive(:read_attribute).with(:my_field).and_return(example_val)
|
61
|
+
example_inst.my_field.should == example_val
|
62
|
+
end
|
63
|
+
it "supplies a writer method #foo= to call write_attribute(:foo)" do
|
64
|
+
example_inst.should_receive(:write_attribute).with(:my_field, example_val)
|
65
|
+
(example_inst.my_field = example_val).should == example_val
|
66
|
+
end
|
67
|
+
it "supplies a receiver method #receive_foo to call write_attribute(:foo) and return self" do
|
68
|
+
example_inst.should_receive(:write_attribute).with(:my_field, example_val)
|
69
|
+
(example_inst.receive_my_field(example_val)).should == example_inst
|
70
|
+
end
|
71
|
+
it "sets visibility of reader with :reader => ()" do
|
72
|
+
subject.field :test_field, Integer, :reader => :private, :writer => false
|
73
|
+
subject.public_instance_methods.should_not include(:test_field)
|
74
|
+
subject.private_instance_methods.should include(:test_field)
|
75
|
+
subject.public_instance_methods.should_not include(:test_field=)
|
76
|
+
subject.private_instance_methods.should_not include(:test_field=)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
|
80
|
+
context '.field' do
|
81
|
+
subject{ complex_class.new }
|
82
|
+
let(:sample_val){ 'bob' }
|
83
|
+
let(:raw_val){ :bob }
|
84
|
+
it_behaves_like 'a model field', :str_field
|
85
|
+
end
|
86
|
+
|
87
|
+
context '#attributes' do
|
88
|
+
it "maps field names to attribute values" do
|
89
|
+
example_inst = subject.receive({:my_field=>7, :str_field=>'yo', :sym_field=>:sup})
|
90
|
+
example_inst.attributes.should == {:my_field=>7, :str_field=>'yo', :sym_field=>:sup}
|
91
|
+
end
|
92
|
+
it "includes all field names, set and unset" do
|
93
|
+
example_inst.attributes.should == {:my_field=>69, :str_field=>nil, :sym_field=>nil}
|
94
|
+
example_inst.receive!(:my_field=>7, :str_field=>'yo')
|
95
|
+
example_inst.attributes.should == {:my_field=>7, :str_field=>'yo', :sym_field=>nil}
|
96
|
+
end
|
97
|
+
it "goes throught the #read_attribute interface" do
|
98
|
+
example_inst.should_receive(:read_attribute).with(:my_field).and_return('int')
|
99
|
+
example_inst.should_receive(:read_attribute).with(:str_field).and_return('str')
|
100
|
+
example_inst.should_receive(:read_attribute).with(:sym_field).and_return('sym')
|
101
|
+
example_inst.attributes.should == {:my_field=>'int', :str_field=>'str', :sym_field=>'sym'}
|
102
|
+
end
|
103
|
+
it "is an empty hash if there are no fields" do
|
104
|
+
subject = Class.new{ include Gorillib::Model }
|
105
|
+
subject.new.attributes.should == {}
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
context '#unset_attribute' do
|
110
|
+
it "unsets the attribute" do
|
111
|
+
example_inst.attribute_set?(:my_field).should be_true
|
112
|
+
example_inst.unset_attribute(:my_field)
|
113
|
+
example_inst.attribute_set?(:my_field).should be_false
|
114
|
+
end
|
115
|
+
it "if set, returns the former value" do
|
116
|
+
example_inst.unset_attribute(:my_field ).should == 69
|
117
|
+
example_inst.unset_attribute(:str_field).should == nil
|
118
|
+
end
|
119
|
+
it "raises an error if the field does not exist" do
|
120
|
+
->{ example_inst.unset_attribute(:fnord) }.should raise_error(Gorillib::Model::UnknownFieldError, /unknown field: fnord/)
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
context '#update_attributes' do
|
125
|
+
it "consumes a map from field names to new values" do
|
126
|
+
example_inst.attributes.should == {:my_field=>69, :str_field=>nil, :sym_field=>nil}
|
127
|
+
example_inst.update_attributes({:my_field=>7, :str_field=>'yo'})
|
128
|
+
example_inst.attributes.should == {:my_field=>7, :str_field=>'yo', :sym_field=>nil}
|
129
|
+
example_inst.update_attributes({:str_field=>'ok', :sym_field => :bye})
|
130
|
+
example_inst.attributes.should == {:my_field=>7, :str_field=>'ok', :sym_field=>:bye}
|
131
|
+
end
|
132
|
+
it "takes string or symbol keys" do
|
133
|
+
example_inst.update_attributes 'my_field'=>7, :str_field=>'yo'
|
134
|
+
example_inst.attributes.should == {:my_field=>7, :str_field=>'yo', :sym_field=>nil}
|
135
|
+
end
|
136
|
+
it "goes throught the #write_attribute interface" do
|
137
|
+
example_inst.should_receive(:write_attribute).with(:my_field, 7)
|
138
|
+
example_inst.should_receive(:write_attribute).with(:str_field, 'yo')
|
139
|
+
example_inst.update_attributes 'my_field'=>7, :str_field=>'yo'
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
context '#receive!' do
|
144
|
+
it "consumes a map from field names to new values" do
|
145
|
+
example_inst.attributes.should == {:my_field=>69, :str_field=>nil, :sym_field=>nil}
|
146
|
+
example_inst.receive!({:my_field=>7, :str_field=>'yo'})
|
147
|
+
example_inst.attributes.should == {:my_field=>7, :str_field=>'yo', :sym_field=>nil}
|
148
|
+
example_inst.receive!({:str_field=>'ok', :sym_field => :bye})
|
149
|
+
example_inst.attributes.should == {:my_field=>7, :str_field=>'ok', :sym_field=>:bye}
|
150
|
+
end
|
151
|
+
it "takes string or symbol keys" do
|
152
|
+
example_inst.receive! 'my_field'=>7, :str_field=>'yo'
|
153
|
+
example_inst.attributes.should == {:my_field=>7, :str_field=>'yo', :sym_field=>nil}
|
154
|
+
end
|
155
|
+
it "goes throught the #write_attribute interface" do
|
156
|
+
example_inst.should_receive(:write_attribute).with(:my_field, 7)
|
157
|
+
example_inst.should_receive(:write_attribute).with(:str_field, 'yo')
|
158
|
+
example_inst.receive! 'my_field'=>7, :str_field=>'yo'
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
context '#== -- two models are equal if' do
|
163
|
+
let(:subklass){ Class.new(subject) }
|
164
|
+
let(:obj_2){ subject.receive(:my_field => 69) }
|
165
|
+
let(:obj_3){ subklass.receive(:my_field => 69) }
|
166
|
+
|
167
|
+
it 'they have the same class' do
|
168
|
+
example_inst.attributes.should == obj_2.attributes
|
169
|
+
example_inst.attributes.should == obj_3.attributes
|
170
|
+
example_inst.should == obj_2
|
171
|
+
example_inst.should_not == obj_3
|
172
|
+
end
|
173
|
+
it 'and the same attributes' do
|
174
|
+
example_inst.attributes.should == obj_2.attributes
|
175
|
+
example_inst.should == obj_2
|
176
|
+
obj_2.my_field = 100
|
177
|
+
example_inst.should_not == obj_2
|
178
|
+
end
|
179
|
+
end
|
180
|
+
|
181
|
+
context ".fields" do
|
182
|
+
it 'is a hash of Gorillib::Model::Field objects' do
|
183
|
+
subject.fields.keys.should == [:my_field, :str_field, :sym_field]
|
184
|
+
subject.fields.values.each{|f| f.should be_a(Gorillib::Model::Field) }
|
185
|
+
subject.fields.values.map(&:name).should == [:my_field, :str_field, :sym_field]
|
186
|
+
end
|
187
|
+
end
|
188
|
+
|
189
|
+
context '.has_field?' do
|
190
|
+
it 'is true if the field exists' do
|
191
|
+
complex_class.has_field?( :my_field).should be_true
|
192
|
+
complex_subclass.has_field?(:my_field).should be_true
|
193
|
+
complex_subclass.has_field?(:zyzzyva ).should be_true
|
194
|
+
end
|
195
|
+
it 'is false if it does not exist' do
|
196
|
+
complex_class.has_field?( :zyzzyva).should be_false
|
197
|
+
complex_class.has_field?( :fnord ).should be_false
|
198
|
+
complex_subclass.has_field?(:fnord ).should be_false
|
199
|
+
end
|
200
|
+
end
|
201
|
+
|
202
|
+
context '.field_names' do
|
203
|
+
it 'lists fields in order by class, then in order added' do
|
204
|
+
subject.field_names.should == [:my_field, :str_field, :sym_field]
|
205
|
+
complex_subclass.field_names.should == [:my_field, :str_field, :sym_field, :zyzzyva, :acme]
|
206
|
+
subject.field :banksy, String
|
207
|
+
subject.field_names.should == [:my_field, :str_field, :sym_field, :banksy ]
|
208
|
+
complex_subclass.field_names.should == [:my_field, :str_field, :sym_field, :banksy, :zyzzyva, :acme]
|
209
|
+
end
|
210
|
+
end
|
211
|
+
|
212
|
+
context '.typename' do
|
213
|
+
it 'has a typename that matches its underscored class name' do
|
214
|
+
subject.typename.should == 'gorillib.test.complex_model'
|
215
|
+
end
|
216
|
+
end
|
217
|
+
|
218
|
+
context '.receive' do
|
219
|
+
it 'creates a new instance' do
|
220
|
+
obj = example_inst
|
221
|
+
subject.should_receive(:new).with().and_return(obj)
|
222
|
+
result = subject.receive(:my_field => 12)
|
223
|
+
result.should equal(obj)
|
224
|
+
result.my_field.should == 12
|
225
|
+
end
|
226
|
+
it 'calls receive! to set the attributes, and returns the object' do
|
227
|
+
obj = example_inst
|
228
|
+
subject.should_receive(:new).with().and_return(obj)
|
229
|
+
obj.should_receive(:receive!).with(:my_field => 12)
|
230
|
+
subject.receive(:my_field => 12).should equal(obj)
|
231
|
+
end
|
232
|
+
|
233
|
+
it 'uses the given type if the _type attribute is a factory' do
|
234
|
+
obj = complex_class.receive(:my_field => 12, :acme => 3, :_type => complex_subclass)
|
235
|
+
obj.should be_a(complex_subclass)
|
236
|
+
end
|
237
|
+
|
238
|
+
it 'complains if the given type is not right' do
|
239
|
+
mock_factory = mock ; mock_factory.stub(:receive! => {}, :receive => mock, :new => mock_factory)
|
240
|
+
mock_factory.should_receive(:<=).and_return(false)
|
241
|
+
complex_class.should_receive(:warn).with(/doesn't match type/)
|
242
|
+
complex_class.receive(:my_field => 12, :acme => 3, :_type => mock_factory)
|
243
|
+
end
|
244
|
+
|
245
|
+
it 'uses the given type if the _type attribute is a typename' do
|
246
|
+
complex_subclass.typename.should == 'gorillib.test.test_subclass'
|
247
|
+
obj = complex_class.receive(:my_field => 12, :acme => 3, :_type => 'gorillib.test.test_subclass')
|
248
|
+
obj.should be_a(complex_subclass)
|
249
|
+
end
|
250
|
+
end
|
251
|
+
|
252
|
+
describe Gorillib::Model::NamedSchema do
|
253
|
+
subject{ simple_model }
|
254
|
+
context ".meta_module" do
|
255
|
+
it "is named for the class (if the class is named)" do
|
256
|
+
subject.send(:meta_module).should == Meta::Gorillib::Test::TestClassType
|
257
|
+
end
|
258
|
+
it "is anonymous if the class is anonymous" do
|
259
|
+
anon_class.name.should be_nil
|
260
|
+
anon_class.send(:meta_module).should be_a(Module)
|
261
|
+
anon_class.send(:meta_module).name.should be_nil
|
262
|
+
end
|
263
|
+
it "carries the field-specfic accessor and receive methods" do
|
264
|
+
subject.send(:meta_module).public_instance_methods.sort.should == [:my_field, :my_field=, :receive_my_field]
|
265
|
+
anon_class.send(:meta_module).public_instance_methods.sort.should == [:my_field, :my_field=, :receive_my_field]
|
266
|
+
end
|
267
|
+
it "is injected right after the Gorillib::Model module" do
|
268
|
+
subject.ancestors.first(4).should == [subject, Meta::Gorillib::Test::TestClassType, Gorillib::Model, Object]
|
269
|
+
subject.should < Meta::Gorillib::Test::TestClassType
|
270
|
+
end
|
271
|
+
it "retrieves an existing named module if one exists" do
|
272
|
+
Gorillib::Test.should_not be_const_defined(:TestClass)
|
273
|
+
module Meta::Gorillib::Test::TestClassType ; def kilroy_was_here() '23 skidoo' ; end ; end
|
274
|
+
subject.send(:meta_module).public_instance_methods.sort.should == [:kilroy_was_here, :my_field, :my_field=, :receive_my_field]
|
275
|
+
Gorillib::Test.should be_const_defined(:TestClass)
|
276
|
+
subject.send(:meta_module).should == Meta::Gorillib::Test::TestClassType
|
277
|
+
end
|
278
|
+
end
|
279
|
+
end
|
280
|
+
|
281
|
+
end
|
@@ -1,7 +1,7 @@
|
|
1
|
-
require
|
1
|
+
require 'spec_helper'
|
2
2
|
require 'gorillib/numeric/clamp'
|
3
3
|
|
4
|
-
describe Numeric do
|
4
|
+
describe Numeric, :simple_spec => true do
|
5
5
|
describe '#clamp' do
|
6
6
|
it 'should return self if neither min nor max are given' do
|
7
7
|
5.clamp().should == 5
|
@@ -1,7 +1,7 @@
|
|
1
|
-
require
|
1
|
+
require 'spec_helper'
|
2
2
|
require 'gorillib/object/blank'
|
3
3
|
|
4
|
-
describe 'object/blank' do
|
4
|
+
describe 'object/blank', :simple_spec => true do
|
5
5
|
describe Object do
|
6
6
|
it 'should provide blank?' do
|
7
7
|
Object.new.should respond_to(:blank?)
|
@@ -1,7 +1,7 @@
|
|
1
|
-
require
|
1
|
+
require 'spec_helper'
|
2
2
|
require 'gorillib/object/try_dup'
|
3
3
|
|
4
|
-
describe
|
4
|
+
describe 'try_dup', :simple_spec => true do
|
5
5
|
it "returns a duplicate version on regular objects" do
|
6
6
|
obj = Object.new
|
7
7
|
oth = obj.try_dup
|
@@ -1,4 +1,4 @@
|
|
1
|
-
require
|
1
|
+
require 'spec_helper'
|
2
2
|
require 'gorillib/object/try'
|
3
3
|
|
4
4
|
class Foo
|
@@ -7,10 +7,11 @@ class Foo
|
|
7
7
|
end
|
8
8
|
end
|
9
9
|
|
10
|
-
describe Object do
|
10
|
+
describe Object, :simple_spec => true do
|
11
11
|
describe '#try' do
|
12
12
|
it 'returns nil if item does not #respond_to? method' do
|
13
13
|
Foo.new.try(:i_am_not_a_method).should be_nil
|
14
|
+
Foo.new.respond_to?(:i_am_not_a_method).should be_false
|
14
15
|
end
|
15
16
|
it 'calls the method (with args) if the item does #respond_to? it' do
|
16
17
|
Foo.new.try(:i_am_a_method_hooray).should == "i was called! hooray!"
|
@@ -0,0 +1,114 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'gorillib/pathname'
|
3
|
+
|
4
|
+
describe Pathname do
|
5
|
+
let(:mock_path){ mock(:path) } # "We mock what we don't understand"
|
6
|
+
|
7
|
+
context '.path_to' do
|
8
|
+
subject{ described_class }
|
9
|
+
before do
|
10
|
+
subject.register_path(:doctor, 'doctor/doctor')
|
11
|
+
subject.register_path(:code, 'twenty-square-digit', 'boustrophedonic')
|
12
|
+
subject.register_path(:hello, :doctor, :doctor)
|
13
|
+
subject.register_path(:oh_crap, '~/ninjas')
|
14
|
+
subject.register_path(:access, '/would/you/like/to')
|
15
|
+
end
|
16
|
+
|
17
|
+
context 'examples' do
|
18
|
+
{ ['/tmp', :code] => '/tmp/twenty-square-digit/boustrophedonic',
|
19
|
+
[:oh_crap] => ENV['HOME']+'/ninjas',
|
20
|
+
[:hello, 'doctor', :doctor, :doctor] => File.expand_path('doctor/doctor/doctor/doctor/doctor/doctor/doctor/doctor/doctor'),
|
21
|
+
[:oh_crap, :doctor] => File.join(ENV['HOME'], 'ninjas', 'doctor', 'doctor'),
|
22
|
+
[".."] => File.expand_path('..'),
|
23
|
+
["..", 'bob'] => File.expand_path(File.join('..', 'bob')),
|
24
|
+
}.each do |input, expected|
|
25
|
+
it 'expands symbols' do
|
26
|
+
subject.path_to(*input).should == Pathname.new(expected)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
it 'delays evaluation of path segments' do
|
32
|
+
subject.register_path(:russia, '/ussr/russia')
|
33
|
+
subject.register_path(:city, 'leningrad')
|
34
|
+
subject.register_path(:ermitage, :russia, :city)
|
35
|
+
subject.path_to(:ermitage).should == Pathname.new('/ussr/russia/leningrad')
|
36
|
+
subject.register_path(:city, 'st_petersburg')
|
37
|
+
subject.path_to(:ermitage).should == Pathname.new('/ussr/russia/st_petersburg')
|
38
|
+
end
|
39
|
+
|
40
|
+
it 'expands all paths into a pathname' do
|
41
|
+
subject.should_receive(:expand_pathseg).with(:a).and_return('/a')
|
42
|
+
subject.should_receive(:expand_pathseg).with('b').and_return('b')
|
43
|
+
subject.path_to(:a, 'b').should == Pathname.new('/a/b')
|
44
|
+
end
|
45
|
+
|
46
|
+
it 'expands relative paths' do
|
47
|
+
FileUtils.cd '/' do
|
48
|
+
subject.path_to(:hello).should == Pathname.new('/doctor/doctor/doctor/doctor')
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
it 'collapses "//" double slashes' do
|
53
|
+
subject.path_to('/', :access, '//have', 'a//pepsi').should == Pathname.new('/would/you/like/to/have/a/pepsi')
|
54
|
+
end
|
55
|
+
|
56
|
+
it 'must have at least one segment' do
|
57
|
+
lambda{ subject.new() }.should raise_error(ArgumentError, /wrong number of arguments/)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
context '.relative_path_to' do
|
62
|
+
subject{ described_class }
|
63
|
+
|
64
|
+
it 'collapses "//" double slashes and useless ".." dots, but does not use the filesystem' do
|
65
|
+
subject.relative_path_to('/', '../..', :access, '//have', 'a//pepsi').should == Pathname.new('/would/you/like/to/have/a/pepsi')
|
66
|
+
end
|
67
|
+
|
68
|
+
it 'does not expand relative paths' do
|
69
|
+
FileUtils.cd '/' do
|
70
|
+
subject.register_path(:hello, 'doctor')
|
71
|
+
subject.relative_path_to(:hello, :hello, :hello).should == Pathname.new('doctor/doctor/doctor')
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
context 'registering paths' do
|
77
|
+
subject { described_class }
|
78
|
+
def expand_pathseg(*args) ; subject.send(:expand_pathseg, *args) ; end
|
79
|
+
|
80
|
+
context '.register_path' do
|
81
|
+
it 'stores a path so expand_pathseg can get it later' do
|
82
|
+
subject.register_path(:probe, ['skeletal', 'girth'])
|
83
|
+
expand_pathseg(:probe).should == ['skeletal', 'girth']
|
84
|
+
end
|
85
|
+
it 'stores a list of path segments to re-expand' do
|
86
|
+
subject.register_path(:ace, 'tomato', 'corporation')
|
87
|
+
expand_pathseg(:ace).should == ['tomato', 'corporation']
|
88
|
+
end
|
89
|
+
it 'replaces the stored path if called again' do
|
90
|
+
subject.register_path(:glg_20, 'boyer')
|
91
|
+
subject.register_path(:glg_20, ['milbarge', 'fitz-hume'])
|
92
|
+
expand_pathseg(:glg_20).should == ['milbarge', 'fitz-hume']
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
context '.register_paths' do
|
97
|
+
let(:paths) { { :foo => ['foo'], :bar => [:foo, 'bar'] } }
|
98
|
+
|
99
|
+
it 'registers multiple paths' do
|
100
|
+
subject.should_receive(:register_path).exactly(paths.size).times
|
101
|
+
subject.register_paths(paths)
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
context '.unregister_path' do
|
106
|
+
it 'unregisters a path' do
|
107
|
+
subject.register_path(:foo, 'foo')
|
108
|
+
expand_pathseg(:foo).should == ['foo']
|
109
|
+
subject.unregister_path(:foo)
|
110
|
+
expect{ expand_pathseg(:foo)}.to raise_error(ArgumentError, /expand path reference.*foo/)
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
require
|
1
|
+
require 'spec_helper'
|
2
2
|
require 'gorillib/string/constantize'
|
3
3
|
|
4
4
|
module Ace
|
@@ -17,7 +17,7 @@ end
|
|
17
17
|
|
18
18
|
module InflectorTest
|
19
19
|
|
20
|
-
describe 'String' do
|
20
|
+
describe 'String', :string_spec => true do
|
21
21
|
describe '#constantize' do
|
22
22
|
it "works from within instance" do
|
23
23
|
@obj = Ace::Base::Case.new
|
@@ -1,10 +1,10 @@
|
|
1
|
-
require
|
1
|
+
require 'spec_helper'
|
2
2
|
require File.expand_path('inflector_test_cases', File.dirname(__FILE__))
|
3
3
|
require 'gorillib/string/human'
|
4
4
|
|
5
5
|
include InflectorTestCases
|
6
6
|
|
7
|
-
describe String do
|
7
|
+
describe String, :string_spec => true do
|
8
8
|
|
9
9
|
describe '#titleize' do
|
10
10
|
MixtureToTitleCase.each do |raw, titleized|
|
@@ -1,11 +1,12 @@
|
|
1
|
-
require
|
1
|
+
require 'spec_helper'
|
2
2
|
require File.expand_path('inflector_test_cases', File.dirname(__FILE__))
|
3
3
|
require 'gorillib/string/inflections'
|
4
4
|
|
5
5
|
include InflectorTestCases
|
6
6
|
|
7
|
-
describe String do
|
8
|
-
|
7
|
+
describe String, :string_spec => true do
|
8
|
+
|
9
|
+
describe '#camelize' do
|
9
10
|
CamelToUnderscore.each do |cameled, underscored|
|
10
11
|
it underscored do
|
11
12
|
underscored.camelize.should == cameled
|
File without changes
|
@@ -1,8 +1,9 @@
|
|
1
|
-
require
|
1
|
+
require 'spec_helper'
|
2
2
|
require GORILLIB_ROOT_DIR('spec/support/kcode_test_helper')
|
3
3
|
require 'gorillib/string/truncate'
|
4
4
|
|
5
|
-
describe String do
|
5
|
+
describe String, :string_spec => true do
|
6
|
+
|
6
7
|
describe '#truncate' do
|
7
8
|
it 'leaves a short string alone' do
|
8
9
|
"Hello World!".truncate(12).should == "Hello World!"
|
@@ -25,14 +26,6 @@ describe String do
|
|
25
26
|
should == "\354\225\210\353\205\225\355..."
|
26
27
|
end
|
27
28
|
end
|
28
|
-
|
29
|
-
# # FIXME: breaks on ruby 1.8
|
30
|
-
# it 'works with unicode when kcode=u' do
|
31
|
-
# Gorillib::KcodeTestHelper.with_kcode('u') do
|
32
|
-
# "\354\225\204\353\246\254\353\236\221 \354\225\204\353\246\254 \354\225\204\353\235\274\353\246\254\354\230\244".truncate(10).
|
33
|
-
# should == "\354\225\204\353\246\254\353\236\221 \354\225\204\353\246\254 ..."
|
34
|
-
# end
|
35
|
-
# end
|
36
29
|
else # ruby 1.9
|
37
30
|
it 'works with unicode' do
|
38
31
|
"\354\225\204\353\246\254\353\236\221 \354\225\204\353\246\254 \354\225\204\353\235\274\353\246\254\354\230\244".force_encoding('UTF-8').truncate(10).
|
@@ -40,4 +33,5 @@ describe String do
|
|
40
33
|
end
|
41
34
|
end
|
42
35
|
end
|
36
|
+
|
43
37
|
end
|
@@ -0,0 +1,120 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
require 'gorillib/type/extended'
|
4
|
+
require 'gorillib/object/blank'
|
5
|
+
|
6
|
+
describe ::Long do
|
7
|
+
it "is_a?(Integer)" do ::Long.should < ::Integer ; end
|
8
|
+
end
|
9
|
+
|
10
|
+
describe ::Double do
|
11
|
+
it "is_a?(Float)" do ::Double.should < ::Float ; end
|
12
|
+
end
|
13
|
+
|
14
|
+
describe ::Binary do
|
15
|
+
it "is_a?(String)" do ::Binary.should < ::String ; end
|
16
|
+
end
|
17
|
+
|
18
|
+
# describe ::Boolean, :model_spec => true do
|
19
|
+
# let(:true_bool ){ ::Boolean.new(true) }
|
20
|
+
# let(:false_bool){ ::Boolean.new(false) }
|
21
|
+
#
|
22
|
+
# def it_responds_same_as(test_obj, comparable, meth, *meth_args, &block)
|
23
|
+
# test_obj.send(meth, *meth_args, &block).should == comparable.send(meth, *meth_args, &block)
|
24
|
+
# end
|
25
|
+
#
|
26
|
+
# def it_responds_with_same_contents(test_obj, comparable, meth, *meth_args, &block)
|
27
|
+
# test_obj.send(meth, *meth_args, &block).sort.should == comparable.send(meth, *meth_args, &block).sort
|
28
|
+
# end
|
29
|
+
#
|
30
|
+
# it("has #class ::Boolean" ){ (true_bool.class).should == ::Boolean ; (false_bool.class).should == ::Boolean }
|
31
|
+
#
|
32
|
+
# it "#is_a?(Boolean)" do true_bool.should be_a(::Boolean) ; false_bool.should be_a(::Boolean) ; end
|
33
|
+
# it "#is_a?(True/False)" do true_bool.should be_a(::TrueClass) ; false_bool.should be_a(::FalseClass) ; end
|
34
|
+
# it "#kind_of?(Boolean)" do true_bool.should be_a_kind_of(::Boolean) ; false_bool.should be_a_kind_of(::Boolean) ; end
|
35
|
+
# it "#instance_of?(True/False)" do true_bool.should be_instance_of(::TrueClass) ; false_bool.should be_instance_of(::FalseClass) ; end
|
36
|
+
#
|
37
|
+
# describe 'mimics true/false' do
|
38
|
+
# [ :!, :to_s, :blank?, :frozen?, :nil?, :present?,
|
39
|
+
# ].each do |meth|
|
40
|
+
# it "##{meth}" do
|
41
|
+
# it_responds_same_as(true_bool, true, meth)
|
42
|
+
# it_responds_same_as(false_bool, false, meth)
|
43
|
+
# end
|
44
|
+
# end
|
45
|
+
#
|
46
|
+
# [ :private_methods, :protected_methods, :singleton_methods,
|
47
|
+
# ].each do |meth|
|
48
|
+
# it "##{meth}" do
|
49
|
+
# it_responds_with_same_contents(true_bool, true, meth)
|
50
|
+
# it_responds_with_same_contents(false_bool, false, meth)
|
51
|
+
# end
|
52
|
+
# end
|
53
|
+
# it "#methods" do ( true.methods - true_bool.methods ).should be_empty ; end
|
54
|
+
# it "#methods" do ( false.methods - false_bool.methods ).should be_empty ; end
|
55
|
+
# it "#public_methods" do ( true.public_methods - true_bool.public_methods ).should be_empty ; end
|
56
|
+
# it "#public_methods" do ( false.public_methods - false_bool.public_methods ).should be_empty ; end
|
57
|
+
#
|
58
|
+
# it ".methods" do (TrueClass.methods | [:true, :false, :new]).sort.should == Boolean.methods.sort ; end
|
59
|
+
#
|
60
|
+
# { :!= => [true, false, nil],
|
61
|
+
# :!~ => [true, false, nil],
|
62
|
+
# :& => [true, false, nil],
|
63
|
+
# :<=> => [true, false, nil],
|
64
|
+
# :== => [true, false, nil],
|
65
|
+
# :=== => [true, false, nil],
|
66
|
+
# :=~ => [true, false, nil],
|
67
|
+
# :^ => [true, false, nil],
|
68
|
+
# :| => [true, false, nil],
|
69
|
+
# :eql? => [true, false, nil],
|
70
|
+
# :equal? => [true, false, nil],
|
71
|
+
# :instance_of? => [::TrueClass, ::FalseClass, ::Object],
|
72
|
+
# :is_a? => [::TrueClass, ::FalseClass, ::Object],
|
73
|
+
# :kind_of? => [::TrueClass, ::FalseClass, ::Object],
|
74
|
+
# }.each do |meth, meth_args|
|
75
|
+
# meth_args.each do |meth_arg|
|
76
|
+
# it "##{meth}(#{meth_arg})" do
|
77
|
+
# it_responds_same_as(true_bool, true, meth, meth_arg)
|
78
|
+
# it_responds_same_as(false_bool, false, meth, meth_arg)
|
79
|
+
# end
|
80
|
+
# end
|
81
|
+
# end
|
82
|
+
#
|
83
|
+
# end
|
84
|
+
#
|
85
|
+
# [ :==, :===, :eql?, :equal?, :<=> ].each do |meth|
|
86
|
+
# it "Boolean.true #{meth} itself and true" do
|
87
|
+
# true_bool.send(meth, true_bool ).should be_true
|
88
|
+
# true_bool.send(meth, Boolean.true ).should be_true
|
89
|
+
# true_bool.send(meth, true ).should be_true
|
90
|
+
# true_bool.send(meth, false_bool ).should be_false
|
91
|
+
# true_bool.send(meth, Boolean.false ).should be_false
|
92
|
+
# true_bool.send(meth, false ).should be_false
|
93
|
+
# true_bool.send(meth, 0 ).should be_false
|
94
|
+
# end
|
95
|
+
# it "Boolean.false #{meth} itself and false" do
|
96
|
+
# false_bool.send(meth, false_bool ).should be_true
|
97
|
+
# false_bool.send(meth, Boolean.false ).should be_true
|
98
|
+
# false_bool.send(meth, false ).should be_true
|
99
|
+
# false_bool.send(meth, true_bool ).should be_false
|
100
|
+
# false_bool.send(meth, Boolean.true ).should be_false
|
101
|
+
# false_bool.send(meth, true ).should be_false
|
102
|
+
# false_bool.send(meth, 0 ).should be_false
|
103
|
+
# end
|
104
|
+
# it "!=" do
|
105
|
+
# (true_bool != true ).should be_false ; (true_bool != false ).should be_true
|
106
|
+
# (true_bool != true_bool ).should be_false ; (true_bool != false_bool ).should be_true
|
107
|
+
# (true_bool != Boolean.true ).should be_false ; (true_bool != Boolean.false).should be_true
|
108
|
+
# (true_bool != 0 ).should be_true ; (true_bool != "true" ).should be_true
|
109
|
+
# (false_bool != false ).should be_false ; (false_bool != true ).should be_true
|
110
|
+
# (false_bool != false_bool ).should be_false ; (false_bool != true_bool ).should be_true
|
111
|
+
# (false_bool != Boolean.false).should be_false ; (false_bool != Boolean.true ).should be_true
|
112
|
+
# (false_bool != 0 ).should be_true ; (false_bool != "true" ).should be_true
|
113
|
+
# end
|
114
|
+
# it "!~" do
|
115
|
+
# (true_bool !~ true ).should be_true
|
116
|
+
# (true_bool !~ true_bool ).should be_true
|
117
|
+
# (true_bool !~ Boolean.true).should be_true
|
118
|
+
# end
|
119
|
+
# end
|
120
|
+
# end
|