datashift 0.0.2 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.markdown +13 -12
- data/Rakefile +8 -8
- data/VERSION +1 -5
- data/datashift.gemspec +12 -38
- data/lib/applications/jruby/jexcel_file.rb +23 -11
- data/lib/datashift/method_detail.rb +44 -5
- data/lib/datashift/method_dictionary.rb +210 -0
- data/lib/datashift/method_mapper.rb +25 -191
- data/lib/generators/excel_generator.rb +12 -11
- data/lib/helpers/spree_helper.rb +36 -12
- data/lib/loaders/excel_loader.rb +2 -1
- data/lib/loaders/loader_base.rb +37 -20
- data/lib/loaders/spree/image_loader.rb +35 -16
- data/lib/loaders/spree/product_loader.rb +27 -1
- data/spec/csv_loader_spec.rb +3 -3
- data/spec/excel_exporter_spec.rb +79 -0
- data/spec/excel_generator_spec.rb +3 -3
- data/spec/excel_loader_spec.rb +35 -16
- data/spec/fixtures/ProjectsMultiCategoriesHeaderLookup.xls +0 -0
- data/spec/fixtures/images/DEMO_001_ror_bag.jpeg +0 -0
- data/spec/fixtures/images/DEMO_002_Powerstation.jpg +0 -0
- data/spec/fixtures/images/DEMO_003_ror_mug.jpeg +0 -0
- data/spec/fixtures/images/DEMO_004_ror_ringer.jpeg +0 -0
- data/spec/fixtures/interact_models_db.sqlite +0 -0
- data/spec/fixtures/interact_spree_db.sqlite +0 -0
- data/spec/fixtures/spree/SpreeProductsWithImages.xls +0 -0
- data/spec/loader_spec.rb +4 -4
- data/spec/method_dictionary_spec.rb +243 -0
- data/spec/method_mapper_spec.rb +17 -213
- data/spec/spec_helper.rb +1 -0
- data/spec/spree_loader_spec.rb +18 -1
- data/spec/spree_method_mapping_spec.rb +4 -4
- metadata +14 -130
- data/Gemfile +0 -28
- data/spec/fixtures/.~lock.ProjectsSingleCategories.xls# +0 -1
@@ -7,39 +7,58 @@ require 'loader_base'
|
|
7
7
|
|
8
8
|
module DataShift
|
9
9
|
|
10
|
-
|
11
|
-
|
12
|
-
def initialize(image = nil)
|
13
|
-
super( Image, image )
|
14
|
-
raise "Failed to create Image for loading" unless @load_object
|
15
|
-
end
|
10
|
+
module ImageLoading
|
16
11
|
|
12
|
+
|
17
13
|
# Note the Spree Image model sets default storage path to
|
18
14
|
# => :path => ":rails_root/public/assets/products/:id/:style/:basename.:extension"
|
19
15
|
|
20
|
-
def
|
16
|
+
def create(image_path, viewable_record = nil, options = {})
|
21
17
|
|
18
|
+
image = Image.new
|
19
|
+
|
22
20
|
unless File.exists?(image_path)
|
23
21
|
puts "ERROR : Invalid Path"
|
24
|
-
return
|
22
|
+
return image
|
25
23
|
end
|
26
24
|
|
27
|
-
alt = (
|
28
|
-
|
29
|
-
|
25
|
+
alt = if(options[:alt])
|
26
|
+
options[:alt]
|
27
|
+
else
|
28
|
+
(viewable_record and viewable_record.respond_to? :name) ? viewable_record.name : ""
|
29
|
+
end
|
30
|
+
|
31
|
+
image.alt = alt
|
30
32
|
|
31
33
|
begin
|
32
|
-
|
34
|
+
image.attachment = File.new(image_path, "r")
|
33
35
|
rescue => e
|
34
36
|
puts e.inspect
|
35
37
|
puts "ERROR : Failed to read image #{image_path}"
|
36
|
-
return
|
38
|
+
return image
|
37
39
|
end
|
38
40
|
|
39
|
-
|
40
|
-
|
41
|
+
image.attachment.reprocess!
|
42
|
+
image.viewable = viewable_record if viewable_record
|
43
|
+
|
44
|
+
puts image.save ? "Success: Crteated Image: #{image.inspect}" : "ERROR : Problem saving to DB Image: #{image.inspect}"
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
class ImageLoader < LoaderBase
|
49
|
+
|
50
|
+
include DataShift::ImageLoading
|
51
|
+
|
52
|
+
def initialize(image = nil)
|
53
|
+
super( Image, image )
|
54
|
+
raise "Failed to create Image for loading" unless @load_object
|
55
|
+
end
|
41
56
|
|
42
|
-
|
57
|
+
# Note the Spree Image model sets default storage path to
|
58
|
+
# => :path => ":rails_root/public/assets/products/:id/:style/:basename.:extension"
|
59
|
+
|
60
|
+
def process( image_path, record = nil)
|
61
|
+
@load_object = create_image(path, record)
|
43
62
|
end
|
44
63
|
end
|
45
64
|
|
@@ -6,8 +6,9 @@
|
|
6
6
|
# Details:: Specific over-rides/additions to support Spree Products
|
7
7
|
#
|
8
8
|
require 'loader_base'
|
9
|
-
require 'excel_loader'
|
10
9
|
require 'csv_loader'
|
10
|
+
require 'excel_loader'
|
11
|
+
require 'image_loader'
|
11
12
|
|
12
13
|
module DataShift
|
13
14
|
|
@@ -17,6 +18,7 @@ module DataShift
|
|
17
18
|
|
18
19
|
include DataShift::CsvLoading
|
19
20
|
include DataShift::ExcelLoading
|
21
|
+
include DataShift::ImageLoading
|
20
22
|
|
21
23
|
def initialize(product = nil)
|
22
24
|
super( Product, product, :instance_methods => true )
|
@@ -63,6 +65,10 @@ module DataShift
|
|
63
65
|
elsif(@current_method_detail.operator?('product_properties') && current_value)
|
64
66
|
|
65
67
|
add_properties
|
68
|
+
|
69
|
+
elsif(@current_method_detail.operator?('images') && current_value)
|
70
|
+
|
71
|
+
add_images
|
66
72
|
|
67
73
|
elsif(@current_method_detail.operator?('count_on_hand') || @current_method_detail.operator?('on_hand') )
|
68
74
|
|
@@ -150,7 +156,27 @@ module DataShift
|
|
150
156
|
|
151
157
|
end
|
152
158
|
|
159
|
+
|
160
|
+
# Special case for Images
|
161
|
+
# A list of paths to Images with a optional 'alt' value - supplied in form :
|
162
|
+
# path:alt|path2:alt2|path_3:alt3 etc
|
163
|
+
#
|
164
|
+
def add_images
|
165
|
+
# TODO smart column ordering to ensure always valid by time we get to associations
|
166
|
+
save_if_new
|
167
|
+
|
168
|
+
images = current_value.split(LoaderBase::multi_assoc_delim)
|
153
169
|
|
170
|
+
images.each do |image|
|
171
|
+
|
172
|
+
img_path, alt_text = image.split(LoaderBase::name_value_delim)
|
173
|
+
|
174
|
+
image = create_image(img_path, @load_object, :alt => alt_text)
|
175
|
+
end
|
176
|
+
|
177
|
+
end
|
178
|
+
|
179
|
+
|
154
180
|
# Special case for ProductProperties since it can have additional value applied.
|
155
181
|
# A list of Properties with a optional Value - supplied in form :
|
156
182
|
# property.name:value|property.name|property.name:value
|
data/spec/csv_loader_spec.rb
CHANGED
@@ -23,9 +23,9 @@ describe 'CSV Loader' do
|
|
23
23
|
end
|
24
24
|
|
25
25
|
before(:each) do
|
26
|
-
|
27
|
-
|
28
|
-
|
26
|
+
MethodDictionary.clear
|
27
|
+
MethodDictionary.find_operators( @klazz )
|
28
|
+
MethodDictionary.find_operators( @assoc_klazz )
|
29
29
|
end
|
30
30
|
|
31
31
|
end
|
@@ -0,0 +1,79 @@
|
|
1
|
+
# Copyright:: (c) Autotelik Media Ltd 2011
|
2
|
+
# Author :: Tom Statter
|
3
|
+
# Date :: Aug 2011
|
4
|
+
# License:: MIT
|
5
|
+
#
|
6
|
+
# Details:: Specs for Excel aspect of Active Record Loader
|
7
|
+
#
|
8
|
+
require File.dirname(__FILE__) + '/spec_helper'
|
9
|
+
|
10
|
+
if(Guards::jruby?)
|
11
|
+
require 'erb'
|
12
|
+
require 'excel_generator'
|
13
|
+
|
14
|
+
include DataShift
|
15
|
+
|
16
|
+
describe 'Excel Generator' do
|
17
|
+
|
18
|
+
before(:all) do
|
19
|
+
db_connect( 'test_file' ) # , test_memory, test_mysql
|
20
|
+
|
21
|
+
# load our test model definitions - Project etc
|
22
|
+
require File.join($DataShiftFixturePath, 'test_model_defs')
|
23
|
+
|
24
|
+
# handle migration changes or reset of test DB
|
25
|
+
migrate_up
|
26
|
+
|
27
|
+
db_clear() # todo read up about proper transactional fixtures
|
28
|
+
results_clear()
|
29
|
+
|
30
|
+
@klazz = Project
|
31
|
+
@assoc_klazz = Category
|
32
|
+
end
|
33
|
+
|
34
|
+
before(:each) do
|
35
|
+
MethodDictionary.clear
|
36
|
+
MethodDictionary.find_operators( @klazz )
|
37
|
+
MethodDictionary.find_operators( @assoc_klazz )
|
38
|
+
end
|
39
|
+
|
40
|
+
it "should be able to create a new excel generator" do
|
41
|
+
generator = ExcelGenerator.new( 'dummy.xls' )
|
42
|
+
|
43
|
+
generator.should_not be_nil
|
44
|
+
end
|
45
|
+
|
46
|
+
it "should generate template .xls file from model" do
|
47
|
+
|
48
|
+
expect = result_file('project_template_spec.xls')
|
49
|
+
|
50
|
+
gen = ExcelGenerator.new( expect )
|
51
|
+
|
52
|
+
gen.generate(Project)
|
53
|
+
|
54
|
+
File.exists?(expect).should be_true
|
55
|
+
|
56
|
+
puts "Can manually check file @ #{expect}"
|
57
|
+
end
|
58
|
+
|
59
|
+
it "should export a simple model to .xls spreedsheet" do
|
60
|
+
|
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
|
+
|
64
|
+
expect= result_file('simple_export_spec.xls')
|
65
|
+
|
66
|
+
gen = ExcelGenerator.new(expect)
|
67
|
+
|
68
|
+
items = Project.all
|
69
|
+
|
70
|
+
gen.export(items)
|
71
|
+
|
72
|
+
File.exists?(expect).should be_true
|
73
|
+
|
74
|
+
end
|
75
|
+
|
76
|
+
end
|
77
|
+
else
|
78
|
+
puts "WARNING: skipped excel_generator_spec : Requires JRUBY - JExcelFile requires JAVA"
|
79
|
+
end # jruby
|
@@ -32,9 +32,9 @@ if(Guards::jruby?)
|
|
32
32
|
end
|
33
33
|
|
34
34
|
before(:each) do
|
35
|
-
|
36
|
-
|
37
|
-
|
35
|
+
MethodDictionary.clear
|
36
|
+
MethodDictionary.find_operators( @klazz )
|
37
|
+
MethodDictionary.find_operators( @assoc_klazz )
|
38
38
|
end
|
39
39
|
|
40
40
|
it "should be able to create a new excel generator" do
|
data/spec/excel_loader_spec.rb
CHANGED
@@ -28,7 +28,7 @@ if(Guards::jruby?)
|
|
28
28
|
db_clear() # todo read up about proper transactional fixtures
|
29
29
|
|
30
30
|
|
31
|
-
|
31
|
+
Project = Project
|
32
32
|
@assoc_klazz = Category
|
33
33
|
end
|
34
34
|
|
@@ -36,49 +36,49 @@ if(Guards::jruby?)
|
|
36
36
|
|
37
37
|
Project.delete_all
|
38
38
|
|
39
|
-
%w{category_001 category_002 category_003}.each do |cat|
|
39
|
+
%w{category_001 category_002 category_003 category_004 category_005}.each do |cat|
|
40
40
|
@assoc_klazz.find_or_create_by_reference(cat)
|
41
41
|
end
|
42
42
|
|
43
43
|
|
44
|
-
|
45
|
-
|
46
|
-
|
44
|
+
MethodDictionary.clear
|
45
|
+
MethodDictionary.find_operators( Project )
|
46
|
+
MethodDictionary.find_operators( @assoc_klazz )
|
47
47
|
end
|
48
48
|
|
49
49
|
it "should be able to create a new excel loader and load object" do
|
50
|
-
loader = ExcelLoader.new(
|
50
|
+
loader = ExcelLoader.new( Project)
|
51
51
|
|
52
52
|
loader.load_object.should_not be_nil
|
53
|
-
loader.load_object.should be_is_a(
|
53
|
+
loader.load_object.should be_is_a(Project)
|
54
54
|
loader.load_object.new_record?.should be_true
|
55
55
|
end
|
56
56
|
|
57
57
|
it "should process a simple .xls spreedsheet" do
|
58
58
|
|
59
|
-
loader = ExcelLoader.new(
|
59
|
+
loader = ExcelLoader.new(Project)
|
60
60
|
|
61
|
-
count =
|
61
|
+
count = Project.count
|
62
62
|
loader.perform_load( $DataShiftFixturePath + '/SimpleProjects.xls')
|
63
63
|
|
64
|
-
loader.loaded_count.should == (
|
64
|
+
loader.loaded_count.should == (Project.count - count)
|
65
65
|
|
66
66
|
end
|
67
67
|
|
68
68
|
it "should process multiple associationss from single column" do
|
69
69
|
|
70
|
-
|
71
|
-
count =
|
70
|
+
Project.find_by_title('001').should be_nil
|
71
|
+
count = Project.count
|
72
72
|
|
73
|
-
loader = ExcelLoader.new(
|
73
|
+
loader = ExcelLoader.new(Project)
|
74
74
|
|
75
75
|
loader.perform_load( $DataShiftFixturePath + '/ProjectsSingleCategories.xls')
|
76
76
|
|
77
77
|
loader.loaded_count.should be > 3
|
78
|
-
loader.loaded_count.should == (
|
78
|
+
loader.loaded_count.should == (Project.count - count)
|
79
79
|
|
80
80
|
{'001' => 2, '002' => 1, '003' => 3, '099' => 0 }.each do|title, expected|
|
81
|
-
project =
|
81
|
+
project = Project.find_by_title(title)
|
82
82
|
|
83
83
|
project.should_not be_nil
|
84
84
|
puts "#{project.inspect} [#{project.categories.size}]"
|
@@ -97,7 +97,7 @@ if(Guards::jruby?)
|
|
97
97
|
loader.loaded_count.should == (Project.count - count)
|
98
98
|
|
99
99
|
{'004' => 3, '005' => 1, '006' => 0, '007' => 1 }.each do|title, expected|
|
100
|
-
project =
|
100
|
+
project = Project.find_by_title(title)
|
101
101
|
|
102
102
|
project.should_not be_nil
|
103
103
|
|
@@ -106,6 +106,25 @@ if(Guards::jruby?)
|
|
106
106
|
|
107
107
|
end
|
108
108
|
|
109
|
+
it "should process multiple associations with lookup specified in column from excel spreedsheet", :fail => true do
|
110
|
+
|
111
|
+
loader = ExcelLoader.new(Project)
|
112
|
+
|
113
|
+
count = Project.count
|
114
|
+
loader.perform_load( $DataShiftFixturePath + '/ProjectsMultiCategoriesHeaderLookup.xls')
|
115
|
+
|
116
|
+
loader.loaded_count.should == (Project.count - count)
|
117
|
+
|
118
|
+
{'004' => 4, '005' => 1, '006' => 0, '007' => 1 }.each do|title, expected|
|
119
|
+
project = Project.find_by_title(title)
|
120
|
+
|
121
|
+
project.should_not be_nil
|
122
|
+
|
123
|
+
project.should have(expected).categories
|
124
|
+
end
|
125
|
+
|
126
|
+
end
|
127
|
+
|
109
128
|
it "should process excel spreedsheet with extra undefined columns" do
|
110
129
|
loader = ExcelLoader.new(Project)
|
111
130
|
lambda {loader.perform_load( ifixture_file('BadAssociationName.xls') ) }.should_not raise_error
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
data/spec/loader_spec.rb
CHANGED
@@ -15,15 +15,15 @@ describe 'Basic Loader' do
|
|
15
15
|
db_connect( 'test_file' ) # , test_memory, test_mysql
|
16
16
|
|
17
17
|
# load our test model definitions - Project etc
|
18
|
-
require File.join($DataShiftFixturePath, 'test_model_defs')
|
19
|
-
|
18
|
+
require File.join($DataShiftFixturePath, 'test_model_defs')
|
19
|
+
|
20
20
|
migrate_up
|
21
21
|
@klazz = Project
|
22
22
|
end
|
23
23
|
|
24
24
|
before(:each) do
|
25
|
-
|
26
|
-
|
25
|
+
MethodDictionary.clear
|
26
|
+
MethodDictionary.find_operators( @klazz )
|
27
27
|
end
|
28
28
|
|
29
29
|
it "should be able to create a new loader and load object" do
|
@@ -0,0 +1,243 @@
|
|
1
|
+
# Copyright:: (c) Autotelik Media Ltd 2011
|
2
|
+
# Author :: Tom Statter
|
3
|
+
# Date :: Aug 2011
|
4
|
+
# License:: MIT
|
5
|
+
#
|
6
|
+
# Details:: Specs for MethodMapper aspect of Active Record Loader
|
7
|
+
# MethodMapper provides the bridge between 'strings' e.g column headings
|
8
|
+
# and a classes different types of assignment operators
|
9
|
+
#
|
10
|
+
require File.dirname(__FILE__) + '/spec_helper'
|
11
|
+
|
12
|
+
describe 'Method Mapping' do
|
13
|
+
|
14
|
+
before(:all) do
|
15
|
+
db_connect( 'test_file' ) # , test_memory, test_mysql
|
16
|
+
|
17
|
+
# load our test model definitions - Project etc
|
18
|
+
require ifixture_file('test_model_defs')
|
19
|
+
|
20
|
+
migrate_up
|
21
|
+
end
|
22
|
+
|
23
|
+
before(:each) do
|
24
|
+
MethodDictionary.clear
|
25
|
+
MethodDictionary.find_operators( Project )
|
26
|
+
MethodDictionary.find_operators( Milestone )
|
27
|
+
end
|
28
|
+
|
29
|
+
it "should store dictionary for multiple AR models" do
|
30
|
+
MethodDictionary.assignments.size.should == 2
|
31
|
+
MethodDictionary.has_many.size.should == 2
|
32
|
+
end
|
33
|
+
|
34
|
+
it "should populate method dictionary for a given AR model" do
|
35
|
+
|
36
|
+
MethodDictionary.has_many.should_not be_empty
|
37
|
+
MethodDictionary.has_many[Project].should include('milestones')
|
38
|
+
|
39
|
+
MethodDictionary.assignments.should_not be_empty
|
40
|
+
MethodDictionary.assignments[Project].should include('id')
|
41
|
+
MethodDictionary.assignments[Project].should include('value_as_string')
|
42
|
+
MethodDictionary.assignments[Project].should include('value_as_text')
|
43
|
+
|
44
|
+
MethodDictionary.belongs_to.should_not be_empty
|
45
|
+
MethodDictionary.belongs_to[Project].should be_empty
|
46
|
+
|
47
|
+
|
48
|
+
MethodDictionary.column_types.should be_is_a(Hash)
|
49
|
+
MethodDictionary.column_types.should_not be_empty
|
50
|
+
MethodDictionary.column_types[Project].size.should == Project.columns.size
|
51
|
+
|
52
|
+
|
53
|
+
end
|
54
|
+
|
55
|
+
it "should populate assigment members without the equivalent association names" do
|
56
|
+
|
57
|
+
# we should remove has-many & belongs_to from basic assignment set as they require a DB lookup
|
58
|
+
# or a Model.create call, not a simple assignment
|
59
|
+
|
60
|
+
MethodDictionary.assignments_for(Project).should_not include( MethodDictionary.belongs_to_for(Project) )
|
61
|
+
MethodDictionary.assignments_for(Project).should_not include( MethodDictionary.has_many_for(Project) )
|
62
|
+
end
|
63
|
+
|
64
|
+
|
65
|
+
it "should populate assignment operators for method details for different forms of a column name" do
|
66
|
+
|
67
|
+
MethodDictionary.build_method_details( Project )
|
68
|
+
|
69
|
+
[:value_as_string, 'value_as_string', "VALUE as_STRING", "value as string"].each do |format|
|
70
|
+
|
71
|
+
method_details = MethodDictionary.find_method_detail( Project, format )
|
72
|
+
|
73
|
+
method_details.class.should == MethodDetail
|
74
|
+
|
75
|
+
method_details.operator.should == 'value_as_string'
|
76
|
+
method_details.operator_for(:assignment).should == 'value_as_string'
|
77
|
+
|
78
|
+
method_details.operator?('value_as_string').should be_true
|
79
|
+
method_details.operator?('blah_as_string').should be_false
|
80
|
+
|
81
|
+
method_details.operator_for(:belongs_to).should be_nil
|
82
|
+
method_details.operator_for(:has_many).should be_nil
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
|
87
|
+
# Note : Not all assignments will currently have a column type, for example
|
88
|
+
# those that are derived from a delegate_belongs_to
|
89
|
+
|
90
|
+
it "should populate column types for assignment operators in method details" do
|
91
|
+
|
92
|
+
MethodDictionary.build_method_details( Project )
|
93
|
+
|
94
|
+
[:value_as_string, 'value_as_string', "VALUE as_STRING", "value as string"].each do |format|
|
95
|
+
|
96
|
+
method_details = MethodDictionary.find_method_detail( Project, format )
|
97
|
+
|
98
|
+
method_details.class.should == MethodDetail
|
99
|
+
|
100
|
+
method_details.col_type.should_not be_nil
|
101
|
+
method_details.col_type.name.should == 'value_as_string'
|
102
|
+
method_details.col_type.default.should == nil
|
103
|
+
method_details.col_type.sql_type.should include 'varchar(255)' # db specific, sqlite
|
104
|
+
method_details.col_type.type.should == :string
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
it "should populate required Class for assignment operators based on column type" do
|
109
|
+
|
110
|
+
MethodDictionary.build_method_details( Project )
|
111
|
+
|
112
|
+
[:value_as_string, 'value_as_string', "VALUE as_STRING", "value as string"].each do |format|
|
113
|
+
|
114
|
+
method_details = MethodDictionary.find_method_detail( Project, format )
|
115
|
+
|
116
|
+
method_details.operator_class_name.should == 'String'
|
117
|
+
method_details.operator_class.should be_is_a(Class)
|
118
|
+
method_details.operator_class.should == String
|
119
|
+
end
|
120
|
+
|
121
|
+
end
|
122
|
+
|
123
|
+
it "should populate belongs_to operator for method details for different forms of a column name" do
|
124
|
+
|
125
|
+
MethodDictionary.build_method_details( Project )
|
126
|
+
MethodDictionary.build_method_details( Milestone )
|
127
|
+
|
128
|
+
# milestone.project = project.id
|
129
|
+
[:project, 'project', "PROJECT", "prOJECt"].each do |format|
|
130
|
+
|
131
|
+
method_details = MethodDictionary.find_method_detail( Milestone, format )
|
132
|
+
|
133
|
+
method_details.should_not be_nil
|
134
|
+
|
135
|
+
method_details.operator.should == 'project'
|
136
|
+
method_details.operator_for(:belongs_to).should == 'project'
|
137
|
+
|
138
|
+
method_details.operator_for(:assignment).should be_nil
|
139
|
+
method_details.operator_for(:has_many).should be_nil
|
140
|
+
end
|
141
|
+
|
142
|
+
end
|
143
|
+
|
144
|
+
it "should populate required Class for belongs_to operator method details" do
|
145
|
+
|
146
|
+
MethodDictionary.find_operators( LoaderRelease )
|
147
|
+
MethodDictionary.find_operators( LongAndComplexTableLinkedToVersion )
|
148
|
+
|
149
|
+
MethodDictionary.build_method_details( LoaderRelease )
|
150
|
+
MethodDictionary.build_method_details( LongAndComplexTableLinkedToVersion )
|
151
|
+
|
152
|
+
|
153
|
+
# release.project = project.id
|
154
|
+
[:project, 'project', "PROJECT", "prOJECt"].each do |format|
|
155
|
+
|
156
|
+
method_details = MethodDictionary.find_method_detail( LoaderRelease, format )
|
157
|
+
|
158
|
+
method_details.operator_class_name.should == 'Project'
|
159
|
+
method_details.operator_class.should == Project
|
160
|
+
end
|
161
|
+
|
162
|
+
|
163
|
+
[:version, "Version", "verSION"].each do |format|
|
164
|
+
method_details = MethodDictionary.find_method_detail( LongAndComplexTableLinkedToVersion, format )
|
165
|
+
|
166
|
+
method_details.operator_type.should == :belongs_to
|
167
|
+
|
168
|
+
method_details.operator_class_name.should == 'Version'
|
169
|
+
method_details.operator_class.should == Version
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
173
|
+
it "should populate required Class for has_one operator method details" do
|
174
|
+
|
175
|
+
MethodDictionary.find_operators( Version )
|
176
|
+
MethodDictionary.build_method_details( Version )
|
177
|
+
|
178
|
+
# version.long_and_complex_table_linked_to_version = LongAndComplexTableLinkedToVersion.create()
|
179
|
+
|
180
|
+
[:long_and_complex_table_linked_to_version, 'LongAndComplexTableLinkedToVersion', "Long And Complex_Table_Linked To Version", "Long_And_Complex_Table_Linked_To_Version"].each do |format|
|
181
|
+
method_details = MethodDictionary.find_method_detail( Version, format )
|
182
|
+
|
183
|
+
method_details.should_not be_nil
|
184
|
+
|
185
|
+
method_details.operator.should == 'long_and_complex_table_linked_to_version'
|
186
|
+
|
187
|
+
method_details.operator_type.should == :has_one
|
188
|
+
|
189
|
+
method_details.operator_class_name.should == 'LongAndComplexTableLinkedToVersion'
|
190
|
+
method_details.operator_class.should == LongAndComplexTableLinkedToVersion
|
191
|
+
end
|
192
|
+
end
|
193
|
+
|
194
|
+
|
195
|
+
it "should find has_many operator for method details" do
|
196
|
+
|
197
|
+
MethodDictionary.build_method_details( Project )
|
198
|
+
|
199
|
+
[:milestones, "Mile Stones", 'mileSTONES', 'MileStones'].each do |format|
|
200
|
+
|
201
|
+
method_details = MethodDictionary.find_method_detail( Project, format )
|
202
|
+
|
203
|
+
method_details.class.should == MethodDetail
|
204
|
+
|
205
|
+
result = 'milestones'
|
206
|
+
method_details.operator.should == result
|
207
|
+
method_details.operator_for(:has_many).should == result
|
208
|
+
|
209
|
+
method_details.operator_for(:belongs_to).should be_nil
|
210
|
+
method_details.operator_for(:assignments).should be_nil
|
211
|
+
end
|
212
|
+
|
213
|
+
end
|
214
|
+
|
215
|
+
|
216
|
+
it "should return nil when non existent column name" do
|
217
|
+
["On sale", 'on_sale'].each do |format|
|
218
|
+
detail = MethodDictionary.find_method_detail( Project, format )
|
219
|
+
|
220
|
+
detail.should be_nil
|
221
|
+
end
|
222
|
+
end
|
223
|
+
|
224
|
+
|
225
|
+
it "should find a set of methods based on a list of column names" do
|
226
|
+
pending("key API - map column headers to set of methods")
|
227
|
+
end
|
228
|
+
|
229
|
+
it "should not by default map setter methods", :fail => true do
|
230
|
+
MethodDictionary.assignments[Milestone].should_not include('title')
|
231
|
+
end
|
232
|
+
|
233
|
+
it "should support reload and inclusion of setter methods", :fail => true do
|
234
|
+
|
235
|
+
MethodDictionary.assignments[Milestone].should_not include('title')
|
236
|
+
|
237
|
+
MethodDictionary.find_operators( Milestone, :reload => true, :instance_methods => true )
|
238
|
+
|
239
|
+
# Milestone delegates :title to Project
|
240
|
+
MethodDictionary.assignments[Milestone].should include('title')
|
241
|
+
end
|
242
|
+
|
243
|
+
end
|