datashift 0.4.3 → 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- data/VERSION +1 -1
- data/datashift.gemspec +7 -3
- data/lib/applications/jruby/jexcel_file.rb +4 -2
- data/lib/datashift/method_details_manager.rb +7 -2
- data/lib/datashift/method_dictionary.rb +3 -3
- data/lib/datashift/method_mapper.rb +1 -0
- data/lib/exporters/excel_exporter.rb +23 -23
- data/lib/helpers/spree_helper.rb +21 -20
- data/lib/loaders/csv_loader.rb +4 -1
- data/lib/loaders/loader_base.rb +24 -4
- data/lib/loaders/spree/image_loader.rb +3 -1
- data/lib/loaders/spree/product_loader.rb +42 -22
- data/lib/thor/export_excel.thor +74 -0
- data/lib/thor/spree/products_images.thor +2 -1
- data/spec/Gemfile +18 -0
- data/spec/excel_exporter_spec.rb +9 -10
- data/spec/excel_generator_spec.rb +3 -8
- data/spec/fixtures/datashift_Spree_db.sqlite +0 -0
- data/spec/fixtures/datashift_test_models_db.sqlite +0 -0
- data/spec/fixtures/spree/SpreeProductImages.xls +0 -0
- data/spec/fixtures/spree/SpreeProductsWithImages.xls +0 -0
- data/spec/spec_helper.rb +34 -10
- data/spec/spree_exporter_spec.rb +14 -11
- data/spec/spree_generator_spec.rb +1 -1
- data/spec/spree_images_loader_spec.rb +27 -11
- data/spec/spree_loader_spec.rb +32 -27
- data/spec/thor_spec.rb +32 -0
- metadata +7 -3
- data/spec/fixtures/interact_models_db.sqlite +0 -0
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.5.0
|
data/datashift.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = "datashift"
|
8
|
-
s.version = "0.
|
8
|
+
s.version = "0.5.0"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Thomas Statter"]
|
12
|
-
s.date = "2012-
|
12
|
+
s.date = "2012-05-08"
|
13
13
|
s.description = "A suite of tools to move data between ActiveRecord models,databases,applications like Excel/Open Office, files and projects including Spree"
|
14
14
|
s.email = "rubygems@autotelik.co.uk"
|
15
15
|
s.extra_rdoc_files = [
|
@@ -24,6 +24,7 @@ Gem::Specification.new do |s|
|
|
24
24
|
"README.rdoc",
|
25
25
|
"Rakefile",
|
26
26
|
"VERSION",
|
27
|
+
"datashift-0.5.0.gem",
|
27
28
|
"datashift.gemspec",
|
28
29
|
"lib/applications/jruby/jexcel_file.rb",
|
29
30
|
"lib/applications/jruby/word.rb",
|
@@ -68,6 +69,7 @@ Gem::Specification.new do |s|
|
|
68
69
|
"lib/loaders/spreadsheet_loader.rb",
|
69
70
|
"lib/loaders/spree/image_loader.rb",
|
70
71
|
"lib/loaders/spree/product_loader.rb",
|
72
|
+
"lib/thor/export_excel.thor",
|
71
73
|
"lib/thor/generate_excel.thor",
|
72
74
|
"lib/thor/import_excel.thor",
|
73
75
|
"lib/thor/spree/bootstrap_cleanup.thor",
|
@@ -92,6 +94,7 @@ Gem::Specification.new do |s|
|
|
92
94
|
"sandbox/config/database.yml",
|
93
95
|
"sandbox/config/environment.rb",
|
94
96
|
"sandbox/config/environments/development.rb",
|
97
|
+
"spec/Gemfile",
|
95
98
|
"spec/csv_loader_spec.rb",
|
96
99
|
"spec/datashift_spec.rb",
|
97
100
|
"spec/db/migrate/20110803201325_create_test_bed.rb",
|
@@ -113,13 +116,13 @@ Gem::Specification.new do |s|
|
|
113
116
|
"spec/fixtures/images/DEMO_002_Powerstation.jpg",
|
114
117
|
"spec/fixtures/images/DEMO_003_ror_mug.jpeg",
|
115
118
|
"spec/fixtures/images/DEMO_004_ror_ringer.jpeg",
|
116
|
-
"spec/fixtures/interact_models_db.sqlite",
|
117
119
|
"spec/fixtures/negative/SpreeProdMiss1Mandatory.csv",
|
118
120
|
"spec/fixtures/negative/SpreeProdMiss1Mandatory.xls",
|
119
121
|
"spec/fixtures/negative/SpreeProdMissManyMandatory.csv",
|
120
122
|
"spec/fixtures/negative/SpreeProdMissManyMandatory.xls",
|
121
123
|
"spec/fixtures/simple_export_spec.xls",
|
122
124
|
"spec/fixtures/simple_template_spec.xls",
|
125
|
+
"spec/fixtures/spree/SpreeProductImages.xls",
|
123
126
|
"spec/fixtures/spree/SpreeProducts.csv",
|
124
127
|
"spec/fixtures/spree/SpreeProducts.xls",
|
125
128
|
"spec/fixtures/spree/SpreeProductsDefaults.yml",
|
@@ -142,6 +145,7 @@ Gem::Specification.new do |s|
|
|
142
145
|
"spec/spree_images_loader_spec.rb",
|
143
146
|
"spec/spree_loader_spec.rb",
|
144
147
|
"spec/spree_method_mapping_spec.rb",
|
148
|
+
"spec/thor_spec.rb",
|
145
149
|
"tasks/config/seed_fu_product_template.erb",
|
146
150
|
"tasks/config/tidy_config.txt",
|
147
151
|
"tasks/export/excel_generator.rake",
|
@@ -123,7 +123,7 @@ if(DataShift::Guards::jruby?)
|
|
123
123
|
# Process each row. (type is org.apache.poi.hssf.usermodel.HSSFRow)
|
124
124
|
|
125
125
|
def each_row
|
126
|
-
@sheet.rowIterator.each { |row| yield row }
|
126
|
+
@sheet.rowIterator.each { |row| @row = row; yield row }
|
127
127
|
end
|
128
128
|
|
129
129
|
# Create new row, bring index in line with POI usage (our 1 is their 0)
|
@@ -150,7 +150,9 @@ if(DataShift::Guards::jruby?)
|
|
150
150
|
create_row(1)
|
151
151
|
return if headers.empty?
|
152
152
|
|
153
|
-
|
153
|
+
headers.each_with_index do |datum, i|
|
154
|
+
@row.createCell(i, excel_cell_type(datum)).setCellValue(datum)
|
155
|
+
end
|
154
156
|
end
|
155
157
|
|
156
158
|
# Populate a row of cells with data in an array
|
@@ -13,10 +13,11 @@ module DataShift
|
|
13
13
|
# Stores MethodDetails for a class mapped by type
|
14
14
|
class MethodDetailsManager
|
15
15
|
|
16
|
-
attr_reader :method_details
|
16
|
+
attr_reader :method_details, :method_details_list
|
17
|
+
attr_reader :managed_class_name
|
17
18
|
|
18
19
|
def initialize( klass )
|
19
|
-
@
|
20
|
+
@managed_class_name = klass.name
|
20
21
|
@method_details = {}
|
21
22
|
@method_details_list = {}
|
22
23
|
end
|
@@ -49,6 +50,10 @@ module DataShift
|
|
49
50
|
@method_details_list[type.to_sym]
|
50
51
|
end
|
51
52
|
|
53
|
+
def all_available_operators
|
54
|
+
method_details_list.values.flatten.collect(&:operator)
|
55
|
+
end
|
56
|
+
|
52
57
|
end
|
53
58
|
|
54
59
|
end
|
@@ -114,13 +114,13 @@ module DataShift
|
|
114
114
|
# If not nil, returned method can be used directly in for example klass.new.send( call, .... )
|
115
115
|
#
|
116
116
|
def self.find_method_detail( klass, external_name )
|
117
|
-
operator = nil
|
118
117
|
|
119
|
-
# TODO - should we raise error to warn find_operators never called ?
|
120
118
|
md_mgr = method_details_mgrs[klass] || MethodDetailsManager.new( klass )
|
121
119
|
|
120
|
+
# md_mgr.all_available_operators.each { |l| puts "DEBUG: Mapped Method : #{l.inspect}" }
|
121
|
+
|
122
122
|
name = external_name.to_s
|
123
|
-
|
123
|
+
|
124
124
|
# TODO - check out regexp to do this work better plus Inflections ??
|
125
125
|
# Want to be able to handle any of ["Count On hand", 'count_on_hand', "Count OnHand", "COUNT ONHand" etc]
|
126
126
|
[
|
@@ -61,6 +61,7 @@ module DataShift
|
|
61
61
|
end
|
62
62
|
|
63
63
|
x, lookup = name.split(MethodMapper::column_delim)
|
64
|
+
#puts "DEBUG: Find Method Detail for #{x}"
|
64
65
|
md = MethodDictionary::find_method_detail( klass, x )
|
65
66
|
|
66
67
|
# TODO be nice if we could cheeck that the assoc on klass responds to the specified
|
@@ -67,39 +67,39 @@ module DataShift
|
|
67
67
|
puts "work_list : [#{work_list.inspect}]"
|
68
68
|
|
69
69
|
details_mgr = MethodDictionary.method_details_mgrs[klass]
|
70
|
-
|
70
|
+
|
71
|
+
|
72
|
+
data = []
|
73
|
+
# For each type belongs has_one, has_many etc find the operators
|
74
|
+
# and create headers, then for each record call those operators
|
71
75
|
work_list.each do |op_type|
|
76
|
+
|
72
77
|
list_for_class_and_op = details_mgr.get_list(op_type)
|
73
78
|
|
74
79
|
next if(list_for_class_and_op.nil? || list_for_class_and_op.empty?)
|
75
|
-
|
76
|
-
|
77
|
-
#end
|
78
|
-
#if(MethodDictionary.respond_to?("#{mdtype}_for") )
|
79
|
-
# method_details = MethodDictionary.send("#{mdtype}_for", klass)
|
80
|
+
|
81
|
+
# method_details = MethodDictionary.send("#{mdtype}_for", klass)
|
80
82
|
|
81
|
-
|
82
|
-
|
83
|
-
|
83
|
+
list_for_class_and_op.each do |md|
|
84
|
+
headers << "#{md.operator}"
|
85
|
+
items.each do |i|
|
86
|
+
data << i.send( md.operator )
|
87
|
+
end
|
84
88
|
|
85
|
-
|
89
|
+
end
|
86
90
|
|
87
|
-
|
88
|
-
|
89
|
-
data = []
|
91
|
+
excel.set_headers( headers )
|
90
92
|
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
93
|
+
|
94
|
+
row_index = 1
|
95
|
+
|
96
|
+
items.each do |datum|
|
97
|
+
excel.create_row(row_index += 1)
|
98
|
+
excel.ar_to_xls_row(1, datum)
|
97
99
|
end
|
100
|
+
|
101
|
+
excel.save( filename() )
|
98
102
|
end
|
99
|
-
|
100
|
-
excel.set_row(2,1,items)
|
101
|
-
|
102
|
-
excel.save( filename() )
|
103
103
|
end
|
104
104
|
end # ExcelGenerator
|
105
105
|
|
data/lib/helpers/spree_helper.rb
CHANGED
@@ -3,22 +3,19 @@
|
|
3
3
|
# Date :: Aug 2011
|
4
4
|
# License:: MIT
|
5
5
|
#
|
6
|
-
# Details:: Spree Helper
|
6
|
+
# Details:: Spree Helper for Product Loading.
|
7
7
|
#
|
8
|
-
#
|
8
|
+
# Utils to try to manage different Spree versions seamlessly.
|
9
|
+
#
|
10
|
+
# Spree Helper for RSpec testing, enables mixing in Support for
|
11
|
+
# testing or loading Rails Spree e-commerce.
|
12
|
+
#
|
13
|
+
# The Spree version you want to test should be picked up from spec/Gemfile
|
9
14
|
#
|
10
15
|
# Since datashift gem is not a Rails app or a Spree App, provides utilities to internally
|
11
16
|
# create a Spree Database, and to load Spree components, enabling standalone testing.
|
12
17
|
#
|
13
|
-
# => Has been tested with 0.7
|
14
|
-
#
|
15
|
-
# # => TODO - Can we move to a Gemfile/bunlder
|
16
|
-
# require 'rubygems'
|
17
|
-
# gemfile = File.expand_path("<%= gemfile_path %>", __FILE__)
|
18
|
-
#
|
19
|
-
# ENV['BUNDLE_GEMFILE'] = gemfile
|
20
|
-
# require 'bundler'
|
21
|
-
# Bundler.setup
|
18
|
+
# => Has been tested with 0.11.2, 0.7, 1.0.0
|
22
19
|
#
|
23
20
|
# => TODO - See if we can improve DB creation/migration ....
|
24
21
|
# N.B Some or all of Spree Tests may fail very first time run,
|
@@ -52,8 +49,12 @@ module DataShift
|
|
52
49
|
end
|
53
50
|
end
|
54
51
|
|
52
|
+
def self.version
|
53
|
+
Gem.loaded_specs['spree'] ? Gem.loaded_specs['spree'].version.version : "0.0.0"
|
54
|
+
end
|
55
|
+
|
55
56
|
def self.is_namespace_version
|
56
|
-
|
57
|
+
SpreeHelper::version.to_f >= 1
|
57
58
|
end
|
58
59
|
|
59
60
|
def self.lib_root
|
@@ -79,7 +80,9 @@ module DataShift
|
|
79
80
|
# => Will chdir into the sandbox to load environment as need to mimic being at root of a rails project
|
80
81
|
# chdir back after environment loaded
|
81
82
|
|
82
|
-
|
83
|
+
# gem('rails', '3.2.3')
|
84
|
+
|
85
|
+
def self.boot( database_env)#, rails_version = '3.1.3' )
|
83
86
|
|
84
87
|
if( ! is_namespace_version )
|
85
88
|
db_connect( database_env )
|
@@ -88,14 +91,12 @@ module DataShift
|
|
88
91
|
@dslog.info "Booted Spree using pre 1.0.0 version"
|
89
92
|
else
|
90
93
|
|
91
|
-
|
92
|
-
#
|
93
|
-
|
94
|
-
gem('rails', '3.1.3')
|
94
|
+
|
95
|
+
#em('rails', rails_version)
|
95
96
|
|
96
|
-
db_connect( database_env
|
97
|
+
db_connect( database_env )#, rails_version )
|
97
98
|
|
98
|
-
@dslog.info "Booting Spree using
|
99
|
+
@dslog.info "Booting Spree using version #{SpreeHelper::version}"
|
99
100
|
|
100
101
|
require 'rails/all'
|
101
102
|
|
@@ -111,7 +112,7 @@ module DataShift
|
|
111
112
|
|
112
113
|
Dir.chdir( store_path )
|
113
114
|
|
114
|
-
@dslog.info "Booted Spree using
|
115
|
+
@dslog.info "Booted Spree using version #{SpreeHelper::version}"
|
115
116
|
end
|
116
117
|
end
|
117
118
|
|
data/lib/loaders/csv_loader.rb
CHANGED
@@ -16,6 +16,9 @@ module DataShift
|
|
16
16
|
|
17
17
|
include DataShift::Logging
|
18
18
|
|
19
|
+
# Options :
|
20
|
+
# strict : Raise exception if any column cannot be mapped
|
21
|
+
|
19
22
|
def perform_csv_load(file_name, options = {})
|
20
23
|
|
21
24
|
require "csv"
|
@@ -32,7 +35,7 @@ module DataShift
|
|
32
35
|
map_headers_to_operators( @parsed_file.shift, options[:strict] , @mandatory )
|
33
36
|
|
34
37
|
unless(@method_mapper.missing_methods.empty?)
|
35
|
-
|
38
|
+
logger.error("Following column headings could not be mapped :\n#{@method_mapper.missing_methods.inspect}")
|
36
39
|
raise MappingDefinitionError, "ERROR: Missing mappings for #{@method_mapper.missing_methods.size} column headings"
|
37
40
|
end
|
38
41
|
|
data/lib/loaders/loader_base.rb
CHANGED
@@ -113,10 +113,29 @@ module DataShift
|
|
113
113
|
reset(object)
|
114
114
|
end
|
115
115
|
|
116
|
+
|
117
|
+
# Based on filename call appropriate loading function
|
118
|
+
# Currently supports :
|
119
|
+
# Excel/Open Office files saved as .xls
|
120
|
+
# CSV files
|
121
|
+
#
|
122
|
+
# OPTIONS :
|
123
|
+
# strict : Raise exception if any column cannot be mapped
|
124
|
+
|
125
|
+
def perform_load( file_name, options = {} )
|
116
126
|
|
117
|
-
|
118
|
-
|
119
|
-
|
127
|
+
raise DataShift::BadFile, "Cannot load #{file_name} file not found." unless(File.exists?(file_name))
|
128
|
+
|
129
|
+
ext = File.extname(file_name)
|
130
|
+
|
131
|
+
if(ext.casecmp('.xls') == 0)
|
132
|
+
raise DataShift::BadRuby, "Please install and use JRuby for loading .xls files" unless(Guards::jruby?)
|
133
|
+
perform_excel_load(file_name, options)
|
134
|
+
elsif(ext.casecmp('.csv') == 0)
|
135
|
+
perform_csv_load(file_name, options)
|
136
|
+
else
|
137
|
+
raise DataShift::UnsupportedFileType, "#{ext} files not supported - Try .csv or OpenOffice/Excel .xls"
|
138
|
+
end
|
120
139
|
end
|
121
140
|
|
122
141
|
|
@@ -126,7 +145,7 @@ module DataShift
|
|
126
145
|
# This is then available through @method_mapper.method_details.each
|
127
146
|
#
|
128
147
|
# Options:
|
129
|
-
# strict :
|
148
|
+
# strict : Raise an exception of any headers can't be mapped to an attribute/association
|
130
149
|
#
|
131
150
|
def map_headers_to_operators( headers, strict, mandatory = [])
|
132
151
|
@headers = headers
|
@@ -134,6 +153,7 @@ module DataShift
|
|
134
153
|
begin
|
135
154
|
method_details = @method_mapper.map_inbound_to_methods( load_object_class, @headers )
|
136
155
|
rescue => e
|
156
|
+
puts e.inspect
|
137
157
|
logger.error("Failed to map header row to set of database operators : #{e.inspect}")
|
138
158
|
raise MappingDefinitionError, "Failed to map header row to set of database operators"
|
139
159
|
end
|
@@ -43,16 +43,20 @@ module DataShift
|
|
43
43
|
# Currently supports :
|
44
44
|
# Excel/Open Office files saved as .xls
|
45
45
|
# CSV files
|
46
|
+
#
|
47
|
+
# OPTIONS :
|
48
|
+
# strict : Raise exception if any column cannot be mapped
|
49
|
+
|
46
50
|
def perform_load( file_name, options = {} )
|
47
51
|
|
48
52
|
raise DataShift::BadFile, "Cannot load #{file_name} file not found." unless(File.exists?(file_name))
|
49
53
|
|
50
54
|
ext = File.extname(file_name)
|
51
55
|
|
52
|
-
if(ext
|
56
|
+
if(ext.casecmp('.xls') == 0)
|
53
57
|
raise DataShift::BadRuby, "Please install and use JRuby for loading .xls files" unless(Guards::jruby?)
|
54
58
|
perform_excel_load(file_name, options)
|
55
|
-
elsif(ext
|
59
|
+
elsif(ext.casecmp('.csv') == 0)
|
56
60
|
perform_csv_load(file_name, options)
|
57
61
|
else
|
58
62
|
raise DataShift::UnsupportedFileType, "#{ext} files not supported - Try .csv or OpenOffice/Excel .xls"
|
@@ -182,16 +186,35 @@ module DataShift
|
|
182
186
|
ovname.strip!
|
183
187
|
ov = @@option_value_klass.find_or_create_by_name_and_option_type_id(ovname, option_type.id)
|
184
188
|
if ov
|
185
|
-
|
186
|
-
|
187
|
-
|
189
|
+
begin
|
190
|
+
# This one line seems to works for 1.1.0 - 3.2 but not 1.0.0 - 3.1 ??
|
191
|
+
if(SpreeHelper::version.to_f >= 1.1)
|
192
|
+
variant = @load_object.variants.create( :sku => "#{@load_object.sku}_#{i}", :price => @load_object.price, :available_on => @load_object.available_on)
|
193
|
+
else
|
194
|
+
variant = @@variant_klass.create( :product => @load_object, :sku => "#{@load_object.sku}_#{i}", :price => @load_object.price, :available_on => @load_object.available_on)
|
195
|
+
#if(variant.valid?)
|
196
|
+
# variant.save
|
197
|
+
# @load_object.variants << variant
|
198
|
+
|
199
|
+
#else
|
200
|
+
#puts "WARNING: For Option #{ovname} - Variant creation failed #{variant.errors.inspect}"
|
201
|
+
end
|
202
|
+
variant.option_values << ov
|
203
|
+
rescue => e
|
204
|
+
puts "Failed to create a Variant for Product #{@load_object.name}"
|
205
|
+
puts e.inspect
|
206
|
+
puts e.backtrace
|
207
|
+
end
|
208
|
+
|
209
|
+
logger.debug "Created New Variant: #{variant.inspect}"
|
210
|
+
|
188
211
|
else
|
189
212
|
puts "WARNING: Option #{ovname} NOT FOUND - No Variant created"
|
190
213
|
end
|
191
214
|
end
|
192
215
|
|
193
216
|
#puts "DEBUG Load Object now has Variants : #{@load_object.variants.inspect}"
|
194
|
-
@load_object.reload
|
217
|
+
@load_object.reload unless @load_object.new_record?
|
195
218
|
#puts "DEBUG Load Object now has Variants : #{@load_object.variants.inspect}"
|
196
219
|
end
|
197
220
|
|
@@ -212,6 +235,7 @@ module DataShift
|
|
212
235
|
img_path, alt_text = image.split(LoaderBase::name_value_delim)
|
213
236
|
|
214
237
|
image = create_image(@@image_klass, img_path, @load_object, :alt => alt_text)
|
238
|
+
logger.debug("Product assigned an Image : #{image.inspect}")
|
215
239
|
end
|
216
240
|
|
217
241
|
end
|
@@ -233,10 +257,20 @@ module DataShift
|
|
233
257
|
|
234
258
|
unless property
|
235
259
|
property = @@property_klass.create( :name => pname, :presentation => pname.humanize)
|
260
|
+
logger.debug "Created New Property #{property.inspect}"
|
236
261
|
end
|
237
262
|
|
238
263
|
if(property)
|
239
|
-
|
264
|
+
if(SpreeHelper::version.to_f >= 1.1)
|
265
|
+
# Property now protected from mass assignment
|
266
|
+
x = @@product_property_klass.new( :value => pvalue )
|
267
|
+
x.property = property
|
268
|
+
x.save
|
269
|
+
logger.debug "Created New ProductProperty #{x.inspect}"
|
270
|
+
@load_object.product_properties << x
|
271
|
+
else
|
272
|
+
@load_object.product_properties << @@product_property_klass.create( :property => property, :value => pvalue)
|
273
|
+
end
|
240
274
|
else
|
241
275
|
puts "WARNING: Property #{pname} NOT found - Not set Product"
|
242
276
|
end
|
@@ -246,20 +280,6 @@ module DataShift
|
|
246
280
|
end
|
247
281
|
|
248
282
|
# Nested tree structure support ..
|
249
|
-
#
|
250
|
-
# ... inside of main loop
|
251
|
-
# the_taxons = []
|
252
|
-
# taxon_col.split(/[\r\n]+/).each do |chain|
|
253
|
-
# taxon = nil
|
254
|
-
# names = chain.split(/\s*>\s*/)
|
255
|
-
# names.each do |name|
|
256
|
-
# taxon = Taxon.find_or_create_by_name_and_parent_id_and_taxonomy_id(name, taxon && taxon.id, main_taxonomy.id)
|
257
|
-
# end
|
258
|
-
# the_taxons << taxon
|
259
|
-
# end
|
260
|
-
# p.taxons = the_taxons
|
261
|
-
|
262
|
-
|
263
283
|
# TAXON FORMAT
|
264
284
|
# name|name>child>child|name
|
265
285
|
|
@@ -302,7 +322,7 @@ module DataShift
|
|
302
322
|
|
303
323
|
unique_list = taxons.compact.uniq - (@load_object.taxons || [])
|
304
324
|
|
305
|
-
|
325
|
+
logger.debug("Product assigned to Taxons : #{unique_list.collect(&:name).inspect}")
|
306
326
|
@load_object.taxons << unique_list unless(unique_list.empty?)
|
307
327
|
end
|
308
328
|
|
@@ -0,0 +1,74 @@
|
|
1
|
+
# Copyright:: (c) Autotelik Media Ltd 2012
|
2
|
+
# Author :: Tom Statter
|
3
|
+
# Date :: April 2012
|
4
|
+
# License:: MIT.
|
5
|
+
#
|
6
|
+
# Usage::
|
7
|
+
#
|
8
|
+
# To pull Datashift commands into your main application :
|
9
|
+
#
|
10
|
+
# require 'datashift'
|
11
|
+
#
|
12
|
+
# DataShift::load_commands
|
13
|
+
#
|
14
|
+
# Cmd Line:
|
15
|
+
#
|
16
|
+
# => bundle exec thor datashift:export:excel -m <active record class> -r <output_template.xls> -a
|
17
|
+
#
|
18
|
+
require 'datashift'
|
19
|
+
|
20
|
+
# Note, not DataShift, case sensitive, create namespace for command line : datashift
|
21
|
+
module Datashift
|
22
|
+
|
23
|
+
|
24
|
+
class Export < Thor
|
25
|
+
|
26
|
+
include DataShift::Logging
|
27
|
+
|
28
|
+
desc "excel", "export any active record model (with optional associations)"
|
29
|
+
method_option :model, :aliases => '-m', :required => true, :desc => "The active record model to export"
|
30
|
+
method_option :result, :aliases => '-r', :required => true, :desc => "Create template of model in supplied file"
|
31
|
+
method_option :assoc, :aliases => '-a', :type => :boolean, :desc => "Include all associations in the template"
|
32
|
+
method_option :exclude, :aliases => '-e', :type => :array, :desc => "Use with -a : Exclude association types. Any from #{DataShift::MethodDetail::supported_types_enum.to_a.inspect}"
|
33
|
+
|
34
|
+
def excel()
|
35
|
+
|
36
|
+
# TODO - We're assuming run from a rails app/top level dir...
|
37
|
+
# ...can we make this more robust ? e.g what about when using active record but not in Rails app,
|
38
|
+
require File.expand_path('config/environment.rb')
|
39
|
+
|
40
|
+
require 'excel_exporter'
|
41
|
+
|
42
|
+
model = options[:model]
|
43
|
+
result = options[:result]
|
44
|
+
|
45
|
+
logger.info "Datashift: Start Excel export to #{result}"
|
46
|
+
|
47
|
+
begin
|
48
|
+
# support modules e.g "Spree::Property")
|
49
|
+
klass = ModelMapper::class_from_string(model) #Kernel.const_get(model)
|
50
|
+
rescue NameError => e
|
51
|
+
puts e
|
52
|
+
raise "ERROR: No such Model [#{model}] found - check valid model supplied via -model <Class>"
|
53
|
+
end
|
54
|
+
|
55
|
+
begin
|
56
|
+
gen = DataShift::ExcelExporter.new(result)
|
57
|
+
|
58
|
+
if(options[:assoc])
|
59
|
+
opts = (options[:exclude]) ? {:exclude => options[:exclude]} : {}
|
60
|
+
logger.info("Datashift: Exporting with associations")
|
61
|
+
gen.generate_with_associations(klass, opts)
|
62
|
+
else
|
63
|
+
gen.generate(klass)
|
64
|
+
end
|
65
|
+
rescue => e
|
66
|
+
puts e
|
67
|
+
puts e.backtrace
|
68
|
+
puts "Warning: Error during export, data may be incomplete"
|
69
|
+
end
|
70
|
+
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
end
|
@@ -12,6 +12,7 @@
|
|
12
12
|
|
13
13
|
# Note, not DataShift, case sensitive, create namespace for command line : datashift
|
14
14
|
module Datashift
|
15
|
+
|
15
16
|
|
16
17
|
class Spree < Thor
|
17
18
|
|
@@ -24,7 +25,7 @@ module Datashift
|
|
24
25
|
method_option :verbose, :aliases => '-v', :type => :boolean, :desc => "Verbose logging"
|
25
26
|
method_option :config, :aliases => '-c', :type => :string, :desc => "Configuration file containg defaults or over rides in YAML"
|
26
27
|
|
27
|
-
def products()
|
28
|
+
def products()
|
28
29
|
|
29
30
|
# TODO - We're assuming run from a rails app/top level dir...
|
30
31
|
# ...can we make this more robust ? e.g what about when using active record but not in Rails app,
|
data/spec/Gemfile
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
source 'https://rubygems.org'
|
2
|
+
|
3
|
+
gem 'rspec' # Behavior Driven Development (BDD) for Ruby
|
4
|
+
gem 'rspec-core' # RSpec runner and example groups.
|
5
|
+
gem 'rspec-expectations' # RSpec matchers for should and should_not.
|
6
|
+
gem 'rspec-mocks' # RSpec test double framework with stubbing and mocking.
|
7
|
+
gem 'rspec-rails' # RSpec version 2.x for Rails version 3.x.
|
8
|
+
gem 'activerecord-jdbcsqlite3-adapter'
|
9
|
+
|
10
|
+
# DEFINE WHICH VERSIONS WE WANT TO TEST WITH
|
11
|
+
|
12
|
+
#gem 'rails', '3.2.3'
|
13
|
+
#gem 'spree', '1.1.0'
|
14
|
+
|
15
|
+
gem 'rails', '3.1.3'
|
16
|
+
gem 'spree', '1.0.0'
|
17
|
+
|
18
|
+
|
data/spec/excel_exporter_spec.rb
CHANGED
@@ -9,7 +9,7 @@ require File.dirname(__FILE__) + '/spec_helper'
|
|
9
9
|
|
10
10
|
if(Guards::jruby?)
|
11
11
|
require 'erb'
|
12
|
-
require '
|
12
|
+
require 'excel_exporter'
|
13
13
|
|
14
14
|
include DataShift
|
15
15
|
|
@@ -37,37 +37,36 @@ if(Guards::jruby?)
|
|
37
37
|
MethodDictionary.find_operators( @assoc_klazz )
|
38
38
|
end
|
39
39
|
|
40
|
-
it "should be able to create a new excel
|
40
|
+
it "should be able to create a new excel exporter" do
|
41
41
|
generator = ExcelExporter.new( 'dummy.xls' )
|
42
42
|
|
43
43
|
generator.should_not be_nil
|
44
44
|
end
|
45
45
|
|
46
|
-
it "should
|
46
|
+
it "should export a model to .xls file" do
|
47
47
|
|
48
|
-
expect = result_file('
|
48
|
+
expect = result_file('project_export_spec.xls')
|
49
49
|
|
50
50
|
gen = ExcelExporter.new( expect )
|
51
51
|
|
52
|
-
gen.
|
52
|
+
gen.export(Project)
|
53
53
|
|
54
54
|
File.exists?(expect).should be_true
|
55
55
|
|
56
56
|
puts "Can manually check file @ #{expect}"
|
57
57
|
end
|
58
58
|
|
59
|
-
it "should export a
|
59
|
+
it "should export a model and associations to .xls file" do
|
60
60
|
|
61
61
|
Project.create( :value_as_string => 'Value as Text', :value_as_boolean => true, :value_as_double => 75.672)
|
62
|
-
#001 Demo string blah blah 2011-02-14 1.00 320.00
|
63
62
|
|
64
|
-
expect= result_file('
|
63
|
+
expect= result_file('project_plus_assoc_export_spec.xls')
|
65
64
|
|
66
|
-
gen =
|
65
|
+
gen = ExcelExporter.new(expect)
|
67
66
|
|
68
67
|
items = Project.all
|
69
68
|
|
70
|
-
gen.
|
69
|
+
gen.export_with_associations(Project, items)
|
71
70
|
|
72
71
|
File.exists?(expect).should be_true
|
73
72
|
|
@@ -56,18 +56,13 @@ if(Guards::jruby?)
|
|
56
56
|
puts "Can manually check file @ #{expect}"
|
57
57
|
end
|
58
58
|
|
59
|
-
it "should
|
59
|
+
it "should genrate a complex template .xls file from model" do
|
60
60
|
|
61
|
-
|
62
|
-
#001 Demo string blah blah 2011-02-14 1.00 320.00
|
63
|
-
|
64
|
-
expect= result_file('simple_export_spec.xls')
|
61
|
+
expect= result_file('project_plus_assoc_template_spec.xls')
|
65
62
|
|
66
63
|
gen = ExcelGenerator.new(expect)
|
67
64
|
|
68
|
-
|
69
|
-
|
70
|
-
gen.export(items)
|
65
|
+
gen.generate_with_associations(Project)
|
71
66
|
|
72
67
|
File.exists?(expect).should be_true
|
73
68
|
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
data/spec/spec_helper.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
|
-
|
2
|
-
require '
|
1
|
+
|
2
|
+
require 'stringio'
|
3
3
|
|
4
4
|
require File.dirname(__FILE__) + '/../lib/datashift'
|
5
5
|
|
@@ -14,17 +14,21 @@ include DataShift
|
|
14
14
|
#
|
15
15
|
#
|
16
16
|
# We are not setup as a Rails project so need to mimic an active record database setup so
|
17
|
-
# we have some AR models
|
17
|
+
# we have some AR models to test against. Create an in memory database from scratch.
|
18
18
|
#
|
19
19
|
$DataShiftFixturePath = File.join(File.dirname(__FILE__), 'fixtures')
|
20
20
|
$DataShiftDatabaseYml = File.join($DataShiftFixturePath, 'config/database.yml')
|
21
21
|
|
22
22
|
module DataShift
|
23
23
|
|
24
|
-
def db_connect( env = 'test_file'
|
24
|
+
def db_connect( env = 'test_file')
|
25
|
+
|
26
|
+
gemfile = File.join(DataShift::root_path, 'spec', 'Gemfile')
|
27
|
+
|
28
|
+
ENV['BUNDLE_GEMFILE'] = gemfile
|
29
|
+
require 'bundler'
|
30
|
+
Bundler.setup
|
25
31
|
|
26
|
-
version ? gem('activerecord', version) : gem('activerecord')
|
27
|
-
|
28
32
|
require 'active_record'
|
29
33
|
|
30
34
|
# Some active record stuff seems to rely on the RAILS_ENV being set ?
|
@@ -41,13 +45,13 @@ module DataShift
|
|
41
45
|
|
42
46
|
#dbtype = Rails.configuration.database_configuration[Rails.env]['adapter'].to_sym
|
43
47
|
|
44
|
-
#ActiveRecord::Base.logger = Logger.new(STDOUT)
|
45
|
-
|
46
48
|
require 'logger'
|
47
49
|
logdir = File.dirname(__FILE__) + '/logs'
|
48
50
|
FileUtils.mkdir_p(logdir) unless File.exists?(logdir)
|
49
51
|
ActiveRecord::Base.logger = Logger.new(logdir + '/datashift_spec.log')
|
50
52
|
|
53
|
+
# Anyway to direct one logger to another ????? ... Logger.new(STDOUT)
|
54
|
+
|
51
55
|
@dslog = ActiveRecord::Base.logger
|
52
56
|
|
53
57
|
puts "Connecting to DB"
|
@@ -57,6 +61,8 @@ module DataShift
|
|
57
61
|
# so copied this from ... Rails::Initializer.initialize_cache
|
58
62
|
Object.const_set "RAILS_CACHE", ActiveSupport::Cache.lookup_store( :memory_store )
|
59
63
|
|
64
|
+
puts "Connected to DB"
|
65
|
+
|
60
66
|
@dslog.info "Connected to DB - #{ActiveRecord::Base.connection.inspect}"
|
61
67
|
end
|
62
68
|
|
@@ -100,6 +106,8 @@ end
|
|
100
106
|
|
101
107
|
module SpecHelper
|
102
108
|
|
109
|
+
# VERSIONS of Spree (1.1.0.rc1, 1.0.0, 0.11.2)
|
110
|
+
|
103
111
|
$SpreeFixturePath = File.join($DataShiftFixturePath, 'spree')
|
104
112
|
$SpreeNegativeFixturePath = File.join($DataShiftFixturePath, 'negative')
|
105
113
|
|
@@ -108,11 +116,14 @@ module SpecHelper
|
|
108
116
|
end
|
109
117
|
|
110
118
|
def self.before_all_spree
|
119
|
+
|
111
120
|
# we are not a Spree project, nor is it practical to externally generate
|
112
121
|
# a complete Spree application for testing so we implement a mini migrate/boot of our own
|
113
|
-
SpreeHelper.load()
|
114
|
-
SpreeHelper.boot(
|
122
|
+
SpreeHelper.load()
|
123
|
+
SpreeHelper.boot('test_spree_standalone') # key to YAML db e.g test_memory, test_mysql
|
115
124
|
|
125
|
+
puts "Testing Spree standalone - version #{SpreeHelper::version}"
|
126
|
+
|
116
127
|
SpreeHelper.migrate_up # create an sqlite Spree database on the fly
|
117
128
|
end
|
118
129
|
|
@@ -136,6 +147,19 @@ module SpecHelper
|
|
136
147
|
|
137
148
|
end
|
138
149
|
|
150
|
+
def capture(stream)
|
151
|
+
begin
|
152
|
+
stream = stream.to_s
|
153
|
+
eval "$#{stream} = StringIO.new"
|
154
|
+
yield
|
155
|
+
result = eval("$#{stream}").string
|
156
|
+
ensure
|
157
|
+
eval("$#{stream} = #{stream.upcase}")
|
158
|
+
end
|
159
|
+
|
160
|
+
result
|
161
|
+
end
|
162
|
+
|
139
163
|
RSpec.configure do |config|
|
140
164
|
# config.use_transactional_fixtures = true
|
141
165
|
# config.use_instantiated_fixtures = false
|
data/spec/spree_exporter_spec.rb
CHANGED
@@ -12,7 +12,7 @@
|
|
12
12
|
require File.dirname(__FILE__) + '/spec_helper'
|
13
13
|
|
14
14
|
require 'spree_helper'
|
15
|
-
require '
|
15
|
+
require 'excel_exporter'
|
16
16
|
|
17
17
|
include DataShift
|
18
18
|
|
@@ -20,6 +20,7 @@ describe 'SpreeLoader' do
|
|
20
20
|
|
21
21
|
before(:all) do
|
22
22
|
SpecHelper::before_all_spree
|
23
|
+
results_clear()
|
23
24
|
end
|
24
25
|
|
25
26
|
before do
|
@@ -29,36 +30,38 @@ describe 'SpreeLoader' do
|
|
29
30
|
|
30
31
|
before_each_spree # inits tests, cleans DB setups model types
|
31
32
|
|
33
|
+
@Taxon_klass.delete_all
|
34
|
+
|
32
35
|
# Create some test data
|
33
36
|
root = @Taxonomy_klass.create( :name => 'Paintings' )
|
34
37
|
|
35
|
-
@Taxon_klass.create( :name => 'Landscape', :
|
36
|
-
@Taxon_klass.create( :name => 'Sea', :
|
38
|
+
@Taxon_klass.create( :name => 'Landscape', :description => "Nice paintings", :taxonomy_id => root.id )
|
39
|
+
@Taxon_klass.create( :name => 'Sea', :description => "Waves and sand", :taxonomy_id => root.id )
|
37
40
|
|
38
41
|
end
|
39
42
|
|
40
43
|
it "should export any Spree model to .xls spreedsheet" do
|
41
44
|
|
42
|
-
expect = result_file('
|
45
|
+
expect = result_file('taxon_export_spec.xls')
|
43
46
|
|
44
|
-
|
47
|
+
exporter = ExcelExporter.new(expect)
|
45
48
|
|
46
|
-
items = @
|
49
|
+
items = @Taxon_klass.all
|
47
50
|
|
48
|
-
|
51
|
+
exporter.export(items)
|
49
52
|
|
50
53
|
File.exists?(expect).should be_true
|
51
54
|
end
|
52
55
|
|
53
56
|
it "should export a Spree model and associations to .xls spreedsheet" do
|
54
57
|
|
55
|
-
expect = result_file('
|
58
|
+
expect = result_file('taxon_and_assoc_export_spec.xls')
|
56
59
|
|
57
|
-
|
60
|
+
exporter = ExcelExporter.new(expect)
|
58
61
|
|
59
|
-
items = @
|
62
|
+
items = @Taxon_klass.all
|
60
63
|
|
61
|
-
|
64
|
+
exporter.export_with_associations(@Taxon_klass, items)
|
62
65
|
|
63
66
|
File.exists?(expect).should be_true
|
64
67
|
|
@@ -45,29 +45,45 @@ describe 'SpreeLoader' do
|
|
45
45
|
end
|
46
46
|
|
47
47
|
|
48
|
-
it "should load Products with associated image" do
|
48
|
+
it "should load Products with associated image from CSV" do
|
49
|
+
|
50
|
+
# In >= 1.1.0 Image moved to master Variant from Product
|
51
|
+
if(SpreeHelper::version.to_f < 1.1)
|
49
52
|
|
50
|
-
|
53
|
+
@product_loader.perform_load( SpecHelper::spree_fixture('SpreeProductsWithImages.csv'), :mandatory => ['sku', 'name', 'price'] )
|
51
54
|
|
52
|
-
|
55
|
+
p = @klass.find_by_name("Demo Product for AR Loader")
|
53
56
|
|
54
|
-
|
55
|
-
|
57
|
+
p.name.should == "Demo Product for AR Loader"
|
58
|
+
p.images.should have_exactly(1).items
|
56
59
|
|
57
|
-
|
60
|
+
@klass.all.each {|p| p.images.should have_exactly(1).items }
|
61
|
+
end
|
58
62
|
end
|
59
63
|
|
60
64
|
|
61
|
-
it "should
|
65
|
+
it "should load Products with associated image", :fail => true do
|
66
|
+
|
67
|
+
if(SpreeHelper::version.to_f < 1.1)
|
68
|
+
@product_loader.perform_load( SpecHelper::spree_fixture('SpreeProductsWithImages.xls'), :mandatory => ['sku', 'name', 'price'] )
|
69
|
+
|
70
|
+
p = @klass.find_by_name("Demo Product for AR Loader")
|
62
71
|
|
63
|
-
|
64
|
-
|
65
|
-
@Image_klass.all.size.should == 0
|
72
|
+
p.name.should == "Demo Product for AR Loader"
|
73
|
+
p.images.should have_exactly(1).items
|
66
74
|
|
67
|
-
|
75
|
+
@klass.all.each {|p| p.images.should have_exactly(1).items }
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
it "should be able to assign Images to preloaded Products" do
|
68
80
|
|
81
|
+
@Image_klass.all.size.should == 0
|
82
|
+
|
69
83
|
loader = DataShift::SpreeHelper::ImageLoader.new
|
70
84
|
|
85
|
+
loader.perform_load( SpecHelper::spree_fixture('SpreeProductImages.xls') )
|
86
|
+
|
71
87
|
end
|
72
88
|
|
73
89
|
end
|
data/spec/spree_loader_spec.rb
CHANGED
@@ -32,17 +32,19 @@ describe 'SpreeLoader' do
|
|
32
32
|
|
33
33
|
before_each_spree
|
34
34
|
|
35
|
-
@
|
35
|
+
@Product_klass.count.should == 0
|
36
36
|
@Taxon_klass.count.should == 0
|
37
37
|
@Variant_klass.count.should == 0
|
38
38
|
|
39
39
|
MethodDictionary.clear
|
40
|
-
MethodDictionary.find_operators( @
|
40
|
+
MethodDictionary.find_operators( @Product_klass )
|
41
41
|
|
42
42
|
# want to test both lookup and dynamic creation - this Taxonomy should be found, rest created
|
43
43
|
root = @Taxonomy_klass.create( :name => 'Paintings' )
|
44
44
|
|
45
|
-
@Taxon_klass.
|
45
|
+
t = @Taxon_klass.new( :name => 'Landscape' )
|
46
|
+
t.taxonomy = root
|
47
|
+
t.save
|
46
48
|
|
47
49
|
@Taxon_klass.count.should == 2
|
48
50
|
|
@@ -99,14 +101,14 @@ describe 'SpreeLoader' do
|
|
99
101
|
|
100
102
|
@product_loader.perform_load( SpecHelper::spree_fixture(source), :mandatory => ['sku', 'name', 'price'] )
|
101
103
|
|
102
|
-
@
|
104
|
+
@Product_klass.count.should == 3
|
103
105
|
|
104
106
|
@product_loader.failed_objects.size.should == 0
|
105
107
|
@product_loader.loaded_objects.size.should == 3
|
106
108
|
|
107
|
-
@product_loader.loaded_count.should == @
|
109
|
+
@product_loader.loaded_count.should == @Product_klass.count
|
108
110
|
|
109
|
-
p = @
|
111
|
+
p = @Product_klass.first
|
110
112
|
|
111
113
|
p.sku.should == "SIMPLE_001"
|
112
114
|
p.price.should == 345.78
|
@@ -116,7 +118,7 @@ describe 'SpreeLoader' do
|
|
116
118
|
p.option_types.should have_exactly(1).items
|
117
119
|
p.option_types.should have_exactly(1).items
|
118
120
|
p.count_on_hand.should == 12
|
119
|
-
@
|
121
|
+
@Product_klass.last.count_on_hand.should == 23
|
120
122
|
end
|
121
123
|
|
122
124
|
|
@@ -149,16 +151,16 @@ describe 'SpreeLoader' do
|
|
149
151
|
def test_default_values
|
150
152
|
@product_loader.perform_load( SpecHelper::spree_fixture('SpreeProductsMandatoryOnly.xls'), :mandatory => ['sku', 'name', 'price'] )
|
151
153
|
|
152
|
-
@
|
154
|
+
@Product_klass.count.should == 3
|
153
155
|
|
154
156
|
@product_loader.failed_objects.size.should == 0
|
155
157
|
@product_loader.loaded_objects.size.should == 3
|
156
158
|
|
157
|
-
p = @
|
159
|
+
p = @Product_klass.first
|
158
160
|
|
159
161
|
p.sku.should == "SPEC_SIMPLE_001"
|
160
162
|
|
161
|
-
@
|
163
|
+
@Product_klass.all { |p|
|
162
164
|
p.sku.should.include "SPEC_"
|
163
165
|
p.cost_price = 1.0
|
164
166
|
p.available_on.should == @expected_time
|
@@ -180,7 +182,7 @@ describe 'SpreeLoader' do
|
|
180
182
|
end
|
181
183
|
|
182
184
|
def test_variants_creation( source )
|
183
|
-
@
|
185
|
+
@Product_klass.count.should == 0
|
184
186
|
@Variant_klass.count.should == 0
|
185
187
|
|
186
188
|
@product_loader.perform_load( SpecHelper::spree_fixture(source), :mandatory => ['sku', 'name', 'price'] )
|
@@ -192,10 +194,10 @@ describe 'SpreeLoader' do
|
|
192
194
|
def expected_multi_column_variants
|
193
195
|
|
194
196
|
# 3 MASTER products, 11 VARIANTS
|
195
|
-
@
|
197
|
+
@Product_klass.count.should == 3
|
196
198
|
@Variant_klass.count.should == 14
|
197
199
|
|
198
|
-
p = @
|
200
|
+
p = @Product_klass.first
|
199
201
|
|
200
202
|
p.sku.should == "DEMO_001"
|
201
203
|
|
@@ -204,7 +206,7 @@ describe 'SpreeLoader' do
|
|
204
206
|
p.description.should == "blah blah"
|
205
207
|
p.cost_price.should == 320.00
|
206
208
|
|
207
|
-
@
|
209
|
+
@Product_klass.all.select {|m| m.is_master.should == true }
|
208
210
|
|
209
211
|
|
210
212
|
# mime_type:jpeg mime_type:PDF mime_type:PNG
|
@@ -281,12 +283,12 @@ describe 'SpreeLoader' do
|
|
281
283
|
|
282
284
|
def expected_multi_column_properties
|
283
285
|
# 3 MASTER products, 11 VARIANTS
|
284
|
-
@
|
286
|
+
@Product_klass.count.should == 3
|
285
287
|
@Variant_klass.count.should == 14
|
286
288
|
|
287
|
-
@
|
289
|
+
@Product_klass.first.properties.should have_exactly(1).items
|
288
290
|
|
289
|
-
p3 = @
|
291
|
+
p3 = @Product_klass.all.last
|
290
292
|
|
291
293
|
p3.properties.should have_exactly(3).items
|
292
294
|
|
@@ -304,7 +306,7 @@ describe 'SpreeLoader' do
|
|
304
306
|
# Operation and results should be identical when loading multiple associations
|
305
307
|
# if using either single column embedded syntax, or one column per entry.
|
306
308
|
|
307
|
-
it "should load Products and multiple Taxons from single column", :
|
309
|
+
it "should load Products and multiple Taxons from single column", :taxons => true do
|
308
310
|
test_taxon_creation( 'SpreeProducts.xls' )
|
309
311
|
end
|
310
312
|
|
@@ -329,7 +331,7 @@ describe 'SpreeLoader' do
|
|
329
331
|
#puts @Taxonomy_klass.all.collect( &:name).inspect
|
330
332
|
#puts @Taxon_klass.all.collect( &:name).inspect
|
331
333
|
|
332
|
-
# Paintings
|
334
|
+
# Paintings already existed and had 1 child Taxon (Landscape)
|
333
335
|
# 2 nested Taxon (Paintings>Nature>Seascape) created under it so expect Taxonomy :
|
334
336
|
|
335
337
|
# WaterColour
|
@@ -340,13 +342,16 @@ describe 'SpreeLoader' do
|
|
340
342
|
@Taxonomy_klass.count.should == 4
|
341
343
|
@Taxon_klass.count.should == 7
|
342
344
|
|
343
|
-
@
|
344
|
-
@
|
345
|
+
@Product_klass.first.taxons.should have_exactly(2).items
|
346
|
+
@Product_klass.last.taxons.should have_exactly(2).items
|
345
347
|
|
346
348
|
p2 = @Variant_klass.find_by_sku("DEMO_002").product
|
347
349
|
|
348
350
|
# Paintings Oils Paintings>Nature>Seascape
|
349
351
|
|
352
|
+
# ["Nature", "Paintings", "Seascape"]
|
353
|
+
|
354
|
+
|
350
355
|
#puts p2.taxons.collect(&:name).inspect
|
351
356
|
|
352
357
|
p2.taxons.should have_exactly(4).items
|
@@ -354,7 +359,10 @@ describe 'SpreeLoader' do
|
|
354
359
|
p2.taxons.collect(&:name).sort.should == ['Nature','Oils','Paintings','Seascape']
|
355
360
|
|
356
361
|
paint_parent = @Taxonomy_klass.find_by_name('Paintings')
|
357
|
-
|
362
|
+
|
363
|
+
|
364
|
+
puts paint_parent.taxons.collect(&:name).sort.inspect
|
365
|
+
|
358
366
|
paint_parent.taxons.should have_exactly(4).items # 3 children + all Taxonomies have a root Taxon
|
359
367
|
|
360
368
|
paint_parent.taxons.collect(&:name).sort.should == ['Landscape','Nature','Paintings','Seascape']
|
@@ -367,16 +375,13 @@ describe 'SpreeLoader' do
|
|
367
375
|
|
368
376
|
p2.taxons.collect( &:id ).should include(ts.id)
|
369
377
|
p2.taxons.collect( &:id ).should include(tn.id)
|
370
|
-
|
371
|
-
puts tn.inspect
|
372
|
-
puts ts.inspect
|
378
|
+
|
373
379
|
|
374
380
|
tn.parent.id.should == paint_parent.root.id
|
375
381
|
ts.parent.id.should == tn.id
|
376
382
|
|
377
383
|
tn.children.should have_exactly(1).items
|
378
384
|
ts.children.should have_exactly(0).items
|
379
|
-
|
380
385
|
|
381
386
|
end
|
382
387
|
|
@@ -392,7 +397,7 @@ describe 'SpreeLoader' do
|
|
392
397
|
end
|
393
398
|
|
394
399
|
|
395
|
-
it "should load Products from multiple column csv as per .xls" do
|
400
|
+
it "should load Products from multiple column csv as per .xls", :blah => true do
|
396
401
|
test_variants_creation('SpreeProductsMultiColumn.csv')
|
397
402
|
|
398
403
|
expected_multi_column_properties
|
data/spec/thor_spec.rb
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
# Copyright:: (c) Autotelik Media Ltd 2012
|
2
|
+
# Author :: Tom Statter
|
3
|
+
# Date :: April 20121
|
4
|
+
#
|
5
|
+
# License:: MIT - Free, OpenSource
|
6
|
+
#
|
7
|
+
# Details:: Specification for Thor tasks supplied with datashift
|
8
|
+
#
|
9
|
+
require 'thor'
|
10
|
+
require 'thor/group'
|
11
|
+
|
12
|
+
|
13
|
+
require File.dirname(__FILE__) + '/spec_helper'
|
14
|
+
|
15
|
+
require 'spree_helper'
|
16
|
+
|
17
|
+
load 'products_images.thor'
|
18
|
+
|
19
|
+
include DataShift
|
20
|
+
|
21
|
+
describe 'Thor high level command line tasks' do
|
22
|
+
|
23
|
+
before(:each) do
|
24
|
+
end
|
25
|
+
|
26
|
+
|
27
|
+
it "should be able to run spree loaders from a simple command line task" do
|
28
|
+
Datashift::Spree.start(["products"])
|
29
|
+
end
|
30
|
+
|
31
|
+
|
32
|
+
end
|
metadata
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
name: datashift
|
3
3
|
version: !ruby/object:Gem::Version
|
4
4
|
prerelease:
|
5
|
-
version: 0.
|
5
|
+
version: 0.5.0
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Thomas Statter
|
@@ -10,7 +10,7 @@ autorequire:
|
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
12
|
|
13
|
-
date: 2012-
|
13
|
+
date: 2012-05-08 00:00:00 Z
|
14
14
|
dependencies: []
|
15
15
|
|
16
16
|
description: A suite of tools to move data between ActiveRecord models,databases,applications like Excel/Open Office, files and projects including Spree
|
@@ -30,6 +30,7 @@ files:
|
|
30
30
|
- README.rdoc
|
31
31
|
- Rakefile
|
32
32
|
- VERSION
|
33
|
+
- datashift-0.5.0.gem
|
33
34
|
- datashift.gemspec
|
34
35
|
- lib/applications/jruby/jexcel_file.rb
|
35
36
|
- lib/applications/jruby/word.rb
|
@@ -74,6 +75,7 @@ files:
|
|
74
75
|
- lib/loaders/spreadsheet_loader.rb
|
75
76
|
- lib/loaders/spree/image_loader.rb
|
76
77
|
- lib/loaders/spree/product_loader.rb
|
78
|
+
- lib/thor/export_excel.thor
|
77
79
|
- lib/thor/generate_excel.thor
|
78
80
|
- lib/thor/import_excel.thor
|
79
81
|
- lib/thor/spree/bootstrap_cleanup.thor
|
@@ -98,6 +100,7 @@ files:
|
|
98
100
|
- sandbox/config/database.yml
|
99
101
|
- sandbox/config/environment.rb
|
100
102
|
- sandbox/config/environments/development.rb
|
103
|
+
- spec/Gemfile
|
101
104
|
- spec/csv_loader_spec.rb
|
102
105
|
- spec/datashift_spec.rb
|
103
106
|
- spec/db/migrate/20110803201325_create_test_bed.rb
|
@@ -119,13 +122,13 @@ files:
|
|
119
122
|
- spec/fixtures/images/DEMO_002_Powerstation.jpg
|
120
123
|
- spec/fixtures/images/DEMO_003_ror_mug.jpeg
|
121
124
|
- spec/fixtures/images/DEMO_004_ror_ringer.jpeg
|
122
|
-
- spec/fixtures/interact_models_db.sqlite
|
123
125
|
- spec/fixtures/negative/SpreeProdMiss1Mandatory.csv
|
124
126
|
- spec/fixtures/negative/SpreeProdMiss1Mandatory.xls
|
125
127
|
- spec/fixtures/negative/SpreeProdMissManyMandatory.csv
|
126
128
|
- spec/fixtures/negative/SpreeProdMissManyMandatory.xls
|
127
129
|
- spec/fixtures/simple_export_spec.xls
|
128
130
|
- spec/fixtures/simple_template_spec.xls
|
131
|
+
- spec/fixtures/spree/SpreeProductImages.xls
|
129
132
|
- spec/fixtures/spree/SpreeProducts.csv
|
130
133
|
- spec/fixtures/spree/SpreeProducts.xls
|
131
134
|
- spec/fixtures/spree/SpreeProductsDefaults.yml
|
@@ -148,6 +151,7 @@ files:
|
|
148
151
|
- spec/spree_images_loader_spec.rb
|
149
152
|
- spec/spree_loader_spec.rb
|
150
153
|
- spec/spree_method_mapping_spec.rb
|
154
|
+
- spec/thor_spec.rb
|
151
155
|
- tasks/config/seed_fu_product_template.erb
|
152
156
|
- tasks/config/tidy_config.txt
|
153
157
|
- tasks/export/excel_generator.rake
|
Binary file
|