flex_columns 1.0.0
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 +7 -0
- data/.gitignore +18 -0
- data/.travis.yml +38 -0
- data/Gemfile +17 -0
- data/LICENSE.txt +22 -0
- data/README.md +124 -0
- data/Rakefile +6 -0
- data/flex_columns.gemspec +72 -0
- data/lib/flex_columns.rb +15 -0
- data/lib/flex_columns/active_record/base.rb +57 -0
- data/lib/flex_columns/contents/column_data.rb +376 -0
- data/lib/flex_columns/contents/flex_column_contents_base.rb +188 -0
- data/lib/flex_columns/definition/field_definition.rb +316 -0
- data/lib/flex_columns/definition/field_set.rb +89 -0
- data/lib/flex_columns/definition/flex_column_contents_class.rb +327 -0
- data/lib/flex_columns/errors.rb +236 -0
- data/lib/flex_columns/has_flex_columns.rb +187 -0
- data/lib/flex_columns/including/include_flex_columns.rb +179 -0
- data/lib/flex_columns/util/dynamic_methods_module.rb +86 -0
- data/lib/flex_columns/util/string_utils.rb +31 -0
- data/lib/flex_columns/version.rb +4 -0
- data/spec/flex_columns/helpers/database_helper.rb +174 -0
- data/spec/flex_columns/helpers/exception_helpers.rb +20 -0
- data/spec/flex_columns/helpers/system_helpers.rb +47 -0
- data/spec/flex_columns/system/basic_system_spec.rb +245 -0
- data/spec/flex_columns/system/bulk_system_spec.rb +153 -0
- data/spec/flex_columns/system/compression_system_spec.rb +218 -0
- data/spec/flex_columns/system/custom_methods_system_spec.rb +120 -0
- data/spec/flex_columns/system/delegation_system_spec.rb +175 -0
- data/spec/flex_columns/system/dynamism_system_spec.rb +158 -0
- data/spec/flex_columns/system/error_handling_system_spec.rb +117 -0
- data/spec/flex_columns/system/including_system_spec.rb +285 -0
- data/spec/flex_columns/system/json_alias_system_spec.rb +171 -0
- data/spec/flex_columns/system/performance_system_spec.rb +218 -0
- data/spec/flex_columns/system/postgres_json_column_type_system_spec.rb +85 -0
- data/spec/flex_columns/system/types_system_spec.rb +93 -0
- data/spec/flex_columns/system/unknown_fields_system_spec.rb +126 -0
- data/spec/flex_columns/system/validations_system_spec.rb +111 -0
- data/spec/flex_columns/unit/active_record/base_spec.rb +32 -0
- data/spec/flex_columns/unit/contents/column_data_spec.rb +520 -0
- data/spec/flex_columns/unit/contents/flex_column_contents_base_spec.rb +253 -0
- data/spec/flex_columns/unit/definition/field_definition_spec.rb +617 -0
- data/spec/flex_columns/unit/definition/field_set_spec.rb +142 -0
- data/spec/flex_columns/unit/definition/flex_column_contents_class_spec.rb +733 -0
- data/spec/flex_columns/unit/errors_spec.rb +297 -0
- data/spec/flex_columns/unit/has_flex_columns_spec.rb +365 -0
- data/spec/flex_columns/unit/including/include_flex_columns_spec.rb +144 -0
- data/spec/flex_columns/unit/util/dynamic_methods_module_spec.rb +105 -0
- data/spec/flex_columns/unit/util/string_utils_spec.rb +23 -0
- metadata +286 -0
@@ -0,0 +1,153 @@
|
|
1
|
+
require 'flex_columns'
|
2
|
+
require 'flex_columns/helpers/system_helpers'
|
3
|
+
|
4
|
+
describe "FlexColumns bulk operations" do
|
5
|
+
include FlexColumns::Helpers::SystemHelpers
|
6
|
+
|
7
|
+
before :each do
|
8
|
+
@dh = FlexColumns::Helpers::DatabaseHelper.new
|
9
|
+
@dh.setup_activerecord!
|
10
|
+
|
11
|
+
create_standard_system_spec_tables!
|
12
|
+
end
|
13
|
+
|
14
|
+
after :each do
|
15
|
+
drop_standard_system_spec_tables!
|
16
|
+
end
|
17
|
+
|
18
|
+
before :each do
|
19
|
+
define_model_class(:User, 'flexcols_spec_users') do
|
20
|
+
flex_column :user_attributes do
|
21
|
+
field :aaa, :string
|
22
|
+
field :bbb, :integer
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
it "should return #to_stored_data correctly on a text column, and return the exact same thing for #to_json" do
|
28
|
+
user = ::User.new
|
29
|
+
user.name = "User 1"
|
30
|
+
user.aaa = "aaa#{rand(1_000_000)}"
|
31
|
+
user.bbb = rand(1_000_000)
|
32
|
+
|
33
|
+
json = user.user_attributes.to_stored_data
|
34
|
+
json.class.should be(String)
|
35
|
+
|
36
|
+
parsed = JSON.parse(json)
|
37
|
+
parsed.keys.sort.should == %w{aaa bbb}.sort
|
38
|
+
parsed['aaa'].should == user.aaa
|
39
|
+
|
40
|
+
user.user_attributes.to_json.should == json
|
41
|
+
end
|
42
|
+
|
43
|
+
context "with a binary column" do
|
44
|
+
before :each do
|
45
|
+
migrate do
|
46
|
+
drop_table :flexcols_spec_users rescue nil
|
47
|
+
create_table :flexcols_spec_users do |t|
|
48
|
+
t.string :name, :null => false
|
49
|
+
t.binary :user_attributes
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
::User.reset_column_information
|
54
|
+
|
55
|
+
define_model_class(:User, 'flexcols_spec_users') do
|
56
|
+
flex_column :user_attributes do
|
57
|
+
field :aaa, :string
|
58
|
+
field :bbb, :integer
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
it "should return #to_stored_data correctly on a binary column, uncompressed, but return JSON separately with #to_json" do
|
64
|
+
user = ::User.new
|
65
|
+
user.name = "User 1"
|
66
|
+
user.aaa = "aaa#{rand(1_000_000)}"
|
67
|
+
user.bbb = rand(1_000_000)
|
68
|
+
|
69
|
+
stored_data = user.user_attributes.to_stored_data
|
70
|
+
stored_data.class.should be(String)
|
71
|
+
stored_data.should match(/^FC:01,0,/)
|
72
|
+
|
73
|
+
stored_data =~ /^FC:01,0,(.*)$/i
|
74
|
+
json = $1
|
75
|
+
parsed = JSON.parse(json)
|
76
|
+
parsed.keys.sort.should == %w{aaa bbb}.sort
|
77
|
+
parsed['aaa'].should == user.aaa
|
78
|
+
|
79
|
+
user.user_attributes.to_json.should == json
|
80
|
+
end
|
81
|
+
|
82
|
+
it "should return #to_stored_data correctly on a binary column, compressed, but return JSON separately with #to_json" do
|
83
|
+
user = ::User.new
|
84
|
+
user.name = "User 1"
|
85
|
+
user.aaa = "aaa#{rand(1_000_000)}" * 1_000
|
86
|
+
user.bbb = rand(1_000_000)
|
87
|
+
|
88
|
+
stored_data = user.user_attributes.to_stored_data
|
89
|
+
stored_data.class.should be(String)
|
90
|
+
stored_data.should match(/^FC:01,1,/)
|
91
|
+
|
92
|
+
compressed = stored_data[8..-1]
|
93
|
+
|
94
|
+
require 'stringio'
|
95
|
+
stream = StringIO.new(compressed, "r")
|
96
|
+
reader = Zlib::GzipReader.new(stream)
|
97
|
+
json = reader.read
|
98
|
+
|
99
|
+
parsed = JSON.parse(json)
|
100
|
+
parsed.keys.sort.should == %w{aaa bbb}.sort
|
101
|
+
parsed['aaa'].should == user.aaa
|
102
|
+
|
103
|
+
user.user_attributes.to_json.should == json
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
it "should be able to instantiate fields without an ActiveRecord model, and then serialize them again" do
|
108
|
+
users = [ ]
|
109
|
+
10.times do |i|
|
110
|
+
user = ::User.new
|
111
|
+
user.name = "User #{i}"
|
112
|
+
user.aaa = "aaa#{rand(1_000_000)}"
|
113
|
+
user.bbb = rand(1_000_000)
|
114
|
+
user.save!
|
115
|
+
|
116
|
+
users << user
|
117
|
+
end
|
118
|
+
|
119
|
+
json_blobs = [ ]
|
120
|
+
::User.connection.select_all("SELECT id, user_attributes FROM flexcols_spec_users ORDER BY id ASC").each do |row|
|
121
|
+
json_blobs << row['user_attributes']
|
122
|
+
end
|
123
|
+
|
124
|
+
as_objects = ::User.create_flex_objects_from(:user_attributes, json_blobs)
|
125
|
+
as_objects.each_with_index do |object, i|
|
126
|
+
user = users[i]
|
127
|
+
|
128
|
+
object.aaa.should == user.aaa
|
129
|
+
object.bbb.should == user.bbb
|
130
|
+
|
131
|
+
object.bbb = "cannot-validate"
|
132
|
+
object.valid?.should_not be
|
133
|
+
object.errors.keys.should == [ :bbb ]
|
134
|
+
object.errors[:bbb].length.should == 1
|
135
|
+
object.errors[:bbb][0].should match(/is not a number/i)
|
136
|
+
end
|
137
|
+
|
138
|
+
json_blobs.each_with_index do |json_blob, i|
|
139
|
+
object = ::User.create_flex_object_from(:user_attributes, json_blob)
|
140
|
+
|
141
|
+
user = users[i]
|
142
|
+
|
143
|
+
object.aaa.should == user.aaa
|
144
|
+
object.bbb.should == user.bbb
|
145
|
+
|
146
|
+
object.bbb = "cannot-validate"
|
147
|
+
object.valid?.should_not be
|
148
|
+
object.errors.keys.should == [ :bbb ]
|
149
|
+
object.errors[:bbb].length.should == 1
|
150
|
+
object.errors[:bbb][0].should match(/is not a number/i)
|
151
|
+
end
|
152
|
+
end
|
153
|
+
end
|
@@ -0,0 +1,218 @@
|
|
1
|
+
require 'flex_columns'
|
2
|
+
require 'flex_columns/helpers/system_helpers'
|
3
|
+
|
4
|
+
describe "FlexColumns compression operations" do
|
5
|
+
include FlexColumns::Helpers::SystemHelpers
|
6
|
+
|
7
|
+
before :each do
|
8
|
+
@dh = FlexColumns::Helpers::DatabaseHelper.new
|
9
|
+
@dh.setup_activerecord!
|
10
|
+
|
11
|
+
migrate do
|
12
|
+
drop_table :flexcols_spec_users rescue nil
|
13
|
+
create_table :flexcols_spec_users do |t|
|
14
|
+
t.string :name, :null => false
|
15
|
+
t.binary :user_attributes
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
define_model_class(:User, 'flexcols_spec_users') do
|
20
|
+
flex_column :user_attributes do
|
21
|
+
field :foo
|
22
|
+
field :bar
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
define_model_class(:UserBackdoor, 'flexcols_spec_users') { }
|
27
|
+
end
|
28
|
+
|
29
|
+
after :each do
|
30
|
+
migrate do
|
31
|
+
drop_table :flexcols_spec_users rescue nil
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
it "should not add a header, and should not compress data, if passed :header => false" do
|
36
|
+
define_model_class(:User, 'flexcols_spec_users') do
|
37
|
+
flex_column :user_attributes, :header => false do
|
38
|
+
field :foo
|
39
|
+
field :bar
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
user = ::User.new
|
44
|
+
user.name = 'User 1'
|
45
|
+
user.foo = "foo1"
|
46
|
+
user.bar = "bar1"
|
47
|
+
user.save!
|
48
|
+
|
49
|
+
user_bd = ::UserBackdoor.find(user.id)
|
50
|
+
data = user_bd.user_attributes
|
51
|
+
parsed = JSON.parse(data)
|
52
|
+
parsed.keys.sort.should == %w{foo bar}.sort
|
53
|
+
|
54
|
+
user = ::User.new
|
55
|
+
user.name = 'User 1'
|
56
|
+
user.foo = "foo" * 10_000
|
57
|
+
user.bar = "bar1"
|
58
|
+
user.save!
|
59
|
+
|
60
|
+
user_bd = ::UserBackdoor.find(user.id)
|
61
|
+
data = user_bd.user_attributes
|
62
|
+
data.length.should > 30_000
|
63
|
+
parsed = JSON.parse(data)
|
64
|
+
parsed.keys.sort.should == %w{foo bar}.sort
|
65
|
+
end
|
66
|
+
|
67
|
+
it "should not compress short data" do
|
68
|
+
user = ::User.new
|
69
|
+
user.name = 'User 1'
|
70
|
+
user.foo = 'foo1'
|
71
|
+
user.bar = 'bar1'
|
72
|
+
user.save!
|
73
|
+
|
74
|
+
user_again = ::User.find(user.id)
|
75
|
+
user_again.foo.should == 'foo1'
|
76
|
+
user_again.bar.should == 'bar1'
|
77
|
+
|
78
|
+
user_bd = ::UserBackdoor.find(user.id)
|
79
|
+
data = user_bd.user_attributes
|
80
|
+
data.should match(/foo1/)
|
81
|
+
data.should match(/bar1/)
|
82
|
+
end
|
83
|
+
|
84
|
+
it "should compress long data" do
|
85
|
+
user = ::User.new
|
86
|
+
user.name = 'User 1'
|
87
|
+
user.foo = 'foo' * 1000
|
88
|
+
user.bar = 'bar1'
|
89
|
+
user.save!
|
90
|
+
|
91
|
+
user_again = ::User.find(user.id)
|
92
|
+
user_again.foo.should == 'foo' * 1000
|
93
|
+
user_again.bar.should == 'bar1'
|
94
|
+
|
95
|
+
user_bd = ::UserBackdoor.find(user.id)
|
96
|
+
data = user_bd.user_attributes
|
97
|
+
data.length.should < 1000
|
98
|
+
data.should_not match(/foo/)
|
99
|
+
data.should_not match(/bar/)
|
100
|
+
end
|
101
|
+
|
102
|
+
it "should read compressed data fine, even if told not to compress new data" do
|
103
|
+
user = ::User.new
|
104
|
+
user.name = 'User 1'
|
105
|
+
user.foo = 'foo' * 1000
|
106
|
+
user.bar = 'bar1'
|
107
|
+
user.save!
|
108
|
+
|
109
|
+
user_again = ::User.find(user.id)
|
110
|
+
user_again.foo.should == 'foo' * 1000
|
111
|
+
user_again.bar.should == 'bar1'
|
112
|
+
|
113
|
+
user_bd = ::UserBackdoor.find(user.id)
|
114
|
+
data = user_bd.user_attributes
|
115
|
+
data.length.should < 1000
|
116
|
+
data.should_not match(/foo/)
|
117
|
+
data.should_not match(/bar/)
|
118
|
+
|
119
|
+
define_model_class(:User2, 'flexcols_spec_users') do
|
120
|
+
flex_column :user_attributes, :compress => false do
|
121
|
+
field :foo
|
122
|
+
field :bar
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
user2 = ::User2.find(user.id)
|
127
|
+
user.foo.should == 'foo' * 1000
|
128
|
+
user.bar.should == 'bar1'
|
129
|
+
end
|
130
|
+
|
131
|
+
it "should not compress long data, if asked not to" do
|
132
|
+
define_model_class(:User, 'flexcols_spec_users') do
|
133
|
+
flex_column :user_attributes, :compress => false do
|
134
|
+
field :foo
|
135
|
+
field :bar
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
user = ::User.new
|
140
|
+
user.name = 'User 1'
|
141
|
+
user.foo = 'foo' * 1000
|
142
|
+
user.bar = 'bar1'
|
143
|
+
user.save!
|
144
|
+
|
145
|
+
user_again = ::User.find(user.id)
|
146
|
+
user_again.foo.should == 'foo' * 1000
|
147
|
+
user_again.bar.should == 'bar1'
|
148
|
+
|
149
|
+
user_bd = ::UserBackdoor.find(user.id)
|
150
|
+
data = user_bd.user_attributes
|
151
|
+
data.length.should >= 3000
|
152
|
+
data.should match(/foofoofoofoo/)
|
153
|
+
data.should match(/bar1/)
|
154
|
+
end
|
155
|
+
|
156
|
+
it "should not compress data if the compressed version is bigger" do
|
157
|
+
define_model_class(:User, 'flexcols_spec_users') do
|
158
|
+
flex_column :user_attributes, :compress => 1 do
|
159
|
+
field :foo
|
160
|
+
field :bar
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
164
|
+
user = ::User.new
|
165
|
+
user.name = 'User 1'
|
166
|
+
user.foo = 'f'
|
167
|
+
user.save!
|
168
|
+
|
169
|
+
user_again = ::User.find(user.id)
|
170
|
+
user_again.foo.should == 'f'
|
171
|
+
user_again.bar.should be_nil
|
172
|
+
|
173
|
+
user_bd = ::UserBackdoor.find(user.id)
|
174
|
+
data = user_bd.user_attributes
|
175
|
+
data.should match(/^FC:01,0,\{/i)
|
176
|
+
end
|
177
|
+
|
178
|
+
it "should not compress data under a certain limit, if asked to" do
|
179
|
+
define_model_class(:User, 'flexcols_spec_users') do
|
180
|
+
flex_column :user_attributes, :compress => 10_000 do
|
181
|
+
field :foo
|
182
|
+
field :bar
|
183
|
+
end
|
184
|
+
end
|
185
|
+
|
186
|
+
user = ::User.new
|
187
|
+
user.name = 'User 1'
|
188
|
+
user.foo = 'foo' * 1000
|
189
|
+
user.bar = 'bar1'
|
190
|
+
user.save!
|
191
|
+
|
192
|
+
user_again = ::User.find(user.id)
|
193
|
+
user_again.foo.should == 'foo' * 1000
|
194
|
+
user_again.bar.should == 'bar1'
|
195
|
+
|
196
|
+
user_bd = ::UserBackdoor.find(user.id)
|
197
|
+
data = user_bd.user_attributes
|
198
|
+
data.length.should >= 3000
|
199
|
+
data.should match(/foofoofoofoo/)
|
200
|
+
data.should match(/bar1/)
|
201
|
+
|
202
|
+
user2 = ::User.new
|
203
|
+
user2.name = 'User 1'
|
204
|
+
user2.foo = 'foo' * 10_000
|
205
|
+
user2.bar = 'bar1'
|
206
|
+
user2.save!
|
207
|
+
|
208
|
+
user2_again = ::User.find(user2.id)
|
209
|
+
user2_again.foo.should == 'foo' * 10_000
|
210
|
+
user2_again.bar.should == 'bar1'
|
211
|
+
|
212
|
+
user2_bd = ::UserBackdoor.find(user2.id)
|
213
|
+
data = user2_bd.user_attributes
|
214
|
+
data.length.should < 10_000
|
215
|
+
data.should_not match(/foofoofoofoo/)
|
216
|
+
data.should_not match(/bar1/)
|
217
|
+
end
|
218
|
+
end
|
@@ -0,0 +1,120 @@
|
|
1
|
+
require 'flex_columns'
|
2
|
+
require 'flex_columns/helpers/system_helpers'
|
3
|
+
|
4
|
+
describe "FlexColumns custom-methods operations" do
|
5
|
+
include FlexColumns::Helpers::SystemHelpers
|
6
|
+
|
7
|
+
before :each do
|
8
|
+
@dh = FlexColumns::Helpers::DatabaseHelper.new
|
9
|
+
@dh.setup_activerecord!
|
10
|
+
|
11
|
+
create_standard_system_spec_tables!
|
12
|
+
end
|
13
|
+
|
14
|
+
after :each do
|
15
|
+
drop_standard_system_spec_tables!
|
16
|
+
end
|
17
|
+
|
18
|
+
it "should allow defining methods that are present on both the attributes class and the enclosing class" do
|
19
|
+
define_model_class(:User, 'flexcols_spec_users') do
|
20
|
+
flex_column :user_attributes do
|
21
|
+
field :number_of_emails_sent
|
22
|
+
|
23
|
+
def increment_number_of_emails_sent
|
24
|
+
self.number_of_emails_sent += 1
|
25
|
+
end
|
26
|
+
|
27
|
+
def change_number_of_emails_sent(return_value)
|
28
|
+
self.number_of_emails_sent = yield number_of_emails_sent
|
29
|
+
return_value
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
user = ::User.new
|
35
|
+
user.name = 'User 1'
|
36
|
+
|
37
|
+
user.user_attributes.number_of_emails_sent = 15
|
38
|
+
user.user_attributes.increment_number_of_emails_sent
|
39
|
+
user.user_attributes.number_of_emails_sent.should == 16
|
40
|
+
(user.user_attributes.change_number_of_emails_sent('abc') { |x| x - 5 }).should == 'abc'
|
41
|
+
user.user_attributes.number_of_emails_sent.should == 11
|
42
|
+
|
43
|
+
user.number_of_emails_sent.should == 11
|
44
|
+
user.increment_number_of_emails_sent
|
45
|
+
user.number_of_emails_sent.should == 12
|
46
|
+
(user.change_number_of_emails_sent('abc') { |x| x - 5 }).should == 'abc'
|
47
|
+
user.number_of_emails_sent.should == 7
|
48
|
+
end
|
49
|
+
|
50
|
+
it "should not delegate methods if told not to" do
|
51
|
+
define_model_class(:User, 'flexcols_spec_users') do
|
52
|
+
flex_column :user_attributes, :delegate => false do
|
53
|
+
field :number_of_emails_sent
|
54
|
+
|
55
|
+
def increment_number_of_emails_sent
|
56
|
+
self.number_of_emails_sent += 1
|
57
|
+
end
|
58
|
+
|
59
|
+
def change_number_of_emails_sent(return_value)
|
60
|
+
self.number_of_emails_sent = yield number_of_emails_sent
|
61
|
+
return_value
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
user = ::User.new
|
67
|
+
user.name = 'User 1'
|
68
|
+
|
69
|
+
user.respond_to?(:number_of_emails_sent).should_not be
|
70
|
+
user.respond_to?(:increment_number_of_emails_sent).should_not be
|
71
|
+
user.respond_to?(:change_number_of_emails_sent).should_not be
|
72
|
+
end
|
73
|
+
|
74
|
+
it "should delegate methods privately if told to" do
|
75
|
+
define_model_class(:User, 'flexcols_spec_users') do
|
76
|
+
flex_column :user_attributes, :delegate => :private do
|
77
|
+
field :number_of_emails_sent
|
78
|
+
|
79
|
+
def increment_number_of_emails_sent
|
80
|
+
self.number_of_emails_sent += 1
|
81
|
+
end
|
82
|
+
|
83
|
+
def change_number_of_emails_sent(return_value)
|
84
|
+
self.number_of_emails_sent = yield number_of_emails_sent
|
85
|
+
return_value
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
def nes=(x)
|
90
|
+
self.number_of_emails_sent = x
|
91
|
+
end
|
92
|
+
|
93
|
+
def nes
|
94
|
+
number_of_emails_sent
|
95
|
+
end
|
96
|
+
|
97
|
+
def ies
|
98
|
+
increment_number_of_emails_sent
|
99
|
+
end
|
100
|
+
|
101
|
+
def cnes(rv, &block)
|
102
|
+
change_number_of_emails_sent(rv, &block)
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
user = ::User.new
|
107
|
+
user.name = 'User 1'
|
108
|
+
|
109
|
+
user.respond_to?(:number_of_emails_sent).should_not be
|
110
|
+
user.respond_to?(:increment_number_of_emails_sent).should_not be
|
111
|
+
user.respond_to?(:change_number_of_emails_sent).should_not be
|
112
|
+
|
113
|
+
user.nes = 10
|
114
|
+
user.nes.should == 10
|
115
|
+
user.ies
|
116
|
+
user.nes.should == 11
|
117
|
+
(user.cnes('abc') { |x| x - 5 }).should == 'abc'
|
118
|
+
user.nes.should == 6
|
119
|
+
end
|
120
|
+
end
|