gorillib 0.4.1pre → 0.4.2pre

Sign up to get free protection for your applications and to get access to all the features.
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