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