flextures 3.1.3 → 4.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.
@@ -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