gorillib 0.4.1pre → 0.4.2pre

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 (89) hide show
  1. data/.gitignore +13 -10
  2. data/.rspec +1 -1
  3. data/.yardopts +1 -0
  4. data/CHANGELOG.md +47 -0
  5. data/Gemfile +22 -19
  6. data/Guardfile +23 -9
  7. data/README.md +12 -12
  8. data/Rakefile +29 -40
  9. data/VERSION +1 -1
  10. data/examples/benchmark/factories_benchmark.rb +87 -0
  11. data/examples/builder/ironfan.rb +1 -19
  12. data/examples/hash/slicing_methods.rb +101 -0
  13. data/gorillib.gemspec +36 -35
  14. data/lib/gorillib/array/deep_compact.rb +4 -3
  15. data/lib/gorillib/array/simple_statistics.rb +76 -0
  16. data/lib/gorillib/base.rb +0 -1
  17. data/lib/gorillib/builder.rb +15 -30
  18. data/lib/gorillib/collection.rb +159 -57
  19. data/lib/gorillib/collection/model_collection.rb +136 -43
  20. data/lib/gorillib/datetime/parse.rb +4 -2
  21. data/lib/gorillib/{array → deprecated/array}/average.rb +0 -0
  22. data/lib/gorillib/{array → deprecated/array}/random.rb +2 -1
  23. data/lib/gorillib/{array → deprecated/array}/sorted_median.rb +0 -0
  24. data/lib/gorillib/{array → deprecated/array}/sorted_percentile.rb +0 -0
  25. data/lib/gorillib/deprecated/array/sorted_sample.rb +13 -0
  26. data/lib/gorillib/{metaprogramming → deprecated/metaprogramming}/aliasing.rb +0 -0
  27. data/lib/gorillib/enumerable/sum.rb +3 -3
  28. data/lib/gorillib/exception/raisers.rb +92 -22
  29. data/lib/gorillib/factories.rb +550 -0
  30. data/lib/gorillib/hash/mash.rb +15 -58
  31. data/lib/gorillib/hashlike/deep_compact.rb +2 -2
  32. data/lib/gorillib/hashlike/slice.rb +55 -40
  33. data/lib/gorillib/model.rb +5 -3
  34. data/lib/gorillib/model/base.rb +33 -119
  35. data/lib/gorillib/model/defaults.rb +58 -14
  36. data/lib/gorillib/model/errors.rb +10 -0
  37. data/lib/gorillib/model/factories.rb +1 -367
  38. data/lib/gorillib/model/field.rb +40 -18
  39. data/lib/gorillib/model/fixup.rb +16 -0
  40. data/lib/gorillib/model/positional_fields.rb +35 -0
  41. data/lib/gorillib/model/schema_magic.rb +162 -0
  42. data/lib/gorillib/model/serialization.rb +1 -2
  43. data/lib/gorillib/model/serialization/csv.rb +59 -0
  44. data/lib/gorillib/pathname.rb +19 -8
  45. data/lib/gorillib/some.rb +2 -0
  46. data/lib/gorillib/string/constantize.rb +17 -10
  47. data/lib/gorillib/string/inflector.rb +11 -7
  48. data/lib/gorillib/type/boolean.rb +40 -0
  49. data/lib/gorillib/type/extended.rb +76 -40
  50. data/lib/gorillib/type/url.rb +6 -4
  51. data/lib/gorillib/utils/console.rb +1 -18
  52. data/lib/gorillib/utils/edge_cases.rb +18 -0
  53. data/spec/examples/builder/ironfan_spec.rb +5 -10
  54. data/spec/gorillib/array/compact_blank_spec.rb +36 -21
  55. data/spec/gorillib/array/simple_statistics_spec.rb +143 -0
  56. data/spec/gorillib/builder_spec.rb +16 -20
  57. data/spec/gorillib/collection_spec.rb +131 -35
  58. data/spec/gorillib/exception/raisers_spec.rb +39 -0
  59. data/spec/gorillib/hash/deep_compact_spec.rb +3 -3
  60. data/spec/gorillib/model/{record/defaults_spec.rb → defaults_spec.rb} +5 -1
  61. data/spec/gorillib/model/factories_spec.rb +335 -0
  62. data/spec/gorillib/model/{record/overlay_spec.rb → overlay_spec.rb} +0 -0
  63. data/spec/gorillib/model/serialization_spec.rb +2 -2
  64. data/spec/gorillib/model_spec.rb +19 -18
  65. data/spec/gorillib/pathname_spec.rb +7 -7
  66. data/spec/gorillib/string/truncate_spec.rb +3 -13
  67. data/spec/gorillib/type/extended_spec.rb +50 -2
  68. data/spec/gorillib/utils/capture_output_spec.rb +1 -1
  69. data/spec/spec_helper.rb +10 -7
  70. data/spec/support/factory_test_helpers.rb +76 -0
  71. data/spec/support/gorillib_test_helpers.rb +36 -24
  72. data/spec/support/model_test_helpers.rb +39 -2
  73. metadata +86 -51
  74. data/lib/alt/kernel/call_stack.rb +0 -56
  75. data/lib/gorillib/array/sorted_sample.rb +0 -12
  76. data/lib/gorillib/builder/field.rb +0 -5
  77. data/lib/gorillib/collection/has_collection.rb +0 -31
  78. data/lib/gorillib/collection/list_collection.rb +0 -58
  79. data/lib/gorillib/exception/confidence.rb +0 -17
  80. data/lib/gorillib/io/system_helpers.rb +0 -30
  81. data/lib/gorillib/model/record_schema.rb +0 -9
  82. data/lib/gorillib/utils/stub_module.rb +0 -33
  83. data/spec/array/average_spec.rb +0 -24
  84. data/spec/array/sorted_median_spec.rb +0 -18
  85. data/spec/array/sorted_percentile_spec.rb +0 -24
  86. data/spec/array/sorted_sample_spec.rb +0 -28
  87. data/spec/gorillib/metaprogramming/aliasing_spec.rb +0 -180
  88. data/spec/gorillib/model/record/factories_spec.rb +0 -335
  89. data/spec/support/kcode_test_helper.rb +0 -16
@@ -1,5 +1,5 @@
1
1
  require 'spec_helper'
2
- require 'model_test_helpers'
2
+ require 'support/model_test_helpers'
3
3
 
4
4
  require 'multi_json'
5
5
  #
@@ -7,7 +7,7 @@ require 'gorillib/model'
7
7
  require 'gorillib/builder'
8
8
  require 'gorillib/model/serialization'
9
9
 
10
- describe Gorillib::Model, :model_spec => true do
10
+ describe Gorillib::Model, :model_spec, :builder_spec do
11
11
  subject do
12
12
  garage.cars << wildcat
13
13
  garage.cars << ford_39
@@ -1,20 +1,9 @@
1
1
  require 'spec_helper'
2
- require 'model_test_helpers'
2
+ require 'support/model_test_helpers'
3
3
 
4
4
  require 'gorillib/model'
5
5
 
6
- describe Gorillib::Model, :model_spec => true do
7
- let(:smurf_class) do
8
- class Gorillib::Test::Smurf
9
- include Gorillib::Model
10
- field :smurfiness, Integer
11
- field :weapon, Symbol
12
- end
13
- Gorillib::Test::Smurf
14
- end
15
- let(:poppa_smurf ){ smurf_class.receive(:name => 'Poppa Smurf', :smurfiness => 9, :weapon => 'staff') }
16
- let(:smurfette ){ smurf_class.receive(:name => 'Smurfette', :smurfiness => 11, :weapon => 'charm') }
17
-
6
+ describe Gorillib::Model, :model_spec do
18
7
  let(:simple_model) do
19
8
  class Gorillib::Test::SimpleModel
20
9
  include Gorillib::Model
@@ -53,8 +42,8 @@ describe Gorillib::Model, :model_spec => true do
53
42
  obj.attributes.should == { :my_field => 'accepted as-is', :str_field => 'bob', :sym_field=>:converted_to_sym }
54
43
  end
55
44
  it 'handles nested structures' do
56
- deep_obj = nested_model.receive(:str_field => 'deep, man', :smurf => poppa_smurf.attributes)
57
- deep_obj.attributes.should == { :str_field => 'deep, man', :smurf => poppa_smurf, :sym_field=>nil, :my_field => nil, }
45
+ deep_obj = nested_model.receive(:str_field => 'deep, man', :smurf => papa_smurf.attributes)
46
+ deep_obj.attributes.should == { :str_field => 'deep, man', :smurf => papa_smurf, :sym_field=>nil, :my_field => nil, }
58
47
  end
59
48
  end
60
49
 
@@ -81,9 +70,9 @@ describe Gorillib::Model, :model_spec => true do
81
70
  example_inst.should_receive(:write_attribute).with(:my_field, mock_val)
82
71
  (example_inst.my_field = mock_val).should == mock_val
83
72
  end
84
- it "supplies a receiver method #receive_foo to call write_attribute(:foo) and return self" do
85
- example_inst.should_receive(:write_attribute).with(:my_field, mock_val)
86
- (example_inst.receive_my_field(mock_val)).should == example_inst
73
+ it "supplies #receive_foo, which does write_attribute(:foo) and returns the new value " do
74
+ example_inst.should_receive(:write_attribute).with(:my_field, mock_val).and_return('okey doke!')
75
+ (example_inst.receive_my_field(mock_val)).should == 'okey doke!'
87
76
  end
88
77
  it "sets visibility of reader with :reader => ()" do
89
78
  described_class.field :test_field, Integer, :reader => :private, :writer => false
@@ -171,6 +160,9 @@ describe Gorillib::Model, :model_spec => true do
171
160
  example_inst.should_receive(:write_attribute).with(:str_field, 'yo')
172
161
  example_inst.receive! 'my_field'=>7, :str_field=>'yo'
173
162
  end
163
+ it "returns nil with no block given" do
164
+ example_inst.receive!('my_field'=>7, :str_field=>'yo').should be_nil
165
+ end
174
166
  end
175
167
 
176
168
  context '#== -- two models are equal if' do
@@ -229,6 +221,15 @@ describe Gorillib::Model, :model_spec => true do
229
221
  end
230
222
  end
231
223
 
224
+ context '.inspect' do
225
+ it('is pretty'){ smurf_class.inspect.should == 'Gorillib::Test::Smurf[name,smurfiness,weapon]' }
226
+ it('is pretty even if class is anonymous'){ Class.new(smurf_class).inspect.should == 'anon[name,smurfiness,weapon]' }
227
+ end
228
+ context '.inspect_compact' do
229
+ it('is just the class name'){ smurf_class.inspect_compact.should == "Gorillib::Test::Smurf" }
230
+ it('is detailed if class is anonymous'){ Class.new(smurf_class).inspect_compact.should == "anon[name,smurfiness,weapon]" }
231
+ end
232
+
232
233
  describe Gorillib::Model::NamedSchema do
233
234
  context ".meta_module" do
234
235
  let(:basic_field_names){ [ :my_field, :my_field=, :receive_my_field, :receive_str_field, :receive_sym_field, :str_field, :str_field=, :sym_field, :sym_field= ]}
@@ -58,17 +58,17 @@ describe Pathname do
58
58
  end
59
59
  end
60
60
 
61
- context '.relative_path_to' do
61
+ context '.relpath_to' do
62
62
  subject{ described_class }
63
63
 
64
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')
65
+ subject.relpath_to('/', '../..', :access, '//have', 'a//pepsi').should == Pathname.new('/would/you/like/to/have/a/pepsi')
66
66
  end
67
67
 
68
68
  it 'does not expand relative paths' do
69
69
  FileUtils.cd '/' do
70
70
  subject.register_path(:hello, 'doctor')
71
- subject.relative_path_to(:hello, :hello, :hello).should == Pathname.new('doctor/doctor/doctor')
71
+ subject.relpath_to(:hello, :hello, :hello).should == Pathname.new('doctor/doctor/doctor')
72
72
  end
73
73
  end
74
74
  end
@@ -76,7 +76,7 @@ describe Pathname do
76
76
  context 'registering paths' do
77
77
  subject { described_class }
78
78
  def expand_pathseg(*args) ; subject.send(:expand_pathseg, *args) ; end
79
-
79
+
80
80
  context '.register_path' do
81
81
  it 'stores a path so expand_pathseg can get it later' do
82
82
  subject.register_path(:probe, ['skeletal', 'girth'])
@@ -92,10 +92,10 @@ describe Pathname do
92
92
  expand_pathseg(:glg_20).should == ['milbarge', 'fitz-hume']
93
93
  end
94
94
  end
95
-
95
+
96
96
  context '.register_paths' do
97
97
  let(:paths) { { :foo => ['foo'], :bar => [:foo, 'bar'] } }
98
-
98
+
99
99
  it 'registers multiple paths' do
100
100
  subject.should_receive(:register_path).exactly(paths.size).times
101
101
  subject.register_paths(paths)
@@ -109,6 +109,6 @@ describe Pathname do
109
109
  subject.unregister_path(:foo)
110
110
  expect{ expand_pathseg(:foo)}.to raise_error(ArgumentError, /expand path reference.*foo/)
111
111
  end
112
- end
112
+ end
113
113
  end
114
114
  end
@@ -1,5 +1,4 @@
1
1
  require 'spec_helper'
2
- require GORILLIB_ROOT_DIR('spec/support/kcode_test_helper')
3
2
  require 'gorillib/string/truncate'
4
3
 
5
4
  describe String, :string_spec => true do
@@ -19,18 +18,9 @@ describe String, :string_spec => true do
19
18
  "Hello Big World!".truncate(15, :omission => "[...]", :separator => ' ') .should == "Hello Big[...]"
20
19
  end
21
20
 
22
- if RUBY_VERSION < '1.9.0'
23
- it 'works with unicode when kcode=none' do
24
- Gorillib::KcodeTestHelper.with_kcode('none') do
25
- "\354\225\210\353\205\225\355\225\230\354\204\270\354\232\224".truncate(10).
26
- should == "\354\225\210\353\205\225\355..."
27
- end
28
- end
29
- else # ruby 1.9
30
- it 'works with unicode' do
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).
32
- should == "\354\225\204\353\246\254\353\236\221 \354\225\204\353\246\254 ...".force_encoding('UTF-8')
33
- end
21
+ it 'works with unicode' do
22
+ "\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).
23
+ should == "\354\225\204\353\246\254\353\236\221 \354\225\204\353\246\254 ...".force_encoding('UTF-8')
34
24
  end
35
25
  end
36
26
 
@@ -1,7 +1,8 @@
1
1
  require 'spec_helper'
2
-
3
- require 'gorillib/type/extended'
2
+ require 'support/factory_test_helpers'
4
3
  require 'gorillib/object/blank'
4
+ #
5
+ require 'gorillib/type/extended'
5
6
 
6
7
  describe ::Long do
7
8
  it "is_a?(Integer)" do ::Long.should < ::Integer ; end
@@ -15,6 +16,53 @@ describe ::Binary do
15
16
  it "is_a?(String)" do ::Binary.should < ::String ; end
16
17
  end
17
18
 
19
+ describe 'factory', :factory_spec do
20
+ describe Gorillib::Factory::DateFactory do
21
+ fuck_wit_dre_day = Date.new(1993, 2, 18) # and Everybody's Celebratin'
22
+ ice_cubes_good_day = Date.new(1992, 1, 20)
23
+ it_behaves_like :it_considers_native, Date.today, fuck_wit_dre_day, ice_cubes_good_day
24
+ it_behaves_like :it_converts, '19930218' => fuck_wit_dre_day, '19920120' => ice_cubes_good_day
25
+ it_behaves_like :it_converts, Time.utc(1992, 1, 20, 8, 8, 8) => ice_cubes_good_day
26
+ before('behaves like it_converts "an unparseable date" to nil'){ subject.stub(:warn) }
27
+ it_behaves_like :it_converts, "an unparseable date" => nil, :non_native_ok => true
28
+ it_behaves_like :it_considers_blankish, nil, ""
29
+ it_behaves_like :it_is_a_mismatch_for, :foo, false, []
30
+ it_behaves_like :it_is_registered_as, :date, Date
31
+ its(:typename){ should == :date }
32
+ end
33
+
34
+ describe Gorillib::Factory::SetFactory do
35
+ let(:collection_123){ Set.new([1,2,3]) }
36
+ let(:empty_collection){ Set.new }
37
+
38
+ it 'follows examples' do
39
+ described_class.new.receive([1,2,3]).should == collection_123
40
+ described_class.new(:items => :symbol).receive(['a', 'b', :c]).should == [:a, :b, :c].to_set
41
+ described_class.new(:empty_product => [1,2,3].to_set).receive([:a, :b, :c]).should == [1, 2, 3, :a, :b, :c].to_set
42
+
43
+ has_an_empty_array = described_class.new.receive( [[]] )
44
+ has_an_empty_array.should == Set.new( [[]] )
45
+ has_an_empty_array.first.should == []
46
+ has_an_empty_array.size.should == 1
47
+ end
48
+
49
+ it_behaves_like :it_considers_blankish, nil
50
+ 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 }
51
+ it_behaves_like :an_enumerable_factory
52
+ it_behaves_like :it_is_registered_as, :set, Set
53
+ its(:typename){ should == :set }
54
+ end
55
+
56
+ describe Gorillib::Factory::Boolean10Factory do
57
+ it_behaves_like :it_considers_native, true, false
58
+ it_behaves_like :it_considers_blankish, nil
59
+ it_behaves_like :it_converts, "false" => false, :false => false, "0" => false, 0 => false
60
+ it_behaves_like :it_converts, "true" => true, :true => true, "1" => true, [] => true, :foo => true, [] => true, Complex(1.5,3) => true, Object.new => true
61
+ it_behaves_like :it_is_registered_as, :boolean_10
62
+ its(:typename){ should == :boolean_10 }
63
+ end
64
+ end
65
+
18
66
  # describe ::Boolean, :model_spec => true do
19
67
  # let(:true_bool ){ ::Boolean.new(true) }
20
68
  # let(:false_bool){ ::Boolean.new(false) }
@@ -59,7 +59,7 @@ describe Gorillib::TestHelpers, :simple_spec => true do
59
59
  end
60
60
 
61
61
  it 'raises an error if no block is given' do
62
- lambda{ Gorillib::TestHelpers.capture_output }.should raise_error(LocalJumpError, "no block given (yield)")
62
+ lambda{ Gorillib::TestHelpers.capture_output }.should raise_error(LocalJumpError, /no block given/)
63
63
  end
64
64
 
65
65
  end
@@ -1,20 +1,23 @@
1
- require 'rubygems' unless defined?(Gem)
2
- require 'rspec'
1
+ require 'bundler/setup' ; Bundler.require(:default, :development, :test)
2
+ require 'rspec/autorun'
3
+
4
+ if ENV['GORILLIB_COV']
5
+ require 'simplecov'
6
+ SimpleCov.start
7
+ end
3
8
 
4
9
  GORILLIB_ROOT_DIR = File.expand_path(File.join(File.dirname(__FILE__),'..'))
5
10
  def GORILLIB_ROOT_DIR *paths
6
11
  File.join(::GORILLIB_ROOT_DIR, *paths)
7
12
  end
8
13
 
9
- ENV['QUIET_RSPEC'] = 'please'
10
-
11
14
  $LOAD_PATH.unshift(GORILLIB_ROOT_DIR('lib'))
12
15
  $LOAD_PATH.unshift(GORILLIB_ROOT_DIR('spec/support'))
13
- require 'gorillib_test_helpers'
14
- Dir[GORILLIB_ROOT_DIR('spec/support/matchers/*.rb')].each {|f| require f}
16
+
17
+ require_relative 'support/gorillib_test_helpers'
18
+ Dir[GORILLIB_ROOT_DIR('spec/support/matchers/*.rb')].each{|f| require f}
15
19
 
16
20
  RSpec.configure do |config|
17
21
  include Gorillib::TestHelpers
18
-
19
22
  config.treat_symbols_as_metadata_keys_with_true_values = true
20
23
  end
@@ -0,0 +1,76 @@
1
+
2
+ #
3
+ # Shared examples for testing type factories
4
+ #
5
+
6
+ shared_examples_for :it_converts do |conversion_mapping|
7
+ non_native_ok = conversion_mapping.delete(:non_native_ok)
8
+ conversion_mapping.each do |obj, expected_result|
9
+ it "#{obj.inspect} to #{expected_result.inspect}" do
10
+ actual_result = subject.receive(obj)
11
+ actual_result.should eql(expected_result)
12
+ subject.native?( obj).should be_false
13
+ subject.blankish?(obj).should be_false
14
+ unless non_native_ok then subject.native?(actual_result).should be_true ; end
15
+ end
16
+ end
17
+ end
18
+
19
+ shared_examples_for :it_considers_native do |*native_objs|
20
+ it native_objs.inspect do
21
+ native_objs.each do |obj|
22
+ subject.native?( obj).should be_true
23
+ actual_result = subject.receive(obj)
24
+ actual_result.should equal(obj)
25
+ end
26
+ end
27
+ end
28
+
29
+ shared_examples_for :it_considers_blankish do |*blankish_objs|
30
+ it blankish_objs.inspect do
31
+ blankish_objs.each do |obj|
32
+ subject.blankish?(obj).should be_true
33
+ subject.receive(obj).should be_nil
34
+ end
35
+ end
36
+ end
37
+
38
+ shared_examples_for :it_is_a_mismatch_for do |*mismatched_objs|
39
+ it mismatched_objs.inspect do
40
+ mismatched_objs.each do |obj|
41
+ ->{ subject.receive(obj) }.should raise_error(Gorillib::Factory::FactoryMismatchError)
42
+ end
43
+ end
44
+ end
45
+
46
+ shared_examples_for :it_is_registered_as do |*keys|
47
+ it "the factory for #{keys}" do
48
+ keys.each do |key|
49
+ Gorillib::Factory(key).should be_a(described_class)
50
+ end
51
+ its_factory = Gorillib::Factory(keys.first)
52
+ Gorillib::Factory.send(:factories).to_hash.select{|key,val| val.equal?(its_factory) }.keys.should == keys
53
+ end
54
+ end
55
+
56
+ # hand it a collection with entries 1, 2, 3 please
57
+ shared_examples_for :an_enumerable_factory do
58
+ it "accepts a factory for its items" do
59
+ mock_factory = mock('factory')
60
+ mock_factory.should_receive(:receive).with(1)
61
+ mock_factory.should_receive(:receive).with(2)
62
+ mock_factory.should_receive(:receive).with(3)
63
+ factory = described_class.new(:items => mock_factory)
64
+ factory.receive( collection_123 )
65
+ end
66
+ it "can generate an empty collection" do
67
+ subject.empty_product.should == empty_collection
68
+ end
69
+ it "lets you override the empty collection" do
70
+ ep = mock; ep.should_receive(:try_dup).and_return 'hey'
71
+ subject = described_class.new(:empty_product => ep)
72
+ subject.empty_product.should == 'hey'
73
+ subject = described_class.new(:empty_product => ->{ 'yo' })
74
+ subject.empty_product.should == 'yo'
75
+ end
76
+ end
@@ -12,27 +12,39 @@ shared_examples_for 'a model' do
12
12
  obj = smurf_class.new :smurfiness => 3, :weapon => :smurfchucks
13
13
  obj.compact_attributes.should == { :smurfiness => 3, :weapon => :smurfchucks }
14
14
  end
15
- it "takes all preceding args as positional, clobbering values set in attrs" do
16
- obj = smurf_class.new 7, :smurfing_stars
17
- obj.compact_attributes.should == { :smurfiness => 7, :weapon => :smurfing_stars }
18
- obj = smurf_class.new 7, :smurfing_stars, :smurfiness => 3, :weapon => :smurfchucks
19
- obj.compact_attributes.should == { :smurfiness => 7, :weapon => :smurfing_stars }
20
- end
21
- it "does nothing special with a nil positional arg -- it clobbers anything there setting the attribute to nil" do
22
- obj = smurf_class.new nil, :smurfiness => 3
23
- obj.compact_attributes.should == { :smurfiness => nil }
24
- end
25
- it "raises an error if too many positional args are given" do
26
- ->{ smurf_class.new 7, :smurfing_stars, :azrael }.should raise_error(ArgumentError, /wrong number of arguments.*3.*0\.\.2/)
27
- end
28
- it "always takes the last hash arg as the attrs -- even if it is in the positional slot of a hash field" do
29
- smurf_class.field :hashie, Hash
30
- obj = smurf_class.new({:smurfiness => 3, :weapon => :smurfchucks})
31
- obj.compact_attributes.should == { :smurfiness => 3, :weapon => :smurfchucks }
32
- obj = smurf_class.new(3, :smurfchucks, { :weapon => :bastard_smurf })
33
- obj.compact_attributes.should == { :smurfiness => 3, :weapon => :smurfchucks }
34
- obj = smurf_class.new(3, :smurfchucks, {:this => :that}, { :weapon => :bastard_smurf })
35
- obj.compact_attributes.should == { :smurfiness => 3, :weapon => :smurfchucks, :hashie => {:this => :that} }
15
+
16
+ context 'positional args' do
17
+ before do
18
+ smurf_class.fields[:smurfiness].position = 0
19
+ smurf_class.fields[:weapon ].position = 1
20
+ end
21
+ it "takes all preceding args as positional, clobbering values set in attrs" do
22
+ obj = smurf_class.new 7, :smurfing_stars
23
+ obj.compact_attributes.should == { :smurfiness => 7, :weapon => :smurfing_stars }
24
+ obj = smurf_class.new 7, :smurfing_stars, :smurfiness => 3, :weapon => :smurfchucks
25
+ obj.compact_attributes.should == { :smurfiness => 7, :weapon => :smurfing_stars }
26
+ end
27
+ it "does nothing special with a nil positional arg -- it clobbers anything there setting the attribute to nil" do
28
+ obj = smurf_class.new nil, :smurfiness => 3
29
+ obj.compact_attributes.should == { :smurfiness => nil }
30
+ end
31
+ it "raises an error if too many positional args are given" do
32
+ ->{ smurf_class.new 7, :smurfing_stars, :azrael }.should raise_error(ArgumentError, /wrong number of arguments.*3.*0\.\.2/)
33
+ end
34
+ it "always takes the last hash arg as the attrs -- even if it is in the positional slot of a hash field" do
35
+ smurf_class.field :hashie, Hash, :position => 2
36
+ obj = smurf_class.new({:smurfiness => 3, :weapon => :smurfiken})
37
+ obj.compact_attributes.should == { :smurfiness => 3, :weapon => :smurfiken }
38
+ obj = smurf_class.new(3, :smurfiken, { :weapon => :bastard_smurf })
39
+ obj.compact_attributes.should == { :smurfiness => 3, :weapon => :smurfiken }
40
+ obj = smurf_class.new(3, :smurfiken, {:this => :that}, { :weapon => :bastard_smurf })
41
+ obj.compact_attributes.should == { :smurfiness => 3, :weapon => :smurfiken, :hashie => {:this => :that} }
42
+ end
43
+ it "skips fields that are not positional args" do
44
+ smurf_class.fields[:weapon].unset_attribute(:position)
45
+ smurf_class.field :color, String, :position => 1
46
+ smurf_class.new(99, 'cerulean').compact_attributes.should == { :smurfiness => 99, :color => 'cerulean' }
47
+ end
36
48
  end
37
49
  end
38
50
 
@@ -44,7 +56,7 @@ shared_examples_for 'a model' do
44
56
  smurf_class.receive(nil).should == nil
45
57
  end
46
58
  it "returns the object if given a single object of the model class" do
47
- smurf_class.receive(poppa_smurf).should equal(poppa_smurf)
59
+ smurf_class.receive(papa_smurf).should equal(papa_smurf)
48
60
  end
49
61
  it "raises an error if the attributes are not hashlike" do
50
62
  ->{ smurf_class.receive('DURRRR') }.should raise_error(ArgumentError, /attributes .* like a hash: "DURRRR"/)
@@ -126,8 +138,8 @@ shared_examples_for "a model field" do |field_name|
126
138
  end
127
139
 
128
140
  context "#receive_XX" do
129
- it('returns the model itself') do
130
- subject.send("receive_#{field_name}", raw_val).should == subject
141
+ it('returns the new attribute') do
142
+ subject.send("receive_#{field_name}", raw_val).should == sample_val
131
143
  end
132
144
  it('type-converts the object') do
133
145
  subject.send("receive_#{field_name}", raw_val)
@@ -1,11 +1,48 @@
1
1
  module Gorillib ; module Test ; end ; end
2
2
  module Meta ; module Gorillib ; module Test ; end ; end ; end
3
3
 
4
- shared_context 'model', :model_spec => true do
4
+ shared_context 'model', :model_spec do
5
5
  after(:each){ Gorillib::Test.nuke_constants ; Meta::Gorillib::Test.nuke_constants }
6
6
 
7
7
  let(:mock_val){ mock('mock value') }
8
8
 
9
+ let(:smurf_class) do
10
+ class Gorillib::Test::Smurf
11
+ include Gorillib::Model
12
+ field :name, String
13
+ field :smurfiness, Integer
14
+ field :weapon, Symbol
15
+ end
16
+ Gorillib::Test::Smurf
17
+ end
18
+ let(:papa_smurf ){ smurf_class.receive(:name => 'Papa Smurf', :smurfiness => 9, :weapon => 'staff') }
19
+ let(:smurfette ){ smurf_class.receive(:name => 'Smurfette', :smurfiness => 11, :weapon => 'charm') }
20
+
21
+ let(:smurf_collection_class) do
22
+ smurf_class
23
+ class Gorillib::Test::SmurfCollection < Gorillib::ModelCollection
24
+ include Gorillib::Collection::ItemsBelongTo
25
+ self.item_type = Gorillib::Test::Smurf
26
+ self.parentage_method = :village
27
+ end
28
+ Gorillib::Test::SmurfCollection
29
+ end
30
+
31
+ let(:smurf_village_class) do
32
+ smurf_class ; smurf_collection_class
33
+ module Gorillib::Test
34
+ class SmurfVillage
35
+ include Gorillib::Model
36
+ field :name, Symbol
37
+ collection :smurfs, SmurfCollection, item_type: Smurf, key_method: :name
38
+ end
39
+ end
40
+ Gorillib::Test::SmurfVillage
41
+ end
42
+
43
+ end
44
+
45
+ shared_context 'builder', :model_spec, :builder_spec do
9
46
  let(:engine_class) do
10
47
  class Gorillib::Test::Engine
11
48
  include Gorillib::Builder
@@ -37,7 +74,7 @@ shared_context 'model', :model_spec => true do
37
74
  car_class
38
75
  class Gorillib::Test::Garage
39
76
  include Gorillib::Builder
40
- collection :cars, Gorillib::Test::Car
77
+ collection :cars, Gorillib::Test::Car, key_method: :name
41
78
  self
42
79
  end
43
80
  Gorillib::Test::Garage