datashift 0.4.3 → 0.5.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.
- 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
|