flex_columns 1.0.6 → 1.0.7

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA512:
3
- metadata.gz: a346cd4387b83db2754cd6d18db49a616015ca230a0b18134f0a7176b4f206778a7f778cec4b97e84c59dfb0358339a2106b1e8656be922a54b2d0143867b1da
4
- data.tar.gz: bebc4830bc2ea67bfa2152cca4587d751dd13da67c4afe22ea288e4522079510aaf2aa42b32fbff72a6b2af4c930ada099fafadb063cb384bb84f30c1a3c05c4
5
2
  SHA1:
6
- metadata.gz: e57b169cbe90447775b3f4b0bf2c6e843825bb12
7
- data.tar.gz: 314c670ba146241547f561a3354cf8473509f1be
3
+ metadata.gz: d883b205cd22c7aa6a6bda071d3ca52c7084e14e
4
+ data.tar.gz: 88057e546d40a01a83ba499f0c9c4d4c5b0863af
5
+ SHA512:
6
+ metadata.gz: 040c456a7527585100159b68e0b1685e590fb30a75f1388107773de1501a6699d8b7903f891ccbc0b0e0f5a7cb44b647d734cf5e65279185723129580cb6f4be
7
+ data.tar.gz: 951bfb6887b746545fcc7d5b8036d9a1efa5bdc31369e1b68fddfcf1bc482b10464d5f11a2d43cb4135ac9e140471cb5490ddee61e8ff41730e4fa03c0f82bb2
data/CHANGES.md CHANGED
@@ -1,5 +1,9 @@
1
1
  # `flex_columns` Changelog
2
2
 
3
+ ## 1.0.7, 2014-04-07
4
+
5
+ * Fixed an issue where, if you defined a model class when its table didn't exist, and then created its table while the Ruby process was still running, you still couldn't access any flex-column attributes — because we would simply skip defining them entirely if the table didn't exist. Now, we define them, assuming the columns exist and are of type `:string` (and `null`able) if the table doesn't exist, and replace them with the actual column definition once the table exists. (You need to call `.reset_column_information` on the model class to make this happen, just as you do with any changes to the underlying table of an ActiveRecord model.)
6
+
3
7
  ## 1.0.6, 2014-04-07
4
8
 
5
9
  * Fixed an issue where Float::INFINITY and Float::NaN could not be stored in a flex column.
data/README.md CHANGED
@@ -110,13 +110,13 @@ As a snapshot of all possibilities:
110
110
  There's lots more, too:
111
111
 
112
112
  * Complete validations support: the flex-column object includes ActiveModel::Validations, so every single Rails validation (or custom validations) will work perfectly
113
- * Bulk operations, for avoiding ActiveRecord instantiation (efficiently operate using raw +select_all+ and +activerecord-import+ or similar systems)
113
+ * Bulk operations, for avoiding ActiveRecord instantiation (efficiently operate using raw `select_all` and `activerecord-import` or similar systems)
114
114
  * Transparently compresses JSON data in the column using GZip, if it's typed as binary (`BINARY`, `VARBINARY`, `CLOB`, etc.); you can fully control this, or turn it off if you want
115
115
  * Happily allows definition and redefinition of flex columns at any time, for full dynamism and compatibility with development mode of Rails
116
116
  * Rich error hierarchy and detailed exception messages — you will know exactly what went wrong when something goes wrong
117
117
  * Include flex columns across associations, with control over exactly what's delegated and visibility of those methods (public or private)
118
118
  * Control whether attribute methods generated are public (default) or private (to encourage encapsulation)
119
- * "Types": automatically adds validations that require fields to comply with database types like +:integer+, +:string+, +:timestamp+, etc.
119
+ * "Types": automatically adds validations that require fields to comply with database types like `:integer`, `:string`, `:timestamp`, etc.
120
120
  * Decide whether to preserve (the default) or delete keys from the underlying JSON that aren't defined in the flex column — lets you ensure database data is of the highest quality, or be compatible with any other storage mechanisms
121
121
 
122
122
  ### Documentation
@@ -60,8 +60,7 @@ module FlexColumns
60
60
 
61
61
  reason = nil
62
62
 
63
- reason ||= :column if columns.detect { |c| c.name.to_s == base_name }
64
- # return false if method_defined?(base_name) || method_defined?("#{base_name}=")
63
+ reason ||= :column if table_exists? && columns.detect { |c| c.name.to_s == base_name }
65
64
  reason ||= :instance_method if instance_methods(false).map(&:to_s).include?(base_name.to_s)
66
65
 
67
66
  (! reason)
@@ -0,0 +1,29 @@
1
+ module FlexColumns
2
+ module Definition
3
+ # This is a class that complies with just enough of the ActiveRecord interface to columns to be able to be
4
+ # swapped in for it, in our code.
5
+ #
6
+ # We use this in just one case: when you declare a flex column on a model class whose underlying table doesn't
7
+ # exist. If you call +.reset_column_information+ on the model in question, we'll pick up the new, actual column
8
+ # (assuming the table exists now), but, until then, we'll use this.
9
+ class FakeColumn
10
+ attr_reader :name
11
+
12
+ def initialize(name)
13
+ @name = name
14
+ end
15
+
16
+ def null
17
+ true
18
+ end
19
+
20
+ def type
21
+ :string
22
+ end
23
+
24
+ def limit
25
+ nil
26
+ end
27
+ end
28
+ end
29
+ end
@@ -1,3 +1,5 @@
1
+ require 'flex_columns/definition/fake_column'
2
+
1
3
  module FlexColumns
2
4
  module Definition
3
5
  # When you declare a flex column, we actually generate a brand-new Class for that column; instances of that flex
@@ -198,25 +200,11 @@ module FlexColumns
198
200
 
199
201
  raise ArgumentError, "Invalid column name: #{column_name.inspect}" unless column_name.kind_of?(Symbol)
200
202
 
201
- column = model_class.columns.detect { |c| c.name.to_s == column_name.to_s }
202
- unless column
203
- raise FlexColumns::Errors::NoSuchColumnError, %{You're trying to define a flex column #{column_name.inspect}, but
204
- the model you're defining it on, #{model_class.name}, seems to have no column
205
- named that.
206
-
207
- It has columns named: #{model_class.columns.map(&:name).sort_by(&:to_s).join(", ")}.}
208
- end
209
-
210
- unless column.type == :binary || column.text? || column.sql_type == "json" # for PostgreSQL >= 9.2, which has a native JSON data type
211
- raise FlexColumns::Errors::InvalidColumnTypeError, %{You're trying to define a flex column #{column_name.inspect}, but
212
- that column (on model #{model_class.name}) isn't of a type that accepts text.
213
- That column is of type: #{column.type.inspect}.}
214
- end
203
+ @model_class = model_class
204
+ @column = find_column(column_name)
215
205
 
216
206
  validate_options(options)
217
207
 
218
- @model_class = model_class
219
- @column = column
220
208
  @options = options
221
209
  @field_set = FlexColumns::Definition::FieldSet.new(self)
222
210
 
@@ -232,6 +220,14 @@ module FlexColumns
232
220
  block_result
233
221
  end
234
222
 
223
+ # This method gets called when ActiveRecord::Base.reset_column_information is called on the underlying model;
224
+ # this simply updates our notion of what column is present. Most importantly, this will correctly switch us from
225
+ # a table-does-not-exist state to a table-exists state (if you migrate the table in), but it also will correctly
226
+ # switch from one column type to another, etc.
227
+ def reset_column_information
228
+ @column = find_column(column_name)
229
+ end
230
+
235
231
  # Tells this class to re-publish all its methods to the DynamicMethodsModule it uses internally, and to the
236
232
  # model class it's a part of.
237
233
  #
@@ -275,6 +271,40 @@ module FlexColumns
275
271
  end
276
272
  end
277
273
 
274
+ # Given the name of a column, finds the column on the model and makes sure it complies with our
275
+ # requirements for columns we can store data in.
276
+ #
277
+ # However, if the underlying table doesn't currently exist, this creates a "fake" column object and returns it;
278
+ # this fake column object responds to just enough methods that we can use it successfully in this gem. This is
279
+ # used so that we can define flex columns on a model for a table that doesn't exist yet (typically, because it
280
+ # hasn't been migrated in yet), and effectively upgrade it using .reset_column_information, above, when it
281
+ # does exist.
282
+ def find_column(column_name)
283
+ return create_temporary_fake_column(column_name) if (! @model_class.table_exists?)
284
+
285
+ out = model_class.columns.detect { |c| c.name.to_s == column_name.to_s }
286
+ unless out
287
+ raise FlexColumns::Errors::NoSuchColumnError, %{You're trying to define a flex column #{column_name.inspect}, but
288
+ the model you're defining it on, #{model_class.name}, seems to have no column
289
+ named that.
290
+
291
+ It has columns named: #{model_class.columns.map(&:name).sort_by(&:to_s).join(", ")}.}
292
+ end
293
+
294
+ unless out.type == :binary || out.text? || out.sql_type == "json" # for PostgreSQL >= 9.2, which has a native JSON data type
295
+ raise FlexColumns::Errors::InvalidColumnTypeError, %{You're trying to define a flex column #{column_name.inspect}, but
296
+ that column (on model #{model_class.name}) isn't of a type that accepts text.
297
+ That column is of type: #{out.type.inspect}.}
298
+ end
299
+
300
+ out
301
+ end
302
+
303
+ # This creates a "fake" column that we can use if the underlying table doesn't exist yet.
304
+ def create_temporary_fake_column(column_name)
305
+ ::FlexColumns::Definition::FakeColumn.new(column_name)
306
+ end
307
+
278
308
  # Check all of our options to make sure they're correct. This is pretty defensive programming, but it is SO
279
309
  # much nicer to get an error on startup if you've specified anything incorrectly than way on down the line,
280
310
  # possibly in production, when it really matters.
@@ -17,6 +17,10 @@ module FlexColumns
17
17
  included do
18
18
  before_validation :_flex_columns_before_validation!
19
19
  before_save :_flex_columns_before_save!
20
+
21
+ class << self
22
+ alias_method_chain :reset_column_information, :flex_columns
23
+ end
20
24
  end
21
25
 
22
26
  # Before we save this model, make sure each flex column has a chance to serialize itself up and assign itself
@@ -133,6 +137,12 @@ module FlexColumns
133
137
  end
134
138
 
135
139
  module ClassMethods
140
+ def reset_column_information_with_flex_columns
141
+ reset_column_information_without_flex_columns
142
+ _flex_column_classes.each { |c| c.reset_column_information }
143
+ _flex_columns_redefine_all_methods!
144
+ end
145
+
136
146
  # Does this class have any flex columns? If this module has been included into a class, then the answer is true.
137
147
  def has_any_flex_columns?
138
148
  true
@@ -177,8 +187,6 @@ it has flex columns named: #{_all_flex_column_names.sort_by(&:to_s).inspect}.}
177
187
  # FlexColumns::Definition::FlexColumnContentsClass#setup!, and so can contain any of the options that that method
178
188
  # accepts. The block, if passed, will be evaluated in the context of the generated class.
179
189
  def flex_column(flex_column_name, options = { }, &block)
180
- return unless table_exists?
181
-
182
190
  flex_column_name = _flex_column_normalize_name(flex_column_name)
183
191
 
184
192
  new_class = Class.new(FlexColumns::Contents::FlexColumnContentsBase)
@@ -191,6 +199,12 @@ it has flex columns named: #{_all_flex_column_names.sort_by(&:to_s).inspect}.}
191
199
  _flex_column_object_for(flex_column_name)
192
200
  end
193
201
 
202
+ _flex_columns_redefine_all_methods!
203
+ end
204
+
205
+ # Defines, or redefines, all methods on the dynamic-methods module associated with this model. This gets called
206
+ # whenever we define a new flex column, or if you call .reset_column_information on the associated model.
207
+ def _flex_columns_redefine_all_methods!
194
208
  _flex_column_dynamic_methods_module.remove_all_methods!
195
209
  _flex_column_classes.each(&:sync_methods!)
196
210
  end
@@ -1,4 +1,4 @@
1
1
  module FlexColumns
2
2
  # The current version of FlexColumns.
3
- VERSION = "1.0.6"
3
+ VERSION = "1.0.7"
4
4
  end
@@ -14,6 +14,14 @@ module FlexColumns
14
14
  end
15
15
  end
16
16
 
17
+ def reset_schema_cache!(model)
18
+ if model.connection.respond_to?(:schema_cache)
19
+ model.connection.schema_cache.clear!
20
+ elsif model.connection.respond_to?(:clear_cache!)
21
+ model.connection.clear_cache!
22
+ end
23
+ end
24
+
17
25
  def define_model_class(name, table_name, &block)
18
26
  model_class = Class.new(::ActiveRecord::Base)
19
27
  ::Object.send(:remove_const, name) if ::Object.const_defined?(name)
@@ -280,8 +280,6 @@ describe "FlexColumns basic operations" do
280
280
  user.name = 'User 1'
281
281
  user.wants_email = [ 1, 2, 3 ]
282
282
 
283
- $stderr.puts "ATTRIBUTES: #{user.attributes.keys.sort.inspect}"
284
-
285
283
  user_json = JSON.dump(user)
286
284
  parsed = JSON.parse(user_json)
287
285
 
@@ -308,6 +306,7 @@ describe "FlexColumns basic operations" do
308
306
  field :bbb
309
307
  end
310
308
  end
309
+ define_model_class(:UserBackdoor, 'flexcols_spec_users') { }
311
310
 
312
311
  ::User.reset_column_information
313
312
 
@@ -26,6 +26,82 @@ describe "FlexColumns basic operations" do
26
26
  end
27
27
  end
28
28
 
29
+ it "should handle the case where a table comes into existence after being defined -- like it will when running a bunch of migrations at once" do
30
+ migrate do
31
+ drop_table :flexcols_coming_into_existence rescue nil
32
+ end
33
+
34
+ class ::Foo < ::ActiveRecord::Base
35
+ self.table_name = 'flexcols_coming_into_existence'
36
+
37
+ flex_column :foo do
38
+ field :att1
39
+ field :att2
40
+ end
41
+ end
42
+
43
+ migrate do
44
+ create_table :flexcols_coming_into_existence do |t|
45
+ t.string :name
46
+ t.string :foo
47
+ end
48
+ end
49
+
50
+ reset_schema_cache!(Foo)
51
+ Foo.reset_column_information
52
+
53
+ f2 = Foo.new
54
+ f2.att1 = "the_att1"
55
+ f2.att2 = "the_att2"
56
+ f2.save!
57
+
58
+ f2_again = Foo.find(f2.id)
59
+ f2_again.att1.should == "the_att1"
60
+ f2_again.att2.should == "the_att2"
61
+ end
62
+
63
+ it "should handle the case where a table comes into existence after being defined, and properly respect things like :binary and compression" do
64
+ migrate do
65
+ drop_table :flexcols_coming_into_existence rescue nil
66
+ end
67
+
68
+ class ::Foo < ::ActiveRecord::Base
69
+ self.table_name = 'flexcols_coming_into_existence'
70
+
71
+ flex_column :foo do
72
+ field :att1
73
+ field :att2
74
+ end
75
+ end
76
+
77
+ migrate do
78
+ create_table :flexcols_coming_into_existence do |t|
79
+ t.string :name
80
+ t.binary :foo
81
+ end
82
+ end
83
+
84
+ reset_schema_cache!(Foo)
85
+ Foo.reset_column_information
86
+
87
+ f2 = Foo.new
88
+ f2.att1 = "the_att1"
89
+ f2.att2 = "the_att2" * 1000
90
+ f2.save!
91
+
92
+ f2_again = Foo.find(f2.id)
93
+ f2_again.att1.should == "the_att1"
94
+ f2_again.att2.should == "the_att2" * 1000
95
+
96
+ class ::FooBackdoor < ActiveRecord::Base
97
+ self.table_name = 'flexcols_coming_into_existence'
98
+ end
99
+
100
+ f2_backdoor = ::FooBackdoor.find(f2.id)
101
+ data = f2_backdoor.foo
102
+ data.should match(/^FC:01,1,/i)
103
+ end
104
+
29
105
  it "should let you redefine flex columns, and obey the new settings" do
30
106
  class ::User < ::ActiveRecord::Base
31
107
  self.table_name = 'flexcols_spec_users'
@@ -130,8 +130,8 @@ describe "FlexColumns performance" do
130
130
 
131
131
  before :each do
132
132
  migrate do
133
- drop_table :flexcols_spec_users rescue nil
134
- create_table :flexcols_spec_users do |t|
133
+ drop_table :flexcols_spec_users_2 rescue nil
134
+ create_table :flexcols_spec_users_2 do |t|
135
135
  t.string :name, :null => false
136
136
  t.text :text_attrs_nonnull, :null => false
137
137
  t.text :text_attrs_null
@@ -140,9 +140,9 @@ describe "FlexColumns performance" do
140
140
  end
141
141
  end
142
142
 
143
- ::User.reset_column_information
143
+ # reset_schema_cache!(::User) if defined?(::User)
144
144
 
145
- define_model_class(:User, 'flexcols_spec_users') do
145
+ define_model_class(:User2, 'flexcols_spec_users_2') do
146
146
  flex_column :text_attrs_nonnull do
147
147
  field :aaa
148
148
  end
@@ -157,9 +157,9 @@ describe "FlexColumns performance" do
157
157
  end
158
158
  end
159
159
 
160
- define_model_class(:UserBackdoor, 'flexcols_spec_users') { }
160
+ define_model_class(:User2Backdoor, 'flexcols_spec_users_2') { }
161
161
 
162
- ::UserBackdoor.reset_column_information
162
+ ::User2Backdoor.reset_column_information
163
163
  end
164
164
 
165
165
  it "should be smart enough to store an empty JSON string to the database, if necessary, if the column is non-NULL" do
@@ -171,11 +171,11 @@ describe "FlexColumns performance" do
171
171
  # those circumstances, rather than trying to work around this (pretty broken) behavior that's also a pretty rare
172
172
  # edge case for us.
173
173
  unless defined?(RUBY_ENGINE) && RUBY_ENGINE == 'jruby' && @dh.database_type == :mysql
174
- my_user = ::User.new
174
+ my_user = ::User2.new
175
175
  my_user.name = 'User 1'
176
176
  my_user.save!
177
177
 
178
- user_bd = ::UserBackdoor.find(my_user.id)
178
+ user_bd = ::User2Backdoor.find(my_user.id)
179
179
  user_bd.name.should == 'User 1'
180
180
  user_bd.text_attrs_nonnull.should == ""
181
181
  user_bd.text_attrs_null.should == nil
@@ -185,7 +185,7 @@ describe "FlexColumns performance" do
185
185
  end
186
186
 
187
187
  it "should store NULL or the empty string in the database, as appropriate, if there's no data left any more" do
188
- my_user = ::User.new
188
+ my_user = ::User2.new
189
189
  my_user.name = 'User 1'
190
190
  my_user.aaa = 'aaa1'
191
191
  my_user.bbb = 'bbb1'
@@ -193,21 +193,21 @@ describe "FlexColumns performance" do
193
193
  my_user.ddd = 'ddd1'
194
194
  my_user.save!
195
195
 
196
- user_bd = ::UserBackdoor.find(my_user.id)
196
+ user_bd = ::User2Backdoor.find(my_user.id)
197
197
  user_bd.name.should == 'User 1'
198
198
  check_text_column_data(user_bd.text_attrs_nonnull, 'aaa', 'aaa1')
199
199
  check_text_column_data(user_bd.text_attrs_null, 'bbb', 'bbb1')
200
200
  check_binary_column_data(user_bd.binary_attrs_nonnull, 'ccc', 'ccc1')
201
201
  check_binary_column_data(user_bd.binary_attrs_null, 'ddd', 'ddd1')
202
202
 
203
- user_again = ::User.find(my_user.id)
203
+ user_again = ::User2.find(my_user.id)
204
204
  user_again.aaa = nil
205
205
  user_again.bbb = nil
206
206
  user_again.ccc = nil
207
207
  user_again.ddd = nil
208
208
  user_again.save!
209
209
 
210
- user_bd_again = ::UserBackdoor.find(my_user.id)
210
+ user_bd_again = ::User2Backdoor.find(my_user.id)
211
211
  user_bd_again.name.should == 'User 1'
212
212
  user_bd_again.text_attrs_nonnull.should == ""
213
213
  user_bd_again.text_attrs_null.should == nil
@@ -0,0 +1,8 @@
1
+ describe ::FlexColumns::Definition::FakeColumn do
2
+ it "should have the right properties" do
3
+ c = ::FlexColumns::Definition::FakeColumn.new(:foo)
4
+ c.name.should == :foo
5
+ c.null.should == true
6
+ c.type.should == :string
7
+ end
8
+ end
@@ -10,6 +10,7 @@ describe FlexColumns::Definition::FlexColumnContentsClass do
10
10
  @klass.send(:extend, FlexColumns::Definition::FlexColumnContentsClass)
11
11
 
12
12
  @model_class = double("model_class")
13
+ allow(@model_class).to receive(:table_exists?).with().and_return(true)
13
14
  allow(@model_class).to receive(:kind_of?).with(Class).and_return(true)
14
15
  allow(@model_class).to receive(:has_any_flex_columns?).with().and_return(true)
15
16
  allow(@model_class).to receive(:name).with().and_return(:mcname)
@@ -121,6 +122,12 @@ describe FlexColumns::Definition::FlexColumnContentsClass do
121
122
  e.message.should match(/integer/i)
122
123
  end
123
124
 
125
+ it "should work if the table doesn't exist" do
126
+ allow(@model_class).to receive(:table_exists?).with().and_return(false)
127
+ allow(@model_class).to receive(:columns).and_raise(StandardError) # to make sure we don't touch this
128
+ @klass.setup!(@model_class, :foo) { }
129
+ end
130
+
124
131
  it "should work on a text column" do
125
132
  @klass.setup!(@model_class, :foo) { }
126
133
  end
@@ -204,6 +211,41 @@ describe FlexColumns::Definition::FlexColumnContentsClass do
204
211
  end
205
212
  end
206
213
 
214
+ describe "reset_column_information" do
215
+ it "should still generate a fake column if the table still doesn't exist" do
216
+ allow(@model_class).to receive(:table_exists?).with().and_return(false)
217
+ @klass.setup!(@model_class, :bar) { }
218
+ c = @klass.column
219
+ c.name.should == :bar
220
+ c.type.should == :string
221
+ c.null.should == true
222
+
223
+ @klass.reset_column_information
224
+ c = @klass.column
225
+ c.name.should == :bar
226
+ c.type.should == :string
227
+ c.null.should == true
228
+ end
229
+
230
+ it "should pull a real column if the table does exist" do
231
+ allow(@column_bar).to receive(:null).with().and_return(false)
232
+
233
+ allow(@model_class).to receive(:table_exists?).with().and_return(false)
234
+ @klass.setup!(@model_class, :bar) { }
235
+ c = @klass.column
236
+ c.name.should == :bar
237
+ c.type.should == :string
238
+ c.null.should == true
239
+
240
+ allow(@model_class).to receive(:table_exists?).with().and_return(true)
241
+ @klass.reset_column_information
242
+ c = @klass.column
243
+ c.name.should == :bar
244
+ c.type.should == :binary
245
+ c.null.should == false
246
+ end
247
+ end
248
+
207
249
  describe "_flex_columns_create_column_data" do
208
250
  def expect_options_transform(class_options, length_limit, resulting_options, column_name = :foo, storage_string = double("storage_string"))
209
251
  @klass.setup!(@model_class, column_name, class_options)
@@ -30,6 +30,10 @@ describe FlexColumns::HasFlexColumns do
30
30
  def table_exists?
31
31
  true
32
32
  end
33
+
34
+ def reset_column_information
35
+ # nothing here
36
+ end
33
37
  end
34
38
 
35
39
  def _flex_column_object_for(column_name, create_if_needed = true)
@@ -59,6 +63,39 @@ describe FlexColumns::HasFlexColumns do
59
63
  @klass.has_any_flex_columns?.should be
60
64
  end
61
65
 
66
+ describe "#_flex_columns_redefine_all_methods" do
67
+ it "should remove all methods on the module, and then add them back" do
68
+ dmm = double("dmm")
69
+ expect(FlexColumns::Util::DynamicMethodsModule).to receive(:new).once.with(@klass, :FlexColumnsDynamicMethods).and_return(dmm)
70
+
71
+ fcc1 = double("fcc1", :column_name => :foo)
72
+ expect(Class).to receive(:new).once.ordered.with(FlexColumns::Contents::FlexColumnContentsBase).and_return(fcc1)
73
+ expect(fcc1).to receive(:setup!).once.ordered.with(@klass, :foo, { })
74
+
75
+ expect(dmm).to receive(:remove_all_methods!).once.ordered.with()
76
+ expect(fcc1).to receive(:sync_methods!).once.ordered.with()
77
+
78
+ @klass.flex_column(:foo)
79
+
80
+ fcc2 = double("fcc2", :column_name => :bar)
81
+ expect(Class).to receive(:new).once.ordered.with(FlexColumns::Contents::FlexColumnContentsBase).and_return(fcc2)
82
+ expect(fcc2).to receive(:setup!).once.ordered.with(@klass, :bar, { })
83
+
84
+ expect(dmm).to receive(:remove_all_methods!).once.ordered.with()
85
+ expect(fcc1).to receive(:sync_methods!).once.ordered.with()
86
+ expect(fcc2).to receive(:sync_methods!).once.ordered.with()
87
+
88
+ @klass.flex_column(:bar)
89
+
90
+
91
+ expect(dmm).to receive(:remove_all_methods!).once.ordered.with()
92
+ expect(fcc1).to receive(:sync_methods!).once.ordered.with()
93
+ expect(fcc2).to receive(:sync_methods!).once.ordered.with()
94
+
95
+ @klass._flex_columns_redefine_all_methods!
96
+ end
97
+ end
98
+
62
99
  describe "#flex_column" do
63
100
  it "should do nothing if the table doesn't exist" do
64
101
  allow(@klass).to receive(:table_exists?).with().and_return(false)
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: flex_columns
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.6
4
+ version: 1.0.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrew Geweke
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2014-04-07 00:00:00 Z
12
+ date: 2014-04-08 00:00:00 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: json
@@ -106,6 +106,7 @@ files:
106
106
  - lib/flex_columns/active_record/base.rb
107
107
  - lib/flex_columns/contents/column_data.rb
108
108
  - lib/flex_columns/contents/flex_column_contents_base.rb
109
+ - lib/flex_columns/definition/fake_column.rb
109
110
  - lib/flex_columns/definition/field_definition.rb
110
111
  - lib/flex_columns/definition/field_set.rb
111
112
  - lib/flex_columns/definition/flex_column_contents_class.rb
@@ -135,6 +136,7 @@ files:
135
136
  - spec/flex_columns/unit/active_record/base_spec.rb
136
137
  - spec/flex_columns/unit/contents/column_data_spec.rb
137
138
  - spec/flex_columns/unit/contents/flex_column_contents_base_spec.rb
139
+ - spec/flex_columns/unit/definition/fake_column_spec.rb
138
140
  - spec/flex_columns/unit/definition/field_definition_spec.rb
139
141
  - spec/flex_columns/unit/definition/field_set_spec.rb
140
142
  - spec/flex_columns/unit/definition/flex_column_contents_class_spec.rb
@@ -187,6 +189,7 @@ test_files:
187
189
  - spec/flex_columns/unit/active_record/base_spec.rb
188
190
  - spec/flex_columns/unit/contents/column_data_spec.rb
189
191
  - spec/flex_columns/unit/contents/flex_column_contents_base_spec.rb
192
+ - spec/flex_columns/unit/definition/fake_column_spec.rb
190
193
  - spec/flex_columns/unit/definition/field_definition_spec.rb
191
194
  - spec/flex_columns/unit/definition/field_set_spec.rb
192
195
  - spec/flex_columns/unit/definition/flex_column_contents_class_spec.rb