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.
Files changed (56) hide show
  1. data/.gitignore +4 -0
  2. data/Gemfile +12 -0
  3. data/README.md +21 -0
  4. data/Rakefile +15 -0
  5. data/gorillib-model.gemspec +27 -0
  6. data/lib/gorillib/builder.rb +239 -0
  7. data/lib/gorillib/core_ext/datetime.rb +23 -0
  8. data/lib/gorillib/core_ext/exception.rb +153 -0
  9. data/lib/gorillib/core_ext/module.rb +10 -0
  10. data/lib/gorillib/core_ext/object.rb +14 -0
  11. data/lib/gorillib/model/base.rb +273 -0
  12. data/lib/gorillib/model/collection/model_collection.rb +157 -0
  13. data/lib/gorillib/model/collection.rb +200 -0
  14. data/lib/gorillib/model/defaults.rb +115 -0
  15. data/lib/gorillib/model/errors.rb +24 -0
  16. data/lib/gorillib/model/factories.rb +555 -0
  17. data/lib/gorillib/model/field.rb +168 -0
  18. data/lib/gorillib/model/lint.rb +24 -0
  19. data/lib/gorillib/model/named_schema.rb +53 -0
  20. data/lib/gorillib/model/positional_fields.rb +35 -0
  21. data/lib/gorillib/model/schema_magic.rb +163 -0
  22. data/lib/gorillib/model/serialization/csv.rb +60 -0
  23. data/lib/gorillib/model/serialization/json.rb +44 -0
  24. data/lib/gorillib/model/serialization/lines.rb +30 -0
  25. data/lib/gorillib/model/serialization/to_wire.rb +54 -0
  26. data/lib/gorillib/model/serialization/tsv.rb +53 -0
  27. data/lib/gorillib/model/serialization.rb +41 -0
  28. data/lib/gorillib/model/type/extended.rb +83 -0
  29. data/lib/gorillib/model/type/ip_address.rb +153 -0
  30. data/lib/gorillib/model/type/url.rb +11 -0
  31. data/lib/gorillib/model/validate.rb +22 -0
  32. data/lib/gorillib/model/version.rb +5 -0
  33. data/lib/gorillib/model.rb +34 -0
  34. data/spec/builder_spec.rb +193 -0
  35. data/spec/core_ext/datetime_spec.rb +41 -0
  36. data/spec/core_ext/exception.rb +98 -0
  37. data/spec/core_ext/object.rb +45 -0
  38. data/spec/model/collection_spec.rb +290 -0
  39. data/spec/model/defaults_spec.rb +104 -0
  40. data/spec/model/factories_spec.rb +323 -0
  41. data/spec/model/lint_spec.rb +28 -0
  42. data/spec/model/serialization/csv_spec.rb +30 -0
  43. data/spec/model/serialization/tsv_spec.rb +28 -0
  44. data/spec/model/serialization_spec.rb +41 -0
  45. data/spec/model/type/extended_spec.rb +166 -0
  46. data/spec/model/type/ip_address_spec.rb +141 -0
  47. data/spec/model_spec.rb +261 -0
  48. data/spec/spec_helper.rb +15 -0
  49. data/spec/support/capture_output.rb +28 -0
  50. data/spec/support/nuke_constants.rb +9 -0
  51. data/spec/support/shared_context_for_builders.rb +59 -0
  52. data/spec/support/shared_context_for_models.rb +55 -0
  53. data/spec/support/shared_examples_for_factories.rb +71 -0
  54. data/spec/support/shared_examples_for_model_fields.rb +62 -0
  55. data/spec/support/shared_examples_for_models.rb +87 -0
  56. metadata +193 -0
@@ -0,0 +1,62 @@
1
+ shared_examples_for "a model field" do |field_name|
2
+ it('gives the model a field'){ subject.class.should have_field(field_name) }
3
+
4
+ context '#read_attribute' do
5
+ it "if set, returns the value" do
6
+ subject.write_attribute(field_name, sample_val)
7
+ subject.read_attribute(field_name).should == sample_val
8
+ end
9
+ it "if unset, calls #read_unset_attribute" do
10
+ subject.should_receive(:read_unset_attribute).with(field_name).and_return(mock_val)
11
+ subject.read_attribute(field_name).should == mock_val
12
+ end
13
+ it "does **not** raise an error if the field does not exist (require 'model/lint' if you want it to)" do
14
+ expect { subject.read_attribute(:fnord) }.not_to raise_error
15
+ end
16
+ end
17
+
18
+ context '#write_attribute' do
19
+ it('sets the value') do
20
+ subject.write_attribute(field_name, sample_val)
21
+ subject.read_attribute(field_name).should == sample_val
22
+ end
23
+ it('returns the new value') do
24
+ subject.write_attribute(field_name, sample_val).should == sample_val
25
+ end
26
+ it "does **not** raise an error if the field does not exist (require 'model/lint' if you want it to)" do
27
+ expect { subject.write_attribute(:fnord, 8) }.not_to raise_error
28
+ end
29
+ end
30
+
31
+ context '#attribute_set?' do
32
+ it('is true if the attribute has been set') do
33
+ subject.write_attribute(field_name, sample_val)
34
+ subject.attribute_set?(field_name).should be_true
35
+ end
36
+ it('is true if the attribute has been set, even to nil or false') do
37
+ subject.write_attribute(field_name, nil)
38
+ subject.attribute_set?(field_name).should be_true
39
+ end
40
+ it('is false if never written') do
41
+ subject.attribute_set?(field_name).should be_false
42
+ end
43
+ it "does **not** raise an error if the field does not exist (require 'model/lint' if you want it to)" do
44
+ expect { subject.attribute_set?(:fnord) }.not_to raise_error
45
+ end
46
+ end
47
+
48
+ context "#receive_XX" do
49
+ it('returns the new attribute') do
50
+ subject.send("receive_#{field_name}", raw_val).should == sample_val
51
+ end
52
+ it('type-converts the object') do
53
+ subject.send("receive_#{field_name}", raw_val)
54
+ subject.read_attribute(field_name).should == sample_val
55
+ subject.read_attribute(field_name).should_not equal(sample_val)
56
+ end
57
+ it('uses a compatible object directly') do
58
+ subject.send("receive_#{field_name}", sample_val)
59
+ subject.read_attribute(field_name).should equal(sample_val)
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,87 @@
1
+ shared_examples_for 'a model' do
2
+
3
+ context 'initialize' do
4
+ it "has no required args" do
5
+ obj = smurf_class.new
6
+ obj.compact_attributes.should == {}
7
+ end
8
+ it "takes the last hashlike arg as the attributes" do
9
+ obj = smurf_class.new :smurfiness => 3, :weapon => :smurfchucks
10
+ obj.compact_attributes.should == { :smurfiness => 3, :weapon => :smurfchucks }
11
+ end
12
+
13
+ context 'positional args' do
14
+ before do
15
+ smurf_class.fields[:smurfiness].position = 0
16
+ smurf_class.fields[:weapon ].position = 1
17
+ end
18
+ it "takes all preceding args as positional, clobbering values set in attrs" do
19
+ obj = smurf_class.new 7, :smurfing_stars
20
+ obj.compact_attributes.should == { :smurfiness => 7, :weapon => :smurfing_stars }
21
+ obj = smurf_class.new 7, :smurfing_stars, :smurfiness => 3, :weapon => :smurfchucks
22
+ obj.compact_attributes.should == { :smurfiness => 7, :weapon => :smurfing_stars }
23
+ end
24
+ it "does nothing special with a nil positional arg -- it clobbers anything there setting the attribute to nil" do
25
+ obj = smurf_class.new nil, :smurfiness => 3
26
+ obj.compact_attributes.should == { :smurfiness => nil }
27
+ end
28
+ it "raises an error if too many positional args are given" do
29
+ ->{ smurf_class.new 7, :smurfing_stars, :azrael }.should raise_error(ArgumentError, /wrong number of arguments.*3.*0\.\.2/)
30
+ end
31
+ it "always takes the last hash arg as the attrs -- even if it is in the positional slot of a hash field" do
32
+ smurf_class.field :hashie, Hash, :position => 2
33
+ obj = smurf_class.new({:smurfiness => 3, :weapon => :smurfiken})
34
+ obj.compact_attributes.should == { :smurfiness => 3, :weapon => :smurfiken }
35
+ obj = smurf_class.new(3, :smurfiken, { :weapon => :bastard_smurf })
36
+ obj.compact_attributes.should == { :smurfiness => 3, :weapon => :smurfiken }
37
+ obj = smurf_class.new(3, :smurfiken, {:this => :that}, { :weapon => :bastard_smurf })
38
+ obj.compact_attributes.should == { :smurfiness => 3, :weapon => :smurfiken, :hashie => {:this => :that} }
39
+ end
40
+ it "skips fields that are not positional args" do
41
+ smurf_class.fields[:weapon].unset_attribute(:position)
42
+ smurf_class.field :color, String, :position => 1
43
+ smurf_class.new(99, 'cerulean').compact_attributes.should == { :smurfiness => 99, :color => 'cerulean' }
44
+ end
45
+ end
46
+ end
47
+
48
+ context 'receive' do
49
+ let(:my_attrs){ { :smurfiness => 900, :weapon => :wood_smurfer } }
50
+ let(:subklass){ class ::Gorillib::Test::SubSmurf < smurf_class ; end ; ::Gorillib::Test::SubSmurf }
51
+
52
+ it "returns nil if given a single nil arg" do
53
+ smurf_class.receive(nil).should == nil
54
+ end
55
+ it "returns the object if given a single object of the model class" do
56
+ smurf_class.receive(papa_smurf).should equal(papa_smurf)
57
+ end
58
+ it "raises an error if the attributes are not hashlike" do
59
+ ->{ smurf_class.receive('DURRRR') }.should raise_error(ArgumentError, /attributes .* like a hash: "DURRRR"/)
60
+ end
61
+ context "with hashlike args," do
62
+ before{ Gorillib::Factory.send(:factories).reject!{|th, type| th.to_s =~ /gorillib\.test/ }}
63
+
64
+ it "instantiates the object, passing it the attrs and block" do
65
+ my_attrs = { :smurfiness => 900, :weapon => :wood_smurfer }
66
+ smurf_class.should_receive(:new).with(my_attrs)
67
+ smurf_class.receive(my_attrs)
68
+ end
69
+ it "retrieves the right factory if :_type is present" do
70
+ my_attrs = self.my_attrs.merge(:_type => 'gorillib.test.smurf')
71
+ smurf_class.should_receive(:new).with(my_attrs)
72
+ smurf_class.receive(my_attrs)
73
+ end
74
+ it "retrieves the right factory if :_type is present" do
75
+ my_attrs = self.my_attrs.merge(:_type => 'gorillib.test.sub_smurf')
76
+ subklass.should_receive(:new).with(my_attrs)
77
+ smurf_class.receive(my_attrs)
78
+ end
79
+ it 'complains if the given type is not right' do
80
+ mock_factory = double('factory') ; mock_factory.stub(:receive! => {}, :receive => double, :new => mock_factory)
81
+ mock_factory.should_receive(:<=).and_return(false)
82
+ smurf_class.should_receive(:warn).with(/factory .* is not a type of Gorillib::Test::Smurf/)
83
+ smurf_class.receive(:my_field => 12, :acme => 3, :_type => mock_factory)
84
+ end
85
+ end
86
+ end
87
+ end
metadata ADDED
@@ -0,0 +1,193 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: gorillib-model
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Infochimps
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2014-08-11 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: bundler
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: 1.6.3
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ version: 1.6.3
30
+ - !ruby/object:Gem::Dependency
31
+ name: multi_json
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ~>
36
+ - !ruby/object:Gem::Version
37
+ version: 1.10.1
38
+ type: :runtime
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ~>
44
+ - !ruby/object:Gem::Version
45
+ version: 1.10.1
46
+ - !ruby/object:Gem::Dependency
47
+ name: activesupport
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ~>
52
+ - !ruby/object:Gem::Version
53
+ version: 4.1.4
54
+ type: :runtime
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ~>
60
+ - !ruby/object:Gem::Version
61
+ version: 4.1.4
62
+ - !ruby/object:Gem::Dependency
63
+ name: addressable
64
+ requirement: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ~>
68
+ - !ruby/object:Gem::Version
69
+ version: 2.3.6
70
+ type: :runtime
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ~>
76
+ - !ruby/object:Gem::Version
77
+ version: 2.3.6
78
+ description: ! 'Gorillib::Model '
79
+ email: coders@infochimps.com
80
+ executables: []
81
+ extensions: []
82
+ extra_rdoc_files: []
83
+ files:
84
+ - .gitignore
85
+ - Gemfile
86
+ - README.md
87
+ - Rakefile
88
+ - gorillib-model.gemspec
89
+ - lib/gorillib/builder.rb
90
+ - lib/gorillib/core_ext/datetime.rb
91
+ - lib/gorillib/core_ext/exception.rb
92
+ - lib/gorillib/core_ext/module.rb
93
+ - lib/gorillib/core_ext/object.rb
94
+ - lib/gorillib/model.rb
95
+ - lib/gorillib/model/base.rb
96
+ - lib/gorillib/model/collection.rb
97
+ - lib/gorillib/model/collection/model_collection.rb
98
+ - lib/gorillib/model/defaults.rb
99
+ - lib/gorillib/model/errors.rb
100
+ - lib/gorillib/model/factories.rb
101
+ - lib/gorillib/model/field.rb
102
+ - lib/gorillib/model/lint.rb
103
+ - lib/gorillib/model/named_schema.rb
104
+ - lib/gorillib/model/positional_fields.rb
105
+ - lib/gorillib/model/schema_magic.rb
106
+ - lib/gorillib/model/serialization.rb
107
+ - lib/gorillib/model/serialization/csv.rb
108
+ - lib/gorillib/model/serialization/json.rb
109
+ - lib/gorillib/model/serialization/lines.rb
110
+ - lib/gorillib/model/serialization/to_wire.rb
111
+ - lib/gorillib/model/serialization/tsv.rb
112
+ - lib/gorillib/model/type/extended.rb
113
+ - lib/gorillib/model/type/ip_address.rb
114
+ - lib/gorillib/model/type/url.rb
115
+ - lib/gorillib/model/validate.rb
116
+ - lib/gorillib/model/version.rb
117
+ - spec/builder_spec.rb
118
+ - spec/core_ext/datetime_spec.rb
119
+ - spec/core_ext/exception.rb
120
+ - spec/core_ext/object.rb
121
+ - spec/model/collection_spec.rb
122
+ - spec/model/defaults_spec.rb
123
+ - spec/model/factories_spec.rb
124
+ - spec/model/lint_spec.rb
125
+ - spec/model/serialization/csv_spec.rb
126
+ - spec/model/serialization/tsv_spec.rb
127
+ - spec/model/serialization_spec.rb
128
+ - spec/model/type/extended_spec.rb
129
+ - spec/model/type/ip_address_spec.rb
130
+ - spec/model_spec.rb
131
+ - spec/spec_helper.rb
132
+ - spec/support/capture_output.rb
133
+ - spec/support/nuke_constants.rb
134
+ - spec/support/shared_context_for_builders.rb
135
+ - spec/support/shared_context_for_models.rb
136
+ - spec/support/shared_examples_for_factories.rb
137
+ - spec/support/shared_examples_for_model_fields.rb
138
+ - spec/support/shared_examples_for_models.rb
139
+ homepage: https://github.com/infochimps-labs/weavr.git
140
+ licenses:
141
+ - Apache 2.0
142
+ post_install_message:
143
+ rdoc_options: []
144
+ require_paths:
145
+ - lib
146
+ required_ruby_version: !ruby/object:Gem::Requirement
147
+ none: false
148
+ requirements:
149
+ - - ! '>='
150
+ - !ruby/object:Gem::Version
151
+ version: '0'
152
+ segments:
153
+ - 0
154
+ hash: -2686585051703152490
155
+ required_rubygems_version: !ruby/object:Gem::Requirement
156
+ none: false
157
+ requirements:
158
+ - - ! '>='
159
+ - !ruby/object:Gem::Version
160
+ version: '0'
161
+ segments:
162
+ - 0
163
+ hash: -2686585051703152490
164
+ requirements: []
165
+ rubyforge_project:
166
+ rubygems_version: 1.8.23
167
+ signing_key:
168
+ specification_version: 3
169
+ summary: Fully-featured Ruby model library
170
+ test_files:
171
+ - spec/builder_spec.rb
172
+ - spec/core_ext/datetime_spec.rb
173
+ - spec/core_ext/exception.rb
174
+ - spec/core_ext/object.rb
175
+ - spec/model/collection_spec.rb
176
+ - spec/model/defaults_spec.rb
177
+ - spec/model/factories_spec.rb
178
+ - spec/model/lint_spec.rb
179
+ - spec/model/serialization/csv_spec.rb
180
+ - spec/model/serialization/tsv_spec.rb
181
+ - spec/model/serialization_spec.rb
182
+ - spec/model/type/extended_spec.rb
183
+ - spec/model/type/ip_address_spec.rb
184
+ - spec/model_spec.rb
185
+ - spec/spec_helper.rb
186
+ - spec/support/capture_output.rb
187
+ - spec/support/nuke_constants.rb
188
+ - spec/support/shared_context_for_builders.rb
189
+ - spec/support/shared_context_for_models.rb
190
+ - spec/support/shared_examples_for_factories.rb
191
+ - spec/support/shared_examples_for_model_fields.rb
192
+ - spec/support/shared_examples_for_models.rb
193
+ has_rdoc: