flat_map 0.0.3
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.
- checksums.yaml +15 -0
- data/.gitignore +31 -0
- data/.metrics +17 -0
- data/.rspec +4 -0
- data/.ruby-gemset +1 -0
- data/.ruby-version +1 -0
- data/.travis.yml +9 -0
- data/Gemfile +20 -0
- data/LICENSE +20 -0
- data/README.markdown +211 -0
- data/Rakefile +15 -0
- data/flat_map.gemspec +30 -0
- data/lib/flat_map.rb +9 -0
- data/lib/flat_map/base_mapper.rb +95 -0
- data/lib/flat_map/base_mapper/attribute_methods.rb +54 -0
- data/lib/flat_map/base_mapper/factory.rb +238 -0
- data/lib/flat_map/base_mapper/mapping.rb +123 -0
- data/lib/flat_map/base_mapper/mounting.rb +168 -0
- data/lib/flat_map/base_mapper/persistence.rb +145 -0
- data/lib/flat_map/base_mapper/skipping.rb +62 -0
- data/lib/flat_map/base_mapper/traits.rb +94 -0
- data/lib/flat_map/empty_mapper.rb +29 -0
- data/lib/flat_map/errors.rb +57 -0
- data/lib/flat_map/mapper.rb +213 -0
- data/lib/flat_map/mapper/skipping.rb +45 -0
- data/lib/flat_map/mapper/targeting.rb +130 -0
- data/lib/flat_map/mapping.rb +124 -0
- data/lib/flat_map/mapping/factory.rb +21 -0
- data/lib/flat_map/mapping/reader.rb +12 -0
- data/lib/flat_map/mapping/reader/basic.rb +28 -0
- data/lib/flat_map/mapping/reader/formatted.rb +45 -0
- data/lib/flat_map/mapping/reader/formatted/formats.rb +28 -0
- data/lib/flat_map/mapping/reader/method.rb +25 -0
- data/lib/flat_map/mapping/reader/proc.rb +15 -0
- data/lib/flat_map/mapping/writer.rb +11 -0
- data/lib/flat_map/mapping/writer/basic.rb +25 -0
- data/lib/flat_map/mapping/writer/method.rb +28 -0
- data/lib/flat_map/mapping/writer/proc.rb +18 -0
- data/lib/flat_map/version.rb +3 -0
- data/spec/flat_map/empty_mapper_spec.rb +36 -0
- data/spec/flat_map/errors_spec.rb +23 -0
- data/spec/flat_map/mapper/attribute_methods_spec.rb +36 -0
- data/spec/flat_map/mapper/callbacks_spec.rb +76 -0
- data/spec/flat_map/mapper/factory_spec.rb +258 -0
- data/spec/flat_map/mapper/mapping_spec.rb +98 -0
- data/spec/flat_map/mapper/mounting_spec.rb +142 -0
- data/spec/flat_map/mapper/skipping_spec.rb +91 -0
- data/spec/flat_map/mapper/targeting_spec.rb +156 -0
- data/spec/flat_map/mapper/traits_spec.rb +172 -0
- data/spec/flat_map/mapper/validations_spec.rb +72 -0
- data/spec/flat_map/mapper_spec.rb +9 -0
- data/spec/flat_map/mapping/factory_spec.rb +12 -0
- data/spec/flat_map/mapping/reader/basic_spec.rb +15 -0
- data/spec/flat_map/mapping/reader/formatted_spec.rb +62 -0
- data/spec/flat_map/mapping/reader/method_spec.rb +13 -0
- data/spec/flat_map/mapping/reader/proc_spec.rb +13 -0
- data/spec/flat_map/mapping/writer/basic_spec.rb +15 -0
- data/spec/flat_map/mapping/writer/method_spec.rb +13 -0
- data/spec/flat_map/mapping/writer/proc_spec.rb +13 -0
- data/spec/flat_map/mapping_spec.rb +123 -0
- data/spec/spec_helper.rb +7 -0
- data/tmp/metric_fu/_data/20131218.yml +6902 -0
- data/tmp/metric_fu/_data/20131219.yml +6726 -0
- metadata +184 -0
@@ -0,0 +1,98 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module FlatMap
|
4
|
+
module MappingSpec
|
5
|
+
SpecTarget = Struct.new(:attr_a, :attr_b, :attr_c, :attr_d)
|
6
|
+
|
7
|
+
class SpecMapper < Mapper
|
8
|
+
# explicit mapping
|
9
|
+
map :mapped_attr_a => :attr_a
|
10
|
+
|
11
|
+
# implicit mapping
|
12
|
+
map :attr_b
|
13
|
+
|
14
|
+
# implicit and explicit with options in one call
|
15
|
+
map :attr_c, :mapped_attr_d => :attr_d,
|
16
|
+
:reader => :read_mappings,
|
17
|
+
:writer => :write_mappings
|
18
|
+
|
19
|
+
def read_mappings(mapping)
|
20
|
+
"#{mapping.name}-#{target.send(mapping.target_attribute)}"
|
21
|
+
end
|
22
|
+
|
23
|
+
def write_mappings(mapping, value)
|
24
|
+
target.send("#{mapping.target_attribute}=", value.upcase)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
class EmptyMapper < Mapper; end
|
29
|
+
end
|
30
|
+
|
31
|
+
describe 'Mapping' do
|
32
|
+
context 'defining mappings' do
|
33
|
+
it "should use Factory for defining mappings" do
|
34
|
+
MappingSpec::EmptyMapper.should_receive(:define_mappings).once.
|
35
|
+
with({:attr_a => :attr_a, :mapped_attr_b => :attr_b}, {:writer => false}).
|
36
|
+
and_call_original
|
37
|
+
Mapping::Factory.should_receive(:new).
|
38
|
+
with(:attr_a, :attr_a, :writer => false).
|
39
|
+
and_call_original
|
40
|
+
Mapping::Factory.should_receive(:new).
|
41
|
+
with(:mapped_attr_b, :attr_b, :writer => false).
|
42
|
+
and_call_original
|
43
|
+
|
44
|
+
MappingSpec::EmptyMapper.class_eval do
|
45
|
+
map :attr_a, :mapped_attr_b => :attr_b, :writer => false
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
specify 'mapper class should have defined mappings' do
|
51
|
+
MappingSpec::SpecMapper.should have(4).mappings
|
52
|
+
MappingSpec::SpecMapper.mappings.all?{ |m| m.is_a?(Mapping::Factory) }.should be_true
|
53
|
+
end
|
54
|
+
|
55
|
+
context "for initialized mapper" do
|
56
|
+
let(:target){ MappingSpec::SpecTarget.new('a', 'b', 'c', 'd') }
|
57
|
+
let(:mapper){ MappingSpec::SpecMapper.new(target) }
|
58
|
+
|
59
|
+
it "should be able to access mapping by its name" do
|
60
|
+
mapper.mapping(:mapped_attr_a).should be_a(FlatMap::Mapping)
|
61
|
+
mapper.mapping(:not_defined).should be_nil
|
62
|
+
end
|
63
|
+
|
64
|
+
describe 'reading and writing' do
|
65
|
+
it "should be able to read from target via brackets" do
|
66
|
+
mapper[:mapped_attr_a].should == 'a'
|
67
|
+
end
|
68
|
+
|
69
|
+
it 'should be able to write to target via brackets' do
|
70
|
+
mapper[:attr_b] = 'B'
|
71
|
+
target.attr_b.should == 'B'
|
72
|
+
end
|
73
|
+
|
74
|
+
it '#read should read all mappings to a hash' do
|
75
|
+
mapper.read.should == {
|
76
|
+
:mapped_attr_a => 'a',
|
77
|
+
:attr_b => 'b',
|
78
|
+
:attr_c => 'attr_c-c',
|
79
|
+
:mapped_attr_d => 'mapped_attr_d-d'
|
80
|
+
}
|
81
|
+
end
|
82
|
+
|
83
|
+
it '#write should assign values using mappings, ignoring invalid ones' do
|
84
|
+
mapper.write \
|
85
|
+
:mapped_attr_a => 'A',
|
86
|
+
:attr_b => 'B',
|
87
|
+
:attr_c => 'new-c',
|
88
|
+
:mapped_attr_d => 'new-d'
|
89
|
+
|
90
|
+
target.attr_a.should == 'A'
|
91
|
+
target.attr_b.should == 'B'
|
92
|
+
target.attr_c.should == 'NEW-C'
|
93
|
+
target.attr_d.should == 'NEW-D'
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
@@ -0,0 +1,142 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module FlatMap
|
4
|
+
module MountingSpec
|
5
|
+
MountTarget = Struct.new(:attr_a, :attr_b)
|
6
|
+
|
7
|
+
class MountMapper < Mapper
|
8
|
+
map :attr_a
|
9
|
+
|
10
|
+
trait :with_b do
|
11
|
+
map :mapped_attr_b => :attr_b
|
12
|
+
end
|
13
|
+
|
14
|
+
def a_method
|
15
|
+
'a value'
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
class HostMapper < Mapper
|
20
|
+
map :host_attr, :reader => :attr_value, :writer => false
|
21
|
+
|
22
|
+
mount :spec_mount,
|
23
|
+
:traits => :with_b,
|
24
|
+
:target => lambda{ |obj| MountingSpec.mount_target },
|
25
|
+
:mapper_class_name => 'FlatMap::MountingSpec::MountMapper'
|
26
|
+
|
27
|
+
mount :spec_mount_before,
|
28
|
+
:target => lambda{ |obj| MountingSpec.mount_target },
|
29
|
+
:mapper_class_name => 'FlatMap::MountingSpec::MountMapper',
|
30
|
+
:save => :before
|
31
|
+
|
32
|
+
def attr_value(*)
|
33
|
+
'attr'
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
class EmptyMapper < Mapper; end
|
38
|
+
|
39
|
+
def self.mount_target
|
40
|
+
@mount_target ||= MountTarget.new('a', 'b')
|
41
|
+
end
|
42
|
+
|
43
|
+
def self.reset_mount_target
|
44
|
+
@mount_target = nil
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
module MountingSuffixSpec
|
49
|
+
class SpecMapper < Mapper
|
50
|
+
mount_options = {
|
51
|
+
:suffix => 'foo',
|
52
|
+
:mapper_class_name => 'FlatMap::MountingSuffixSpec::MountMapper',
|
53
|
+
:target => lambda{ |_| OpenStruct.new } }
|
54
|
+
mount :mount, mount_options do
|
55
|
+
mount :nested,
|
56
|
+
:mapper_class_name => 'FlatMap::MountingSuffixSpec::NestedMapper',
|
57
|
+
:target => lambda{ |_| OpenStruct.new }
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
class MountMapper < Mapper
|
62
|
+
map :attr_mount
|
63
|
+
end
|
64
|
+
|
65
|
+
class NestedMapper < Mapper
|
66
|
+
map :attr_nested
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
describe 'Mounting' do
|
71
|
+
let(:mapper){ MountingSpec::HostMapper.new(Object.new) }
|
72
|
+
let(:mounting){ mapper.mounting(:spec_mount) }
|
73
|
+
|
74
|
+
after{ MountingSpec.reset_mount_target }
|
75
|
+
|
76
|
+
context 'defining mountings' do
|
77
|
+
it "should use Factory for defining mappings" do
|
78
|
+
Mapper::Factory.should_receive(:new).
|
79
|
+
with(:foo, :mapper_class_name => 'FooMapper').
|
80
|
+
and_call_original
|
81
|
+
|
82
|
+
expect{ MountingSpec::EmptyMapper.mount(:foo, :mapper_class_name => 'FooMapper') }.
|
83
|
+
to change{ MountingSpec::EmptyMapper.mountings.length }.from(0).to(1)
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
describe 'properties' do
|
88
|
+
it{ mapper.hosted?.should be_false }
|
89
|
+
it{ mounting.hosted?.should be_true }
|
90
|
+
it{ mounting.host.should == mapper }
|
91
|
+
end
|
92
|
+
|
93
|
+
it 'should be able to access mapping by name' do
|
94
|
+
mapper.mounting(:spec_mount).should be_a(FlatMap::Mapper)
|
95
|
+
mapper.mounting(:undefined_mount).should be_nil
|
96
|
+
end
|
97
|
+
|
98
|
+
it '#read should add mounted mappers to a result' do
|
99
|
+
mapper.read.should == {
|
100
|
+
:host_attr => 'attr',
|
101
|
+
:attr_a => 'a',
|
102
|
+
:mapped_attr_b => 'b'
|
103
|
+
}
|
104
|
+
end
|
105
|
+
|
106
|
+
it '#write should pass values to mounted mappers' do
|
107
|
+
target = MountingSpec.mount_target
|
108
|
+
mapper.write :attr_a => 'A', :mapped_attr_b => 'B'
|
109
|
+
target.attr_a.should == 'A'
|
110
|
+
target.attr_b.should == 'B'
|
111
|
+
end
|
112
|
+
|
113
|
+
it 'should delegate missing methods to mounted mappers' do
|
114
|
+
expect{ mapper.a_method.should == 'a value' }.not_to raise_error
|
115
|
+
end
|
116
|
+
|
117
|
+
specify '#before_save_mountings' do
|
118
|
+
mapper.before_save_mountings.should == [mapper.mounting(:spec_mount_before)]
|
119
|
+
end
|
120
|
+
|
121
|
+
specify '#after_save_mountings' do
|
122
|
+
mapper.after_save_mountings.should == [mapper.mounting(:spec_mount)]
|
123
|
+
end
|
124
|
+
|
125
|
+
context 'with suffix' do
|
126
|
+
let(:mapper){ MountingSuffixSpec::SpecMapper.new(OpenStruct.new) }
|
127
|
+
let(:mounting){ mapper.mounting(:mount_foo) }
|
128
|
+
|
129
|
+
it{ mapper.should_not be_suffixed }
|
130
|
+
it{ mounting.should be_suffixed }
|
131
|
+
|
132
|
+
it 'should cascade to nested mappings' do
|
133
|
+
mapper.attr_mount_foo = 'foo'
|
134
|
+
mapper.attr_nested_foo = 'bar'
|
135
|
+
|
136
|
+
mapper.read.should include({
|
137
|
+
:attr_mount_foo => 'foo',
|
138
|
+
:attr_nested_foo => 'bar' })
|
139
|
+
end
|
140
|
+
end
|
141
|
+
end
|
142
|
+
end
|
@@ -0,0 +1,91 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module FlatMap
|
4
|
+
module SkippingSpec
|
5
|
+
class SpecMapper < Mapper
|
6
|
+
trait :with_trait do
|
7
|
+
map :attr_a, :attr_b
|
8
|
+
|
9
|
+
set_callback :validate, :before, :set_attr_a, :prepend => true
|
10
|
+
set_callback :save, :before, :set_attr_b
|
11
|
+
|
12
|
+
validates_numericality_of :attr_a
|
13
|
+
|
14
|
+
def set_attr_a
|
15
|
+
self.attr_a = 'a'
|
16
|
+
end
|
17
|
+
|
18
|
+
def set_attr_b
|
19
|
+
self.attr_b = 'b'
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
describe 'Skipping' do
|
26
|
+
let(:mapper){ SkippingSpec::SpecMapper.new(OpenStruct.new, :with_trait) }
|
27
|
+
|
28
|
+
before{ mapper.trait(:with_trait).skip! }
|
29
|
+
|
30
|
+
it 'should completely ignore skipped mounting' do
|
31
|
+
mapper.should be_valid
|
32
|
+
mapper.save.should be_true
|
33
|
+
mapper.attr_a.should be_nil
|
34
|
+
mapper.attr_b.should be_nil
|
35
|
+
end
|
36
|
+
|
37
|
+
it '#use! should enable skipped mounting' do
|
38
|
+
mapper.trait(:with_trait).use!
|
39
|
+
|
40
|
+
mapper.should_not be_valid
|
41
|
+
mapper.attr_a.should == 'a'
|
42
|
+
mapper.errors[:attr_a].should be_present
|
43
|
+
|
44
|
+
mapper.attr_a = 5
|
45
|
+
mapper.save
|
46
|
+
mapper.attr_b.should == 'b'
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
describe 'Skipping ActiveRecord' do
|
51
|
+
let(:target){ OpenStruct.new }
|
52
|
+
let(:mapper){ SkippingSpec::SpecMapper.new(target, :with_trait) }
|
53
|
+
|
54
|
+
before{ target.stub(:is_a?).with(ActiveRecord::Base).and_return(true) }
|
55
|
+
|
56
|
+
context 'for new record' do
|
57
|
+
before do
|
58
|
+
target.stub(:new_record?).and_return(true)
|
59
|
+
mapper.trait(:with_trait).skip!
|
60
|
+
end
|
61
|
+
|
62
|
+
specify '#skip! should set ivar @destroyed to true' do
|
63
|
+
target.instance_variable_get('@destroyed').should be_true
|
64
|
+
end
|
65
|
+
|
66
|
+
specify '#use! should set ivar @destroyed to true' do
|
67
|
+
mapper.trait(:with_trait).use!
|
68
|
+
target.instance_variable_get('@destroyed').should be_false
|
69
|
+
end
|
70
|
+
end
|
71
|
+
|
72
|
+
context 'for persisted record' do
|
73
|
+
before do
|
74
|
+
target.stub(:new_record?).and_return(false)
|
75
|
+
end
|
76
|
+
|
77
|
+
specify '#skip! should reload persisted record' do
|
78
|
+
target.should_receive(:reload)
|
79
|
+
mapper.trait(:with_trait).skip!
|
80
|
+
end
|
81
|
+
|
82
|
+
specify '#use! should use all nested mountings' do
|
83
|
+
mapper.trait(:with_trait).skip!
|
84
|
+
mock = double('mounting')
|
85
|
+
mock.should_receive(:use!)
|
86
|
+
mapper.trait(:with_trait).stub(:all_nested_mountings).and_return([mock])
|
87
|
+
mapper.trait(:with_trait).use!
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
@@ -0,0 +1,156 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module FlatMap
|
4
|
+
module ModelMethodsSpec
|
5
|
+
class TargetClass < Struct.new(:attr_a, :attr_b)
|
6
|
+
end
|
7
|
+
|
8
|
+
class OtherTargetClass < Struct.new(:attr_c, :attr_d)
|
9
|
+
end
|
10
|
+
|
11
|
+
module ArbitraryModule
|
12
|
+
end
|
13
|
+
|
14
|
+
class TargetClassMapper < Mapper
|
15
|
+
include ArbitraryModule
|
16
|
+
|
17
|
+
map :attr_a
|
18
|
+
map :dob => :attr_b, :multiparam => Date
|
19
|
+
end
|
20
|
+
|
21
|
+
class InheritedClassMapper < TargetClassMapper
|
22
|
+
end
|
23
|
+
|
24
|
+
class ExplicitNameMapper < Mapper
|
25
|
+
self.target_class_name = 'FlatMap::ModelMethodsSpec::OtherTargetClass'
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
describe 'Working with Target' do
|
30
|
+
describe '#target_class' do
|
31
|
+
it 'should detect target_class from mapper class name' do
|
32
|
+
ModelMethodsSpec::TargetClassMapper.target_class.should == ModelMethodsSpec::TargetClass
|
33
|
+
end
|
34
|
+
|
35
|
+
it 'should detect target_class from nearest ancestor when inherited' do
|
36
|
+
ModelMethodsSpec::InheritedClassMapper.target_class.
|
37
|
+
should == ModelMethodsSpec::TargetClass
|
38
|
+
end
|
39
|
+
|
40
|
+
it 'should use explicit class name if specified' do
|
41
|
+
ModelMethodsSpec::ExplicitNameMapper.target_class.
|
42
|
+
should == ModelMethodsSpec::OtherTargetClass
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
describe '.build' do
|
47
|
+
it 'should use target class to build a new object for mapper' do
|
48
|
+
ModelMethodsSpec::TargetClassMapper.
|
49
|
+
should_receive(:new).
|
50
|
+
with(kind_of(ModelMethodsSpec::TargetClass), :used_trait)
|
51
|
+
ModelMethodsSpec::TargetClassMapper.build(:used_trait)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
describe '.find' do
|
56
|
+
let(:target){ ModelMethodsSpec::TargetClass.new('a', 'b') }
|
57
|
+
|
58
|
+
it 'should delegate to target class to find object for mapper' do
|
59
|
+
ModelMethodsSpec::TargetClass.should_receive(:find).with(1).and_return(target)
|
60
|
+
ModelMethodsSpec::TargetClassMapper.should_receive(:new).with(target, :used_trait)
|
61
|
+
ModelMethodsSpec::TargetClassMapper.find(1, :used_trait)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
describe 'behavior' do
|
66
|
+
let(:target){ ModelMethodsSpec::TargetClass.new('a', 'b') }
|
67
|
+
let(:mapper){ ModelMethodsSpec::TargetClassMapper.new(target){} }
|
68
|
+
|
69
|
+
specify '#model_name' do
|
70
|
+
mapper.model_name.should == 'mapper'
|
71
|
+
end
|
72
|
+
|
73
|
+
specify '#to_key should delegate to target' do
|
74
|
+
target.should_receive(:to_key).and_return(1)
|
75
|
+
mapper.to_key.should == 1
|
76
|
+
end
|
77
|
+
|
78
|
+
specify '#persisted? when target does not respond to :persised?' do
|
79
|
+
mapper.should_not be_persisted
|
80
|
+
end
|
81
|
+
|
82
|
+
specify '#persisted? when target responds to :persisted?' do
|
83
|
+
target.stub(:persisted?).and_return(true)
|
84
|
+
mapper.should be_persisted
|
85
|
+
end
|
86
|
+
|
87
|
+
specify '#id when target does not respond to :id' do
|
88
|
+
mapper.id.should be_nil
|
89
|
+
end
|
90
|
+
|
91
|
+
specify '#id when target responds to :id' do
|
92
|
+
target.stub(:id).and_return(1)
|
93
|
+
mapper.id.should == 1
|
94
|
+
end
|
95
|
+
|
96
|
+
describe '#write with multiparams' do
|
97
|
+
let(:params) {{
|
98
|
+
'attr_a' => 'A',
|
99
|
+
'dob(0i)' => '1999',
|
100
|
+
'dob(1i)' => '01',
|
101
|
+
'dob(2i)' => '02'
|
102
|
+
}}
|
103
|
+
|
104
|
+
it 'should assign values properly' do
|
105
|
+
mapper.write(params)
|
106
|
+
target.attr_a.should == 'A'
|
107
|
+
target.attr_b.should == Date.new(1999, 1, 2)
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
describe '#save_target' do
|
112
|
+
it 'should return true for owned mappers' do
|
113
|
+
mapper.extension.save_target.should be_true
|
114
|
+
end
|
115
|
+
|
116
|
+
it 'should return true if target does not respond to #save' do
|
117
|
+
mapper.save_target.should be_true
|
118
|
+
end
|
119
|
+
|
120
|
+
it 'should save with no validation if target responds to #save' do
|
121
|
+
target.should_receive(:save).with(:validate => false).and_return(true)
|
122
|
+
mapper.save_target.should be_true
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
describe '#apply' do
|
127
|
+
let(:params){{ :attr_a => 'A' }}
|
128
|
+
|
129
|
+
it 'should write params first' do
|
130
|
+
mapper.should_receive(:write).with(params)
|
131
|
+
ActiveRecord::Base.should_receive(:transaction).and_yield
|
132
|
+
mapper.apply(params)
|
133
|
+
end
|
134
|
+
|
135
|
+
it 'should not save if not valid' do
|
136
|
+
mapper.stub(:valid?).and_return(false)
|
137
|
+
mapper.should_not_receive(:save)
|
138
|
+
mapper.apply(params)
|
139
|
+
end
|
140
|
+
|
141
|
+
it 'should save if valid' do
|
142
|
+
mapper.stub(:valid?).and_return(true)
|
143
|
+
ActiveRecord::Base.should_receive(:transaction).and_yield
|
144
|
+
mapper.should_receive(:save)
|
145
|
+
mapper.apply(params)
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
specify '#shallow_save saves target in a save callbacks' do
|
150
|
+
mapper.should_receive(:run_callbacks).with(:save).and_yield
|
151
|
+
mapper.should_receive(:save_target)
|
152
|
+
mapper.shallow_save
|
153
|
+
end
|
154
|
+
end
|
155
|
+
end
|
156
|
+
end
|