skn_utils 1.4.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,123 @@
1
+ ##
2
+ # spec/lib/skn_utils/generic_bean_spec.rb
3
+ #
4
+
5
+ RSpec.describe SknUtils::PageControls, "PageControls Marshal'able Bean class " do
6
+ let(:object) {
7
+ SknUtils::PageControls.new({one: "one",
8
+ two: "two",
9
+ three: {four: 4, five: 5, six: {seven: 7, eight: "eight" }},
10
+ four: {any_key: "any value"},
11
+ five: [],
12
+ six: [{any_key: "any value"},
13
+ {four: 4,
14
+ five: 5,
15
+ six: {seven: 7, eight: "eight" },
16
+ twenty:[{seven: 7, eight: 8 }, {nine: 9, ten: 10 }]
17
+ }
18
+ ]
19
+ })
20
+ }
21
+
22
+ context "Internal Operations, assuming :dept => :multi_with_arrays and enable_serialization => true" do
23
+ it "Creates an empty bean if no params are passed" do
24
+ is_expected.to be
25
+ end
26
+ it "Can be Marshalled after dynamically adding a key/value." do
27
+ expect { object.fifty = {any_key: "any value"} }.not_to raise_error
28
+ expect { object.sixty = 60 }.not_to raise_error
29
+ dmp = obj = ""
30
+ expect { dmp = Marshal.dump(object) }.not_to raise_error
31
+ expect { obj = Marshal.load(dmp) }.not_to raise_error
32
+ expect(obj).to be_a(SknUtils::PageControls)
33
+ expect( object.fifty.any_key).to eql "any value"
34
+ expect( object.sixty).to eql 60
35
+ end
36
+ it "Initializes from a hash" do
37
+ expect(object).to be
38
+ end
39
+ it "Does not modify the base class, only singleton instance methods" do
40
+ obj1 = SknUtils::PageControls.new({one: "one", two: "two"})
41
+ obj2 = SknUtils::PageControls.new({three: "3", four: "4"})
42
+ expect(obj1.one).to eql "one"
43
+ expect(obj2.three).to eql "3"
44
+ expect(obj2.one?).to be false
45
+ expect(obj1.three?).to be false
46
+ expect { obj1.three }.to raise_error NoMethodError
47
+ expect { obj2.one }.to raise_error NoMethodError
48
+ end
49
+ it "Supports predicates(?)" do
50
+ expect(object.one?).to be true
51
+ expect(object.three.five?).to be true
52
+ end
53
+ it "Does not support - respond_to - methods, because it has no accessor methods" do
54
+ expect(object).not_to respond_to(:one)
55
+ expect(object.one).to eql "one"
56
+ end
57
+ it "nest objects if multi-level hash is given" do
58
+ expect(object.three).to be_a(SknUtils::PageControls)
59
+ expect(object.three.five).to eq(5)
60
+ end
61
+ it "nest objects if multi-level array of hashes is given" do
62
+ expect(object.six).to be_a(Array)
63
+ expect(object.six.first).to be_a(SknUtils::PageControls)
64
+ expect(object.six.last).to be_a(SknUtils::PageControls)
65
+ expect(object.six.last.six.eight).to eq('eight')
66
+ end
67
+ it "nest objects if multi-level array of hashes, and an element contains another array of hashes, is given" do
68
+ expect(object.six.first).to be_a(SknUtils::PageControls)
69
+ expect(object.six).to be_a(Array)
70
+ expect(object.six.last.twenty).to be_a(Array)
71
+ expect(object.six.last.twenty.first).to be_a(SknUtils::PageControls)
72
+ expect(object.six.last.twenty.last).to be_a(SknUtils::PageControls)
73
+ expect(object.six.last.twenty.first.eight).to eq(8)
74
+ expect(object.six.last.twenty.last.ten).to eq(10)
75
+ end
76
+ it "nest arrays of objects if array of hashes is dynamically given (post-create)" do
77
+ expect { object.one_array = [{one: "one", two: "two"},{one: 1, two: 2}] }.not_to raise_error
78
+ expect(object.one_array.first.one).to eql("one")
79
+ expect(object.one_array.last.two).to eql(2)
80
+ expect(object.one_array[0]).to be_a(SknUtils::PageControls)
81
+ end
82
+ it "#attributes method returns a hash of all attributes and their values." do
83
+ expect(object.attributes).to be_a(Hash)
84
+ expect(object.attributes[:one]).to be_eql("one")
85
+ expect(object.attributes[:three]).to be_a(Hash)
86
+ expect(object.attributes[:six].last[:six][:eight]).to eql('eight')
87
+ end
88
+ end
89
+
90
+ shared_examples_for "retains initialization options" do
91
+ it "retains depth_level option flag" do
92
+ expect(@obj.depth_level).to eql(:multi_with_arrays)
93
+ end
94
+ it "retains serialization option flag" do
95
+ expect(@obj.serialization_required?).to be true
96
+ end
97
+ end
98
+
99
+ context "Basic Operations without marshaling " do
100
+ before :each do
101
+ @obj = object
102
+ end
103
+ it_behaves_like "retains initialization options"
104
+ it_behaves_like "marshalable ruby pojo"
105
+ end
106
+ context "Basic Operations after Yaml marshaling " do
107
+ before :each do
108
+ dmp = YAML::dump(object)
109
+ @obj = YAML::load(dmp)
110
+ end
111
+ it_behaves_like "retains initialization options"
112
+ it_behaves_like "marshalable ruby pojo"
113
+ end
114
+ context "Basic Operations after Marshal marshaling " do
115
+ before :each do
116
+ dmp = Marshal.dump(object)
117
+ @obj = Marshal.load(dmp)
118
+ end
119
+ it_behaves_like "retains initialization options"
120
+ it_behaves_like "marshalable ruby pojo"
121
+ end
122
+
123
+ end
@@ -0,0 +1,92 @@
1
+ ##
2
+ # spec/lib/skn_utils/result_bean_spec.rb
3
+ #
4
+
5
+ RSpec.describe SknUtils::ResultBean, "Result Bean class - Basic useage." do
6
+ let(:object) {
7
+ SknUtils::ResultBean.new({one: "one",
8
+ two: "two",
9
+ three: {four: 4, five: 5, six: {seven: 7, eight: "eight" }},
10
+ four: {any_key: "any value"},
11
+ five: []
12
+ })
13
+ }
14
+
15
+ context "Internal Operations, assuming :dept => :multi and enable_serialization => false" do
16
+ it "Creates an empty bean if no params are passed" do
17
+ is_expected.to be
18
+ end
19
+ it "Initializes from a hash" do
20
+ expect(SknUtils::ResultBean.new({one: "one", two: "two"})).to be
21
+ end
22
+ it "Does not modify the base class, only singleton instance methods" do
23
+ obj1 = SknUtils::ResultBean.new({one: "one", two: "two"})
24
+ obj2 = SknUtils::ResultBean.new({three: 3, four: "4"})
25
+ expect(obj1.one).to eql "one"
26
+ expect(obj2.three).to eql 3
27
+ expect(obj2.one?).to be false
28
+ expect(obj1.three?).to be false
29
+ expect { obj1.three }.to raise_error NoMethodError
30
+ expect { obj2.one }.to raise_error NoMethodError
31
+ end
32
+ it "Supports - respond_to - methods, because it has accessor methods" do
33
+ expect(object).to respond_to(:one)
34
+ end
35
+ end
36
+
37
+ shared_examples_for "retains initialization options" do
38
+ it "retains depth_level option flag" do
39
+ expect(@obj.depth_level).to eql(:multi)
40
+ end
41
+ it "retains serialization option flag" do
42
+ expect(@obj.serialization_required?).to be false
43
+ end
44
+ end
45
+
46
+ context "Basic Operations after Marshal marshaling " do
47
+ it "Singleton objects (like ResultBean) cannot be marshaled" do
48
+ expect { Marshal.dump(object) }.to raise_error TypeError
49
+ end
50
+ end
51
+ context "Basic Operations without marshaling " do
52
+ before :each do
53
+ @obj = object
54
+ end
55
+ it_behaves_like "retains initialization options"
56
+ it_behaves_like "ruby pojo"
57
+ end
58
+ context "Basic Operations after Yaml marshaling " do
59
+ before :each do
60
+ dmp = YAML::dump(object)
61
+ @obj = YAML::load(dmp)
62
+ end
63
+ it_behaves_like "retains initialization options"
64
+ it_behaves_like "ruby pojo"
65
+ end
66
+ context "ResultBeans stripped of their internal singleton accessors can be Marshaled! " do
67
+ before :each do
68
+ dmp = YAML::dump(object)
69
+ obj = YAML::load(dmp) # Yaml'ing removes singleton accessor methods'
70
+ # by initializing object without using its
71
+ # initialize() method
72
+
73
+ dmp = Marshal.dump(obj) # Now Marshal load/dump will work
74
+ @obj = Marshal.load(dmp) # Use GenericBean if Marshal support is needed
75
+ end
76
+ it_behaves_like "retains initialization options"
77
+ it_behaves_like "ruby pojo"
78
+ end
79
+ context "Basic Operations after Yaml marshaling via restored accessors " do
80
+ before :each do
81
+ dmp = YAML::dump(object)
82
+ @obj = YAML::load(dmp)
83
+ # Restore setters
84
+ @obj.attributes.keys.each do |k|
85
+ @obj.singleton_class.send(:attr_accessor, k)
86
+ end
87
+ end
88
+ it_behaves_like "retains initialization options"
89
+ it_behaves_like "ruby pojo"
90
+ end
91
+
92
+ end
@@ -0,0 +1,178 @@
1
+ ##
2
+ # spec/lib/skn_utils/result_bean_with_errors_spec.rb
3
+ #
4
+
5
+ RSpec.describe SknUtils::ResultBeanWithErrors, "Result Bean class with ActiveModel::Errors object " do
6
+ let(:object) {
7
+ SknUtils::ResultBeanWithErrors.new({one: "one",
8
+ two: "two",
9
+ three: {four: 4, five: 5, six: {seven: 7, eight: "eight" }},
10
+ four: {any_key: "any value"},
11
+ five: []
12
+ })
13
+ }
14
+
15
+ context "Internal Operations, assuming :dept => :multi and enable_serialization => false" do
16
+ it "Creates an empty bean if no params are passed" do
17
+ is_expected.to be
18
+ expect(subject.errors).to be
19
+ end
20
+ it "Initializes from a hash that DOES NOT include an errors.object " do
21
+ expect(SknUtils::ResultBeanWithErrors.new({one: "one", two: "two"})).to be
22
+ end
23
+ it "Initializes from a hash that DOES include an errors.object " do
24
+ errors = ActiveModel::Errors.new(self) ## VERY BAD IDEAL
25
+ expect(SknUtils::ResultBeanWithErrors.new({one: "one", two: "two", errors: errors})).to be
26
+ end
27
+ it "Does not modify the base class, only singleton instance methods" do
28
+ obj1 = SknUtils::ResultBeanWithErrors.new({one: "one", two: "two"})
29
+ obj2 = SknUtils::ResultBeanWithErrors.new({three: "3", four: "4"})
30
+ expect(obj1.one).to eql "one"
31
+ expect(obj2.three).to eql "3"
32
+ expect(obj2.one?).to be_falsey
33
+ expect(obj1.three?).to be_falsey
34
+ expect { obj1.three }.to raise_error NoMethodError
35
+ expect { obj2.one }.to raise_error NoMethodError
36
+ end
37
+ it "Supports - respond_to - methods, because it has accessor methods" do
38
+ expect(object).to respond_to(:one)
39
+ end
40
+ end
41
+
42
+ shared_examples_for "retains initialization options" do
43
+ it "retains depth_level option flag" do
44
+ expect(@obj.depth_level).to eql(:multi)
45
+ end
46
+ it "retains serialization option flag" do
47
+ expect(@obj.serialization_required?).to be false
48
+ end
49
+ end
50
+
51
+ context "ActiveModel:Errors object" do
52
+ it "#errors method returns an ActiveModel::Errors object" do
53
+ obj = SknUtils::ResultBeanWithErrors.new({one: "one", two: "two"})
54
+ expect(obj.errors).to be_an_instance_of(ActiveModel::Errors)
55
+ end
56
+
57
+ it "#errors method accepts additional errors" do
58
+ obj = SknUtils::ResultBeanWithErrors.new({one: "one", two: "two"})
59
+ obj.errors.add(:one,"must be numeric.")
60
+ expect(obj.errors.size).to be 1
61
+ end
62
+
63
+ it "#errors.full_messages method returns messages" do
64
+ obj = SknUtils::ResultBeanWithErrors.new({one: "one", two: "two"})
65
+ obj.errors.add(:one,"must be numeric.")
66
+ expect(obj.errors.full_messages.first).to include("numeric")
67
+ end
68
+
69
+ it "#errors.add_on_empty method correctly adds new errors" do
70
+ obj = SknUtils::ResultBeanWithErrors.new({one: "one", two: ""})
71
+ obj.errors.add_on_empty(:two)
72
+ expect(obj.errors.count).to be 1
73
+ end
74
+
75
+ it "#errors.add_on_blank method correctly adds new errors" do
76
+ obj = SknUtils::ResultBeanWithErrors.new({one: "one", two: ""})
77
+ obj.errors.add_on_blank(:two)
78
+ expect(obj.errors.count).to be 1
79
+ end
80
+
81
+ it "#errors.get method correctly retrieves existing message by attribute" do
82
+ obj = SknUtils::ResultBeanWithErrors.new({one: "one", two: ""})
83
+ obj.errors.add_on_blank(:two)
84
+ expect(obj.errors.get(:two).first).to include("blank")
85
+ end
86
+
87
+ it "#errors[] method correctly retrieves existing message by attribute" do
88
+ obj = SknUtils::ResultBeanWithErrors.new({one: "one", two: ""})
89
+ obj.errors.add_on_blank(:two)
90
+ expect(obj.errors[:two].first).to include("blank")
91
+ end
92
+
93
+ it "#errors.set method correctly adds sets message on attribute" do
94
+ obj = SknUtils::ResultBeanWithErrors.new({one: "one", two: ""})
95
+ obj.errors.set(:two, "Required value, must not be empty")
96
+ expect(obj.errors.get(:two)).to include("Required")
97
+ end
98
+
99
+ it "#errors.include? method correctly determines that an error exists for the given key" do
100
+ obj = SknUtils::ResultBeanWithErrors.new({one: "one", two: ""})
101
+ obj.errors.add(:two, "Required value, must not be empty")
102
+ result = obj.errors.include?(:two)
103
+ expect(result).to be_truthy
104
+ result = obj.errors.include?(:one)
105
+ expect(result).to be_falsey
106
+ end
107
+
108
+ it "#errors.delete method correctly removes an error for the given key" do
109
+ obj = SknUtils::ResultBeanWithErrors.new({one: "one", two: ""})
110
+ obj.errors.add(:two, "Required value, must not be empty")
111
+ result = obj.errors.include?(:two)
112
+ expect(result).to be_truthy
113
+ obj.errors.delete(:two)
114
+ result = obj.errors.include?(:two)
115
+ expect(result).to be_falsey
116
+ end
117
+ end
118
+
119
+ context "Serialization" do
120
+ before :each do
121
+ @obj = object
122
+ end
123
+ it "Serialization does not include the errors object." do
124
+ expect(@obj.to_hash[:errors]).not_to be
125
+ expect(@obj.errors).to be_a(ActiveModel::Errors)
126
+ end
127
+
128
+ it_behaves_like "retains initialization options"
129
+ it_behaves_like "ruby pojo"
130
+ end
131
+
132
+ context "Basic Operations after Marshal marshaling " do
133
+ it "Singleton objects (like ResultBean) cannot be marshaled" do
134
+ expect { Marshal.dump(object) }.to raise_error TypeError
135
+ end
136
+ end
137
+ context "Basic Operations without marshaling " do
138
+ before :each do
139
+ @obj = object
140
+ end
141
+ it_behaves_like "retains initialization options"
142
+ it_behaves_like "ruby pojo"
143
+ end
144
+ context "Basic Operations after Yaml marshaling " do
145
+ before :each do
146
+ dmp = YAML::dump(object)
147
+ @obj = YAML::load(dmp)
148
+ end
149
+ it_behaves_like "retains initialization options"
150
+ it_behaves_like "ruby pojo"
151
+ end
152
+ context "ResultBeans stripped of their internal singleton accessors can be Marshaled! " do
153
+ before :each do
154
+ dmp = YAML::dump(object)
155
+ obj = YAML::load(dmp) # Yaml'ing removes singleton accessor methods'
156
+ # by initializing object without using its
157
+ # initialize() method
158
+
159
+ dmp = Marshal.dump(obj) # Now Marshal load/dump will work
160
+ @obj = Marshal.load(dmp) # Use GenericBean if Marshal support is needed
161
+ end
162
+ it_behaves_like "retains initialization options"
163
+ it_behaves_like "ruby pojo"
164
+ end
165
+ context "Basic Operations after Yaml marshaling via restored accessors " do
166
+ before :each do
167
+ dmp = YAML::dump(object)
168
+ @obj = YAML::load(dmp)
169
+ # Restore setters
170
+ @obj.attributes.keys.each do |k|
171
+ @obj.singleton_class.send(:attr_accessor, k)
172
+ end
173
+ end
174
+ it_behaves_like "retains initialization options"
175
+ it_behaves_like "ruby pojo"
176
+ end
177
+
178
+ end
@@ -0,0 +1,39 @@
1
+ ENV['RAILS_ENV'] ||= 'test'
2
+
3
+ require 'active_model'
4
+ require 'skn_utils'
5
+ require 'rspec'
6
+
7
+ # Shared Examples and Support Routines
8
+ Dir["./spec/support/**/*.rb"].sort.each { |f| require f}
9
+
10
+ # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
11
+ RSpec.configure do |config|
12
+ Kernel.srand config.seed
13
+
14
+ config.order = :random
15
+ config.color = true
16
+ config.tty = false
17
+ config.formatter = :progress #:html, :textmate, :documentation
18
+
19
+ config.filter_run :focus
20
+ config.run_all_when_everything_filtered = true
21
+
22
+ config.disable_monkey_patching! # -- breaks rspec runtime
23
+ config.warnings = true
24
+ # config.profile_examples = 10
25
+
26
+ if config.files_to_run.one?
27
+ config.formatter = :documentation
28
+ end
29
+
30
+ config.expect_with :rspec do |expectations|
31
+ expectations.include_chain_clauses_in_custom_matcher_descriptions = true
32
+ expectations.syntax = :expect
33
+ end
34
+
35
+ config.mock_with :rspec do |mocks|
36
+ mocks.verify_partial_doubles = true
37
+ end
38
+
39
+ end
@@ -0,0 +1,55 @@
1
+ ##
2
+ # <root>/spec/support/shared_example_marshalable_ruby_pojo.rb
3
+ #
4
+ # refs: page_controls, generic_bean
5
+ #
6
+
7
+ RSpec.shared_examples "marshalable ruby pojo" do
8
+ it "provides getters" do
9
+ expect(@obj.one).to be_eql("one")
10
+ expect(@obj.two).to be_eql("two")
11
+ end
12
+ it "provides setters" do
13
+ @obj.one = "1"
14
+ @obj.two = "2"
15
+ expect(@obj.two).to be_eql("2")
16
+ expect(@obj.one).to be_eql("1")
17
+ end
18
+ it "#clear_attribute sets given attribute to nil." do
19
+ expect(@obj.two).to be_eql("two")
20
+ expect(@obj.clear_two).to be_nil
21
+ end
22
+ it "#attribute? returns true or false based on contents of attribute." do
23
+ expect(@obj.two?).to be true
24
+ @obj.two = false
25
+ expect(@obj.two?).to be false
26
+ @obj.clear_two
27
+ expect(@obj.two?).to be false
28
+ expect(@obj.three?).to be true
29
+ expect(@obj.four?).to be true
30
+ @obj.clear_three
31
+ expect(@obj.three?).to be false
32
+ @obj.clear_four
33
+ expect(@obj.four?).to be false
34
+ end
35
+ it "#attribute? returns false when attribute is not defined or unknown" do
36
+ expect(@obj.address?).to be false
37
+ end
38
+ it "raises an 'NoMethodError' error when attribute does not exist" do
39
+ expect { @obj.address }.to raise_error NoMethodError
40
+ end
41
+ context "transformations are enabled with " do
42
+ it "#to_json method returns a serialized version of this object." do
43
+ expect(object.to_json).to include(":\"")
44
+ end
45
+ it "#to_xml method returns a serialized version of this object." do
46
+ expect(object.to_xml).to include("xml version")
47
+ end
48
+ it "#to_hash method returns a serialized version of this object." do
49
+ expect(object.to_hash).to be_a(Hash)
50
+ end
51
+ it "#attributes method returns original input hash." do
52
+ expect(object.attributes).to be_a(Hash)
53
+ end
54
+ end
55
+ end