flextures 3.1.3 → 4.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,19 +1,6 @@
1
- # encoding: utf-8
2
-
3
1
  require 'ostruct'
4
2
 
5
3
  module Flextures
6
- # OpenStruct hack in flextures Plug-in
7
- class OpenStruct < ::OpenStruct
8
- # Struct Data translate to Hash
9
- def to_hash
10
- (self.methods - ::OpenStruct.new.methods)
11
- .select{ |name| name.to_s.match(/\w+=/) }
12
- .map{ |name| name.to_s.gsub(/=/,'').to_sym }
13
- .reduce({}){ |k,h| h[k]=self.send(k); h }
14
- end
15
- end
16
-
17
4
  module Extensions
18
5
  module Array
19
6
  # use Object#extend
@@ -21,7 +8,7 @@ module Flextures
21
8
  # @return [Hash] tanslated Hash data
22
9
  # example:
23
10
  # hash = array.extend(Extensions::Array).to_hash(keys)
24
- def to_hash( keys )
11
+ def to_hash(keys)
25
12
  values = self
26
13
  values = values[0..keys.size-1] if keys.size < values.size
27
14
  values = values+[nil]*(keys.size-values.size) if keys.size > values.size
@@ -1,5 +1,3 @@
1
- # encoding: utf-8
2
-
3
1
  module Flextures
4
2
  # Flextures FactoryFilter is program to translate ActiveRecord data
5
3
  class LoadFilter
@@ -10,7 +8,7 @@ module Flextures
10
8
  # @params [String] table_name
11
9
  # @params [Array] options arguments ActiveRecord Model
12
10
  # @params [Proc] block FactoryFilter
13
- def self.define( table_name, *options, &block )
11
+ def self.define(table_name, *options, &block)
14
12
  h={ block: block }
15
13
  options.each do |o|
16
14
  begin
@@ -40,12 +38,12 @@ module Flextures
40
38
  # @params options
41
39
  # @params block
42
40
  # @return Flextures::Factory
43
- def self.define( table_name, hash )
41
+ def self.define(table_name, hash)
44
42
  FACTORIES[table_name.to_sym]=hash
45
43
  end
46
44
 
47
45
  # get FactoryFilter
48
- def self.get( table_name )
46
+ def self.get(table_name)
49
47
  FACTORIES[table_name.to_sym]
50
48
  end
51
49
  def self.[](table_name); self.get(table_name); end
@@ -1,5 +1,3 @@
1
- # encoding: utf-8
2
-
3
1
  require 'ostruct'
4
2
  require 'csv'
5
3
 
@@ -88,28 +86,28 @@ module Flextures
88
86
 
89
87
  def loads(*fixtures)
90
88
  # キャッシュが有効 ∧ 呼んだ事無いファイル
91
- load_list = self.class.parse_flextures_options( @options, *fixtures)
89
+ load_list = self.class.parse_flextures_options(@options, *fixtures)
92
90
  load_list.sort(&self.class.loading_order).each do |params|
93
91
  load(params)
94
92
  end
95
93
  end
96
94
 
97
95
  def load(params)
98
- return if cashable?(params) and loaded?(params)
99
- @already_loaded_fixtures[params[:table]] = params
100
96
  self.class.load(params)
101
97
  end
102
98
 
103
- def cashable?(params)
104
- !!params[:cache]
99
+ def self.cache?(params)
100
+ if params.first.is_a?(Hash)
101
+ param = params.first
102
+ param[:cache] == true
103
+ end
105
104
  end
106
105
 
107
- def loaded?(params)
108
- equal_table_data?(@already_loaded_fixtures[params[:table]], params)
106
+ def reset_cache
109
107
  end
110
108
 
111
109
  # compare
112
- def equal_table_data?(src,dst)
110
+ def equal_table_data?(src, dst)
113
111
  return false unless src.is_a?(Hash)
114
112
  return false unless dst.is_a?(Hash)
115
113
  (src.to_a - dst.to_a).empty?
@@ -118,9 +116,8 @@ module Flextures
118
116
  # called by Rspec or Should
119
117
  # set options
120
118
  # @params [Hash] options exmple : { cashe: true, dir: "models/users" }
121
- def set_options( options )
119
+ def set_options(options)
122
120
  @options.merge!(options)
123
- @options
124
121
  end
125
122
 
126
123
  # called by Rspec or Should after filter
@@ -138,12 +135,12 @@ module Flextures
138
135
  # parse flextures function arguments
139
136
  # @params [Hash] fixtures function arguments
140
137
  # @return [Array] formatted load options
141
- def self.parse_flextures_options( base_options, *fixtures )
138
+ def self.parse_flextures_options(base_options, *fixtures)
142
139
  options = {}
143
140
  options = fixtures.shift if fixtures.size > 1 and fixtures.first.is_a?(Hash)
144
141
 
145
- options[:dir] = self.parse_controller_option( options ) if options[:controller]
146
- options[:dir] = self.parse_model_options( options ) if options[:model]
142
+ options[:dir] = self.parse_controller_option(options) if options[:controller]
143
+ options[:dir] = self.parse_model_options(options) if options[:model]
147
144
 
148
145
  # :all value load all loadable fixtures
149
146
  fixtures = Flextures::deletable_tables if fixtures.size==1 and :all == fixtures.first
@@ -161,7 +158,7 @@ module Flextures
161
158
  # flextures :users => :users2 # :table_name => :file_name
162
159
  #
163
160
  # @params [Hash] fixtures load table data
164
- def self.flextures( *fixtures )
161
+ def self.flextures(*fixtures)
165
162
  loader = Flextures::Loader::Instance.new
166
163
  loader.loads(*fixtures)
167
164
  end
@@ -178,7 +175,7 @@ module Flextures
178
175
  # load fixture data
179
176
  # fixture file prefer YAML to CSV
180
177
  # @params [Hash] format file load format(table name, file name, options...)
181
- def self.load( format )
178
+ def self.load(format)
182
179
  file_name, method = file_exist(format)
183
180
  if method
184
181
  send(method, format)
@@ -189,31 +186,31 @@ module Flextures
189
186
 
190
187
  # load CSV data
191
188
  # @params [Hash] format file load format(table name, file name, options...)
192
- def self.csv( format )
189
+ def self.csv(format)
193
190
  type = :csv
194
- file_name, ext = file_exist( format, [type] )
195
- return unless self.file_loadable?( format, file_name )
196
- klass, filter = self.create_model_filter( format, file_name, type )
197
- self.load_csv( format, klass, filter, file_name )
191
+ file_name, ext = file_exist(format, [type])
192
+ return unless self.file_loadable?(format, file_name)
193
+ klass, filter = self.create_model_filter(format, file_name, type)
194
+ self.load_csv(format, klass, filter, file_name)
198
195
  end
199
196
 
200
197
  # load YAML data
201
198
  # @params [Hash] format file load format( table: name, file: name, options...)
202
- def self.yml( format )
199
+ def self.yml(format)
203
200
  type = :yml
204
- file_name, ext = file_exist( format, [type] )
201
+ file_name, ext = file_exist(format, [type])
205
202
 
206
- return unless self.file_loadable?( format, file_name )
203
+ return unless self.file_loadable?(format, file_name)
207
204
 
208
- klass, filter = self.create_model_filter( format, file_name, type )
209
- self.load_yml( format, klass, filter, file_name )
205
+ klass, filter = self.create_model_filter(format, file_name, type)
206
+ self.load_yml(format, klass, filter, file_name)
210
207
  end
211
208
 
212
- def self.load_csv( format, klass, filter, file_name )
209
+ def self.load_csv(format, klass, filter, file_name)
213
210
  attributes = klass.columns.map(&:name)
214
- CSV.open( file_name ) do |csv|
211
+ CSV.open(file_name) do |csv|
215
212
  keys = csv.shift # active record column names
216
- warning( "CSV", attributes, keys ) unless format[:silent]
213
+ warning("CSV", attributes, keys) unless format[:silent]
217
214
  csv.each do |values|
218
215
  h = values.extend(Extensions::Array).to_hash(keys)
219
216
  filter.call(h)
@@ -222,12 +219,12 @@ module Flextures
222
219
  file_name
223
220
  end
224
221
 
225
- def self.load_yml( format, klass, filter, file_name )
226
- yaml = YAML.load( File.open(file_name) )
222
+ def self.load_yml(format, klass, filter, file_name)
223
+ yaml = YAML.load(File.open(file_name))
227
224
  return false unless yaml # if file is empty
228
225
  attributes = klass.columns.map(&:name)
229
226
  yaml.each do |k,h|
230
- warning( "YAML", attributes, h.keys ) unless format[:silent]
227
+ warning("YAML", attributes, h.keys) unless format[:silent]
231
228
  filter.call(h)
232
229
  end
233
230
  file_name
@@ -237,7 +234,7 @@ module Flextures
237
234
  # load directroy is change
238
235
  # spec/fixtures/:controller_name/:action_name/
239
236
  # @return [String] directory path
240
- def self.parse_controller_option( options )
237
+ def self.parse_controller_option(options)
241
238
  controller_dir = ["controllers"]
242
239
  controller_dir<< options[:controller] if options[:controller]
243
240
  controller_dir<< options[:action] if options[:controller] and options[:action]
@@ -248,7 +245,7 @@ module Flextures
248
245
  # load directroy is change
249
246
  # spec/fixtures/:model_name/:method_name/
250
247
  # @return [String] directory path
251
- def self.parse_model_options( options )
248
+ def self.parse_model_options(options)
252
249
  model_dir = ["models"]
253
250
  model_dir<< options[:model] if options[:model]
254
251
  model_dir<< options[:method] if options[:model] and options[:method]
@@ -258,7 +255,7 @@ module Flextures
258
255
  # example:
259
256
  # self.create_stair_list("foo/bar/baz")
260
257
  # return ["foo/bar/baz","foo/bar","foo",""]
261
- def self.stair_list( dir, stair=true )
258
+ def self.stair_list(dir, stair=true)
262
259
  return [dir.to_s] unless stair
263
260
  l = []
264
261
  dir.to_s.split("/").reduce([]){ |a,d| a<< d; l.unshift(a.join("/")); a }
@@ -269,12 +266,12 @@ module Flextures
269
266
  # parse format option and return load file info
270
267
  # @param [Hash] format load file format informations
271
268
  # @return [Array] [file_name, filt_type(:csv or :yml)]
272
- def self.file_exist( format, type = [:csv,:yml] )
269
+ def self.file_exist(format, type = [:csv, :yml])
273
270
  table_name = format[:table].to_s
274
271
  file_name = (format[:file] || format[:table]).to_s
275
- base_dir_name = Flextures::Config.fixture_load_directory
272
+ base_dir_name = Flextures::Configuration.load_directory
276
273
  self.stair_list(format[:dir], format[:stair]).each do |dir|
277
- file_path = File.join( base_dir_name, dir, file_name )
274
+ file_path = File.join(base_dir_name, dir, file_name)
278
275
  return ["#{file_path}.csv", :csv] if type.member?(:csv) and File.exist?("#{file_path}.csv")
279
276
  return ["#{file_path}.yml", :yml] if type.member?(:yml) and File.exist?("#{file_path}.yml")
280
277
  end
@@ -283,8 +280,8 @@ module Flextures
283
280
 
284
281
  # file load check
285
282
  # @return [Bool] lodable is 'true'
286
- def self.file_loadable?( format, file_name )
287
- return unless File.exist?( file_name )
283
+ def self.file_loadable?(format, file_name)
284
+ return unless File.exist?(file_name)
288
285
  puts "try loading #{file_name}" if !format[:silent] and ![:fun].include?(format[:loader])
289
286
  true
290
287
  end
@@ -296,17 +293,18 @@ module Flextures
296
293
  end
297
294
 
298
295
  # create filter and table info
299
- def self.create_model_filter( format, file_name, type )
296
+ def self.create_model_filter(format, file_name, type)
300
297
  table_name = format[:table].to_s
301
- klass = PARENT::create_model( table_name )
298
+ klass = PARENT::create_model(table_name)
299
+ # binding.pry
302
300
  # if you use 'rails3_acts_as_paranoid' gem, that is not delete data 'delete_all' method
303
- klass.send( klass.respond_to?(:delete_all!) ? :delete_all! : :delete_all )
301
+ klass.send(klass.respond_to?(:delete_all!) ? :delete_all! : :delete_all)
304
302
 
305
303
  filter = ->(h){
306
- filter = create_filter( klass, LoadFilter[table_name.to_sym], file_name, type, format )
304
+ filter = create_filter(klass, LoadFilter[table_name.to_sym], file_name, type, format)
307
305
  o = klass.new
308
- o = filter.call( o, h )
309
- o.save( validate: false )
306
+ o = filter.call(o, h)
307
+ o.save(validate: false)
310
308
  o
311
309
  }
312
310
  [klass, filter]
@@ -322,24 +320,24 @@ module Flextures
322
320
  # @params [Symbol] ext file type (:csv or :yml)
323
321
  # @params [Hash] options other options
324
322
  # @return [Proc] translate filter
325
- def self.create_filter( klass, factory, filename, ext, options )
323
+ def self.create_filter(klass, factory, filename, ext, options)
326
324
  columns = klass.columns
327
325
  # data translat array to hash
328
326
  column_hash = columns.reduce({}) { |h,col| h[col.name] = col; h }
329
327
  lack_columns = columns.reject { |c| c.null and c.default }.map{ |o| o.name.to_sym }
330
328
  # default value shound not be null columns
331
329
  not_nullable_columns = columns.reject(&:null).map(&:name)
332
- strict_filter=->(o,h){
330
+ strict_filter = ->(o,h){
333
331
  # if value is not 'nil', value translate suitable form
334
332
  h.each{ |k,v| v.nil? || o[k] = (TRANSLATER[column_hash[k].type] && TRANSLATER[column_hash[k].type].call(v)) }
335
333
  # call FactoryFilter
336
- factory.call(*[o, filename, ext][0,factory.arity]) if factory and !options[:unfilter]
334
+ factory.call(*[o, filename, ext][0, factory.arity]) if factory and !options[:unfilter]
337
335
  o
338
336
  }
339
337
  # receives hased data and translate ActiveRecord Model data
340
338
  # loose filter correct error values
341
339
  # strict filter don't correct errora values and raise error
342
- loose_filter=->(o,h){
340
+ loose_filter = ->(o,h){
343
341
  h.reject! { |k,v| options[:minus].include?(k) } if options[:minus]
344
342
  # if column name is not include database table columns, those names delete
345
343
  h.select! { |k,v| column_hash[k] }
@@ -1,5 +1,3 @@
1
- # encoding: utf-8
2
-
3
1
  module Flextures
4
2
  class Railtie < Rails::Railtie
5
3
  rake_tasks do
@@ -1,100 +1,154 @@
1
- # encoding: utf-8
2
-
3
-
1
+ # flextures function use like fixtures method in RSpec
4
2
  module RSpec
5
3
  module Rails
6
- module SetupAndTeardownAdapter
7
- extend ActiveSupport::Concern
8
-
9
- module ClassMethods
10
- def flextures_prepend_before(&block)
11
- prepend_before(&block)
12
- end
4
+ module FlextureSupport
5
+ @@once_included = false
6
+ def self.included(m)
7
+ init_tables
8
+ end
13
9
 
14
- def flextures_before(&block)
15
- before(&block)
10
+ def self.init_tables
11
+ unless @@once_included
12
+ Flextures::init_tables
13
+ @@once_included = true
16
14
  end
17
15
  end
18
16
  end
19
17
  end
18
+
19
+ RSpec.configure do |c|
20
+ c.include RSpec::Rails::FlextureSupport
21
+ end
20
22
  end
21
23
 
22
- # flextures function use like fixtures method in RSpec
23
- module RSpec
24
- module Core
25
- module Hooks
26
- # load fixtture data
27
- # @params [Array] _ fixture file names
28
- def flextures( *_ )
29
- flextures_loader = create_or_get_flextures_loader(__method__)
30
- flextures_before do
31
- flextures_loader.loads( *_ )
24
+ # override setup_fixtures function
25
+ module ActiveRecord
26
+ module TestFixtures
27
+ PARENT = self
28
+ @@flextures_loader = Flextures::Loader.new
29
+ @@all_cached_flextures = {}
30
+ @@already_loaded_flextures = {}
31
+
32
+ alias :setup_fixtures_bkup :setup_fixtures
33
+ def setup_fixtures
34
+ Flextures::load_configurations
35
+ setup_fixtures_bkup
36
+ end
37
+
38
+ alias :teardown_fixtures_bkup :teardown_fixtures
39
+ def teardown_fixtures
40
+ teardown_fixtures_bkup
41
+ end
42
+
43
+ # load initial fixtures
44
+ # There is fixtures load before start rspec
45
+ def self.init_load_should_cache_fixtures(table_load_settings)
46
+ table_load_settings.each do |load_setting|
47
+ if should_cache_setting?(load_setting) and !cached_table?(load_setting)
48
+ @@flextures_loader.load(load_setting)
49
+ set_cached_settng_list(load_setting)
50
+ end
51
+ end
52
+ end
53
+
54
+ # Usually, fixture is cached when is exist under "spec/fixture/" directly.
55
+ def self.should_cache_setting?(load_setting)
56
+ load_setting.keys.sort == %i[table file loader].sort &&
57
+ load_setting[:file].to_s == load_setting[:table].to_s &&
58
+ load_setting[:loader] == :fun
59
+ end
60
+
61
+ # check: same data is exist in DB.
62
+ def self.cached_table?(load_setting)
63
+ flextures_cached?(load_setting) || fixture_cached?(load_setting)
64
+ end
65
+
66
+ def self.flextures_cached?(load_setting)
67
+ config = @@all_cached_flextures[load_setting[:table]]
68
+ config && config == load_setting
69
+ end
70
+
71
+ # flextures check fixture function already loaded data.
72
+ def self.fixture_cached?(load_setting)
73
+ default_file_path = File.join(Flextures::Configuration.load_directory, "#{load_setting[:table]}.yml")
74
+
75
+ load_setting[:file] == default_file_path &&
76
+ yml_fixture_cached?(load_setting[:table])
77
+ end
78
+
79
+ def self.yml_fixture_cached?(table_name)
80
+ connection = ActiveRecord::Base.connection
81
+ !!ActiveRecord::FixtureSet.fixture_is_cached?(connection, table_name)
82
+ end
83
+
84
+ def self.set_cached_settng_list(load_setting)
85
+ @@all_cached_flextures[load_setting[:table]] = load_setting
86
+ end
87
+
88
+ def load_not_cached_fixtures(table_load_settings)
89
+ table_load_settings.each do |load_setting|
90
+ if PARENT.cached_table?(load_setting) and load_setting[:cache] != false
91
+ next
92
+ else
93
+ @@flextures_loader.load(load_setting)
32
94
  end
33
95
  end
96
+ end
97
+
98
+ def load_all_fixtures(table_load_settings)
99
+ table_load_settings.each do |load_setting|
100
+ @@flextures_loader.load(load_setting)
101
+ end
102
+ end
103
+
104
+ module ClassMethods
105
+ def get_or_initialize_flextures_loader_options
106
+ @flextures_loader_options ||= {}
107
+ end
108
+
109
+ def flextures_loader_options
110
+ get_or_initialize_flextures_loader_options
111
+ end
112
+
113
+ def flextures_loader
114
+ PARENT.class_variable_get(:@@flextures_loader)
115
+ end
34
116
 
35
- # flexturesの読み出し
36
- def create_or_get_flextures_loader(*_)
37
- @@flextures_loader ||= Flextures::Loader.new(*_)
117
+ def flextures(*fixtures)
118
+ loads_use_cache_fixtures(*fixtures)
38
119
  end
39
120
 
40
- def flextures_get_options
41
- @@flextures_loader
121
+ def loads_use_cache_fixtures(*fixtures)
122
+ table_load_settings = Flextures::Loader.parse_flextures_options(flextures_loader_options, *fixtures)
123
+
124
+ if use_transactional_fixtures
125
+ PARENT.init_load_should_cache_fixtures(table_load_settings)
126
+ before do
127
+ load_not_cached_fixtures(table_load_settings)
128
+ end
129
+ else
130
+ before do
131
+ load_all_fixtures(table_load_settings)
132
+ end
133
+ end
42
134
  end
43
135
 
44
136
  # delete table data
45
137
  # @params [Array] _ table names
46
- def flextures_delete( *_ )
47
- flextures_loader = create_or_get_flextures_loader(__method__)
48
- flextures_before do
138
+ def flextures_delete(*_)
139
+ before do
49
140
  if _.empty?
50
141
  Flextures::init_tables
51
142
  else
52
- Flextures::delete_tables( *_ )
143
+ Flextures::delete_tables(*_)
53
144
  end
54
145
  end
55
146
  end
56
147
 
57
- def flextures_set_options( options )
58
- flextures_loader = create_or_get_flextures_loader(__method__)
59
- flextures_prepend_before do
60
- flextures_loader.set_options( options )
61
- end
62
- end
63
- end
64
- end
65
-
66
- module Rails
67
- module FlextureSupport
68
- def self.included(m)
69
- Flextures::init_tables
148
+ def flextures_set_options(options)
149
+ @flextures_loader_options = get_or_initialize_flextures_loader_options
150
+ @flextures_loader_options = @flextures_loader_options.merge(options)
70
151
  end
71
152
  end
72
153
  end
73
-
74
- RSpec.configure do |c|
75
- c.include RSpec::Rails::FlextureSupport
76
- end
77
- end
78
-
79
- # override setup_fixtures function
80
- module ActiveRecord
81
- module TestFixtures
82
- alias :setup_fixtures_bkup :setup_fixtures
83
- def setup_fixtures
84
- Flextures::init_load
85
- setup_fixtures_bkup
86
- set_transactional_filter_params
87
- end
88
-
89
- # nilで無い時は値をtransactional_filterが有効 
90
- def set_transactional_filter_params
91
- return if Flextures::Config.use_transactional_fixtures.nil?
92
- self.use_transactional_fixtures = Flextures::Config.use_transactional_fixtures
93
- end
94
-
95
- alias :teardown_fixtures_bkup :teardown_fixtures
96
- def teardown_fixtures
97
- teardown_fixtures_bkup
98
- end
99
- end
100
154
  end