drive_time 0.0.3
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/.gitignore +61 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +240 -0
- data/Rakefile +7 -0
- data/drive_time.gemspec +30 -0
- data/lib/drive_time/bi_directional_hash.rb +33 -0
- data/lib/drive_time/builders/join_builder.rb +39 -0
- data/lib/drive_time/builders/name_builder.rb +19 -0
- data/lib/drive_time/class_name_map.rb +41 -0
- data/lib/drive_time/converters/spreadsheets_converter.rb +125 -0
- data/lib/drive_time/converters/worksheet_converter.rb +262 -0
- data/lib/drive_time/field_expander.rb +73 -0
- data/lib/drive_time/loader.rb +100 -0
- data/lib/drive_time/logging.rb +19 -0
- data/lib/drive_time/model_store.rb +73 -0
- data/lib/drive_time/version.rb +3 -0
- data/lib/drive_time.rb +71 -0
- data/spec/drive_time/bi_directional_hash_spec.rb +54 -0
- data/spec/drive_time/builder/join_builder_spec.rb +48 -0
- data/spec/drive_time/builder/name_builder_spec.rb +26 -0
- data/spec/drive_time/class_name_map_spec.rb +77 -0
- data/spec/drive_time/converters/worksheet_converter_spec.rb +64 -0
- data/spec/drive_time/field_expander_spec.rb +130 -0
- data/spec/drive_time/loader_spec.rb +111 -0
- data/spec/drive_time/model_store_spec.rb +52 -0
- data/spec/drive_time_spec.rb +44 -0
- data/spec/fixtures/mapping.yml +55 -0
- data/spec/full_tests.rb +48 -0
- data/spec/spec_helper.rb +6 -0
- metadata +233 -0
@@ -0,0 +1,48 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module DriveTime
|
4
|
+
|
5
|
+
describe JoinBuilder do
|
6
|
+
|
7
|
+
before(:each) do
|
8
|
+
@join_builder = JoinBuilder.new
|
9
|
+
end
|
10
|
+
|
11
|
+
it "should combine values into a single value" do
|
12
|
+
# All present
|
13
|
+
name_fields = ['Key1', 'Key2', 'Key3']
|
14
|
+
row_map = {'Key1' => 'Value1', 'Key2' => 'Value2', 'Key3' => 'Value3'}
|
15
|
+
@join_builder.build(name_fields, row_map).should == 'value1_value2_value3'
|
16
|
+
|
17
|
+
end
|
18
|
+
|
19
|
+
it "should ignore empty fields so long as they exist" do
|
20
|
+
name_fields = ['Key1', 'Key2', 'Key3']
|
21
|
+
row_map = {'Key1' => 'Value1', 'Key2' => '', 'Key3' => 'Value3'}
|
22
|
+
@join_builder.build(name_fields, row_map).should == 'value1_value3'
|
23
|
+
end
|
24
|
+
|
25
|
+
it "should not add anything to a single name" do
|
26
|
+
name_fields = ['Key3']
|
27
|
+
row_map = {'Key1' => 'Value1', 'Key2' => 'Value2', 'Key3' => 'Value3'}
|
28
|
+
@join_builder.build(name_fields, row_map).should == 'value3'
|
29
|
+
end
|
30
|
+
|
31
|
+
it "should raise a MissingFieldError if a field is missing" do
|
32
|
+
|
33
|
+
name_fields = ['Key1']
|
34
|
+
row_map = {}
|
35
|
+
|
36
|
+
expect { @join_builder.build(name_fields, row_map) }.to raise_error NameBuilder::MissingFieldError
|
37
|
+
end
|
38
|
+
|
39
|
+
it "should raise a NoFieldsError if all fields are missing" do
|
40
|
+
|
41
|
+
name_fields = ['Key1', 'Key2', 'Key3']
|
42
|
+
row_map = {'Key1' => '', 'Key2' => '', 'Key3' => ''}
|
43
|
+
|
44
|
+
expect { @join_builder.build(name_fields, row_map) }.to raise_error NameBuilder::NoFieldsError
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
48
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module DriveTime
|
4
|
+
|
5
|
+
describe NameBuilder do
|
6
|
+
|
7
|
+
before(:each) do
|
8
|
+
@name_builder = NameBuilder.new
|
9
|
+
end
|
10
|
+
|
11
|
+
it "should combine names into a single name, adding a '.' for a middle initial" do
|
12
|
+
# All present
|
13
|
+
name_fields = ['First Name', 'Middle Names', 'Last Name']
|
14
|
+
row_map = {'First Name' => 'George', 'Middle Names' => 'W', 'Last Name' => 'Bush'}
|
15
|
+
@name_builder.build(name_fields, row_map).should == 'george_w._bush'
|
16
|
+
end
|
17
|
+
|
18
|
+
it "should combine names into a single name, adding no '.' for any longer middle name" do
|
19
|
+
# All present
|
20
|
+
name_fields = ['First Name', 'Middle Names', 'Last Name']
|
21
|
+
row_map = {'First Name' => 'George', 'Middle Names' => 'Wo', 'Last Name' => 'Bush'}
|
22
|
+
@name_builder.build(name_fields, row_map).should == 'george_wo_bush'
|
23
|
+
end
|
24
|
+
|
25
|
+
end
|
26
|
+
end
|
@@ -0,0 +1,77 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module DriveTime
|
4
|
+
|
5
|
+
describe ClassNameMap do
|
6
|
+
|
7
|
+
before :each do
|
8
|
+
@class_name_map = ClassNameMap.new
|
9
|
+
@class_a = "ClassA"
|
10
|
+
@class_b = "ClassB"
|
11
|
+
@class_c = "ClassC"
|
12
|
+
@class_d = "ClassD"
|
13
|
+
@class_e = "ClassD"
|
14
|
+
@class_name_map.save_mapping(@class_c, @class_d)
|
15
|
+
end
|
16
|
+
|
17
|
+
describe "when saving class mapping" do
|
18
|
+
|
19
|
+
context "when no mapped class name is given" do
|
20
|
+
it "should return the classname" do
|
21
|
+
@class_name_map.save_mapping(@class_a).should == @class_a
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
context "when a mapped class name is given" do
|
26
|
+
it "should return the mapping" do
|
27
|
+
@class_name_map.save_mapping(@class_a, @class_b).should == @class_b
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
|
33
|
+
describe "when resolving the original from mapped" do
|
34
|
+
|
35
|
+
context "when a mapping exists" do
|
36
|
+
|
37
|
+
it "should return the mapping" do
|
38
|
+
@class_name_map.save_mapping(@class_a, @class_b)
|
39
|
+
@class_name_map.resolve_original_from_mapped(@class_b).should == @class_a
|
40
|
+
end
|
41
|
+
|
42
|
+
end
|
43
|
+
|
44
|
+
context "when no mapping exists" do
|
45
|
+
|
46
|
+
it "should return the class" do
|
47
|
+
@class_name_map.save_mapping(@class_a)
|
48
|
+
@class_name_map.resolve_original_from_mapped(@class_a).should == @class_a
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
54
|
+
|
55
|
+
describe "when resolving the mapped from original" do
|
56
|
+
|
57
|
+
context "when a mapping exists" do
|
58
|
+
|
59
|
+
it "should return the original" do
|
60
|
+
@class_name_map.save_mapping(@class_a, @class_b)
|
61
|
+
@class_name_map.resolve_mapped_from_original(@class_a).should == @class_b
|
62
|
+
end
|
63
|
+
|
64
|
+
end
|
65
|
+
|
66
|
+
context "when no mapping exists" do
|
67
|
+
|
68
|
+
it "should return the class" do
|
69
|
+
@class_name_map.resolve_mapped_from_original(@class_e).should == @class_e
|
70
|
+
end
|
71
|
+
|
72
|
+
end
|
73
|
+
|
74
|
+
end
|
75
|
+
|
76
|
+
end
|
77
|
+
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module DriveTime
|
4
|
+
|
5
|
+
describe WorksheetConverter do
|
6
|
+
|
7
|
+
before(:each) do
|
8
|
+
@worksheet_converter = WorksheetConverter.new(nil, nil, nil, nil)
|
9
|
+
end
|
10
|
+
|
11
|
+
context 'build_id_for_model' do
|
12
|
+
|
13
|
+
it 'should build correct id for model using basic key' do
|
14
|
+
|
15
|
+
class WorksheetConverter
|
16
|
+
public :build_id_for_model
|
17
|
+
end
|
18
|
+
|
19
|
+
mapping = {:key => 'name'}
|
20
|
+
@worksheet_converter.row_map = {'name' => 'John'}
|
21
|
+
|
22
|
+
@worksheet_converter.build_id_for_model(mapping).should == 'john'
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'should build correct id for model using join builder' do
|
26
|
+
|
27
|
+
class WorksheetConverter
|
28
|
+
public :build_id_for_model
|
29
|
+
end
|
30
|
+
|
31
|
+
mapping = {:key => {:builder => 'join', :from_fields => ['one', 'two', 'three'] } }
|
32
|
+
@worksheet_converter.row_map = {'one' => 'Apple', 'two' => 'Orange', 'three' => 'Plum'}
|
33
|
+
|
34
|
+
@worksheet_converter.build_id_for_model(mapping).should == 'apple_orange_plum'
|
35
|
+
end
|
36
|
+
|
37
|
+
it 'should build correct id for model using name builder' do
|
38
|
+
|
39
|
+
class WorksheetConverter
|
40
|
+
public :build_id_for_model
|
41
|
+
end
|
42
|
+
|
43
|
+
mapping = {:key => {:builder => 'name', :from_fields => ['forename', 'middle_name', 'surname'] } }
|
44
|
+
@worksheet_converter.row_map = {'forename' => 'George', 'middle_name' => 'W', 'surname' => 'Bush'}
|
45
|
+
|
46
|
+
@worksheet_converter.build_id_for_model(mapping).should == 'george_w._bush'
|
47
|
+
end
|
48
|
+
|
49
|
+
it 'should raise a NoFieldNameError if no field exists with key name' do
|
50
|
+
|
51
|
+
class WorksheetConverter
|
52
|
+
public :build_id_for_model
|
53
|
+
end
|
54
|
+
|
55
|
+
mapping = {:key => 'nonsense'}
|
56
|
+
@worksheet_converter.row_map = {'name' => 'John'}
|
57
|
+
|
58
|
+
expect { @worksheet_converter.build_id_for_model(mapping) }.to raise_error WorksheetConverter::NoFieldNameError
|
59
|
+
end
|
60
|
+
|
61
|
+
end
|
62
|
+
|
63
|
+
end
|
64
|
+
end
|
@@ -0,0 +1,130 @@
|
|
1
|
+
require "spec_helper"
|
2
|
+
require "google_drive"
|
3
|
+
|
4
|
+
module DriveTime
|
5
|
+
|
6
|
+
describe FieldExpander do
|
7
|
+
|
8
|
+
before :each do
|
9
|
+
@loader = Loader.new
|
10
|
+
@loader.stub :begin_session
|
11
|
+
@field_expander = FieldExpander.new(@loader)
|
12
|
+
@valid_file_path = "valid_file_path"
|
13
|
+
|
14
|
+
@invalid_token = "invalid_token"
|
15
|
+
@valid_expand_file_token = "expand_file"
|
16
|
+
@valid_expand_file_token_with_filename = "expand_file[#{@valid_file_path}]"
|
17
|
+
@valid_expand_spreadsheet_token = "expand_spreadsheet"
|
18
|
+
@valid_expand_spreadsheet_token_with_filename = "expand_spreadsheet[#{@valid_file_path}]"
|
19
|
+
@file = {name: 'file'} # need something in the object or Ruby treats it as blank
|
20
|
+
@file.stub :initialize
|
21
|
+
@file_contents = "12345"
|
22
|
+
@model_key = "model_key"
|
23
|
+
@worksheet = {name: 'worksheet'}
|
24
|
+
@spreadsheet = {name: 'spreadsheet'}
|
25
|
+
end
|
26
|
+
|
27
|
+
context "when supplied with a field containig an invalid token" do
|
28
|
+
|
29
|
+
it "should raise a TokenExpansionError" do
|
30
|
+
expect { @field_expander.expand(@invalid_token, @model_key) }.to raise_error TokenExpansionError
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
|
35
|
+
context "when supplied with a field containig an 'expand_file' token" do
|
36
|
+
|
37
|
+
context "when the file exists" do
|
38
|
+
|
39
|
+
it "should load the file" do
|
40
|
+
@loader.should_receive(:load_file_direct).with("#{@model_key}.txt").and_return(@file)
|
41
|
+
@file.should_receive(:download_to_string).and_return(@file_contents)
|
42
|
+
@field_expander.expand(@valid_expand_file_token, @model_key).should == @file_contents
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
46
|
+
|
47
|
+
context "when the file doesn't exist" do
|
48
|
+
|
49
|
+
it "should raise a TokenExpansionError" do
|
50
|
+
@loader.stub(:load_file_direct).and_return(nil)
|
51
|
+
expect { @field_expander.expand(@valid_expand_file_token, @model_key) }.to raise_error TokenExpansionError
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
context "when supplied with a field containig an 'expand_file' token and a filename" do
|
58
|
+
|
59
|
+
context "when the file exists" do
|
60
|
+
|
61
|
+
it "should load the file " do
|
62
|
+
@loader.should_receive(:load_file_direct).with("#{@valid_file_path}.txt").and_return(@file)
|
63
|
+
@file.should_receive(:download_to_string).and_return(@file_contents)
|
64
|
+
@field_expander.expand(@valid_expand_file_token_with_filename, @model_key).should == @file_contents
|
65
|
+
end
|
66
|
+
|
67
|
+
end
|
68
|
+
|
69
|
+
context "when the file doesn't exist" do
|
70
|
+
|
71
|
+
it "should raise a TokenExpansionError" do
|
72
|
+
@loader.stub(:load_file_direct).and_return(nil)
|
73
|
+
expect { @field_expander.expand(@valid_expand_file_token_with_filename, @model_key) }.to raise_error TokenExpansionError
|
74
|
+
end
|
75
|
+
|
76
|
+
end
|
77
|
+
|
78
|
+
end
|
79
|
+
|
80
|
+
context "when supplied with a field containig an 'expand_spreadsheet' token" do
|
81
|
+
|
82
|
+
context "when the spreadsheet exists" do
|
83
|
+
|
84
|
+
it "should load the spreadsheet" do
|
85
|
+
@file.stub(:worksheets).and_return([@worksheet])
|
86
|
+
@loader.should_receive(:load_spreadsheet_direct).with(@model_key).and_return(@file)
|
87
|
+
@field_expander.should_receive(:expand_worksheet).with(@worksheet)
|
88
|
+
@field_expander.expand(@valid_expand_spreadsheet_token, @model_key)
|
89
|
+
end
|
90
|
+
|
91
|
+
end
|
92
|
+
|
93
|
+
context "when the spreadsheet doesn't exist" do
|
94
|
+
|
95
|
+
it "should raise a TokenExpansionError" do
|
96
|
+
@loader.stub(:load_spreadsheet_direct).and_return(nil)
|
97
|
+
expect { @field_expander.expand(@valid_expand_spreadsheet_token, @model_key) }.to raise_error TokenExpansionError
|
98
|
+
end
|
99
|
+
|
100
|
+
end
|
101
|
+
|
102
|
+
end
|
103
|
+
|
104
|
+
context "when supplied with a field containig an 'expand_spreadsheet' token and a spreadsheet name" do
|
105
|
+
|
106
|
+
context "when the spreadsheet exists" do
|
107
|
+
|
108
|
+
it "should load the spreadsheet " do
|
109
|
+
@file.stub(:worksheets).and_return([@worksheet])
|
110
|
+
@loader.should_receive(:load_spreadsheet_direct).with(@valid_file_path).and_return(@file)
|
111
|
+
@field_expander.should_receive(:expand_worksheet).with(@worksheet).and_return(@file_contents)
|
112
|
+
@field_expander.expand(@valid_expand_spreadsheet_token_with_filename, @model_key)
|
113
|
+
end
|
114
|
+
|
115
|
+
end
|
116
|
+
|
117
|
+
context "when the spreadsheet doesn't exist" do
|
118
|
+
|
119
|
+
it "should raise a TokenExpansionError" do
|
120
|
+
@loader.stub(:load_spreadsheet_direct).and_return(nil)
|
121
|
+
expect { @field_expander.expand(@valid_expand_spreadsheet_token_with_filename, @model_key) }.to raise_error TokenExpansionError
|
122
|
+
end
|
123
|
+
|
124
|
+
end
|
125
|
+
|
126
|
+
end
|
127
|
+
|
128
|
+
end
|
129
|
+
|
130
|
+
end
|
@@ -0,0 +1,111 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module DriveTime
|
4
|
+
|
5
|
+
VALID_SPREADSHEET_1_TITLE = 'Fixture 1'
|
6
|
+
VALID_SPREADSHEET_2_TITLE = 'Fixture 2'
|
7
|
+
INVALID_SPREADSHEET_TITLE = 'Invalid Title xccdtyyehdyd56ejr6'
|
8
|
+
|
9
|
+
describe Loader do
|
10
|
+
|
11
|
+
def last_access_time_for_cached_file(title)
|
12
|
+
cached_directory = ENV['CACHED_DIR']
|
13
|
+
file_name = "#{title}.yml"
|
14
|
+
file_path = File.join(cached_directory, file_name)
|
15
|
+
File.atime(file_path).to_i
|
16
|
+
end
|
17
|
+
|
18
|
+
def clear_cache_dir
|
19
|
+
cached_directory = ENV['CACHED_DIR']
|
20
|
+
FileUtils.rm Dir.glob("#{cached_directory}/*")
|
21
|
+
end
|
22
|
+
|
23
|
+
def cached_file_exists(file_name)
|
24
|
+
cached_directory = ENV['CACHED_DIR']
|
25
|
+
file_name = "#{VALID_SPREADSHEET_1_TITLE}.yml"
|
26
|
+
file_path = File.join(cached_directory, file_name)
|
27
|
+
return File.exists? file_path
|
28
|
+
end
|
29
|
+
|
30
|
+
before(:each ) do
|
31
|
+
@loader = Loader.new
|
32
|
+
end
|
33
|
+
|
34
|
+
context 'When not using cache' do
|
35
|
+
|
36
|
+
context 'when accessing a spreadsheet' do
|
37
|
+
|
38
|
+
it "should raise a SpreadsheetNotFoundError if a spreadsheet doesn't exist" do
|
39
|
+
expect{ @loader.load_spreadsheet(INVALID_SPREADSHEET_TITLE, false) }.to raise_error(Loader::SpreadsheetNotFoundError)
|
40
|
+
end
|
41
|
+
|
42
|
+
it "should download a Spreadsheet sucessfully" do
|
43
|
+
@loader.load_spreadsheet(VALID_SPREADSHEET_1_TITLE, false).title.should == VALID_SPREADSHEET_1_TITLE
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
47
|
+
|
48
|
+
context 'when accessing a worksheet from with a loaded spreadsheet' do
|
49
|
+
|
50
|
+
before(:each) do
|
51
|
+
@spreadsheet = @loader.load_spreadsheet(VALID_SPREADSHEET_1_TITLE, false)
|
52
|
+
end
|
53
|
+
|
54
|
+
it "should raise a SpreadsheetNotFoundError if a worksheet doesn't exist" do
|
55
|
+
expect{ @loader.load_worksheet_from_spreadsheet(@spreadsheet, 'nmgsgscg', false) }.to raise_error(Loader::WorksheetNotFoundError)
|
56
|
+
end
|
57
|
+
|
58
|
+
it "should download a Worksheet sucessfully" do
|
59
|
+
@loader.load_worksheet_from_spreadsheet(@spreadsheet, 'Label', false).title.should == 'Label'
|
60
|
+
end
|
61
|
+
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
context 'When using cache' do
|
66
|
+
|
67
|
+
before(:each) do
|
68
|
+
@spreadsheet = @loader.load_spreadsheet(VALID_SPREADSHEET_1_TITLE, false)
|
69
|
+
# Save the time so we can check file access
|
70
|
+
@before = Time.now.to_i
|
71
|
+
end
|
72
|
+
|
73
|
+
context 'when accessing a spreadsheet' do
|
74
|
+
it "should pull a Spreadsheet from the cache if it exists" do
|
75
|
+
@loader.load_spreadsheet(VALID_SPREADSHEET_1_TITLE).title.should == VALID_SPREADSHEET_1_TITLE
|
76
|
+
last_access_time_for_cached_file(VALID_SPREADSHEET_1_TITLE).should <= @before
|
77
|
+
end
|
78
|
+
|
79
|
+
it "should download a Spreadsheet if it isn't in the cache" do
|
80
|
+
clear_cache_dir
|
81
|
+
@loader.load_spreadsheet(VALID_SPREADSHEET_1_TITLE, false).title.should == VALID_SPREADSHEET_1_TITLE
|
82
|
+
end
|
83
|
+
|
84
|
+
it "should save the spreadsheet to the cache" do
|
85
|
+
clear_cache_dir
|
86
|
+
@loader.load_spreadsheet(VALID_SPREADSHEET_1_TITLE)
|
87
|
+
cached_file_exists(VALID_SPREADSHEET_1_TITLE).should be_true
|
88
|
+
end
|
89
|
+
|
90
|
+
it "should save the spreadsheet's worksheets to the cache" do
|
91
|
+
clear_cache_dir
|
92
|
+
@loader.load_spreadsheet(VALID_SPREADSHEET_1_TITLE)
|
93
|
+
cached_file_exists('Label').should be_true
|
94
|
+
cached_file_exists('Act').should be_true
|
95
|
+
cached_file_exists('Album').should be_true
|
96
|
+
cached_file_exists('Group').should be_true
|
97
|
+
end
|
98
|
+
|
99
|
+
end
|
100
|
+
|
101
|
+
context 'when accessing a worksheet from with a loaded spreadsheet' do
|
102
|
+
|
103
|
+
it "should download a Spreadsheet sucessfully" do
|
104
|
+
@loader.load_worksheet_from_spreadsheet(@spreadsheet, 'Label').title.should == 'Label'
|
105
|
+
end
|
106
|
+
|
107
|
+
end
|
108
|
+
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'active_record'
|
3
|
+
|
4
|
+
module DriveTime
|
5
|
+
|
6
|
+
describe ModelStore do
|
7
|
+
|
8
|
+
class ModelA
|
9
|
+
end
|
10
|
+
|
11
|
+
class ModelB
|
12
|
+
end
|
13
|
+
|
14
|
+
before(:each) do
|
15
|
+
@model_store = ModelStore.new
|
16
|
+
@model_a = ModelA.new
|
17
|
+
@model_b = ModelB.new
|
18
|
+
end
|
19
|
+
|
20
|
+
describe 'when models are added' do
|
21
|
+
|
22
|
+
it 'should allow an added model to be retrieved' do
|
23
|
+
@model_store.add_model(@model_a, 'model_a', ModelA)
|
24
|
+
@model_store.get_model(ModelA, 'model_a').should == @model_a
|
25
|
+
end
|
26
|
+
|
27
|
+
describe 'when the same model is added twice' do
|
28
|
+
|
29
|
+
it 'should raise a ModelAddedTwiceError' do
|
30
|
+
@model_store.add_model(@model_a, 'model_a', ModelA)
|
31
|
+
expect { @model_store.add_model(@model_a, 'model_a', ModelA) }.to raise_error(ModelStore::ModelAddedTwiceError)
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
describe 'when models are retieved' do
|
38
|
+
|
39
|
+
it 'should raise a NoModelsOfClassInStoreError if no model is stored of the given type' do
|
40
|
+
@model_store.add_model(@model_a, 'model_a', ModelA)
|
41
|
+
expect { @model_store.get_model(ModelB, 'model_a') }.to raise_error(ModelStore::NoModelsOfClassInStoreError)
|
42
|
+
end
|
43
|
+
|
44
|
+
it 'should raise a NoModelOfClassWithKeyInStoreError if no model is stored of the given type with the given key' do
|
45
|
+
@model_store.add_model(@model_a, 'model_a', ModelA)
|
46
|
+
expect { @model_store.get_model(ModelA, 'model_b') }.to raise_error(ModelStore::NoModelOfClassWithKeyInStoreError)
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
# Mapped from Group
|
4
|
+
|
5
|
+
module DriveTime
|
6
|
+
|
7
|
+
describe DriveTime do
|
8
|
+
|
9
|
+
it 'should process string correctly' do
|
10
|
+
|
11
|
+
input_string = ' a Test STRING-with-spaces- AND hyphens '
|
12
|
+
# All lower case
|
13
|
+
# Underscores replace speces and hyphens
|
14
|
+
# Leading and trailing whitespace is removed
|
15
|
+
expected_string = 'a_test_string-with-spaces-_and_hyphens'
|
16
|
+
result_string = DriveTime.underscore_from_text input_string
|
17
|
+
result_string.should == expected_string
|
18
|
+
end
|
19
|
+
|
20
|
+
it 'should process a title to a class' do
|
21
|
+
input_string = "Nonsense Things"
|
22
|
+
expected_string = "NonsenseThing"
|
23
|
+
result_string = DriveTime.class_name_from_title input_string
|
24
|
+
result_string.should == expected_string
|
25
|
+
end
|
26
|
+
|
27
|
+
it 'should only treat yes and y (in any case) as affirmative' do
|
28
|
+
# Positive
|
29
|
+
DriveTime.is_affirmative?('yes').should be_true
|
30
|
+
DriveTime.is_affirmative?('YES').should be_true
|
31
|
+
DriveTime.is_affirmative?('Yes').should be_true
|
32
|
+
DriveTime.is_affirmative?('y').should be_true
|
33
|
+
DriveTime.is_affirmative?('Y').should be_true
|
34
|
+
DriveTime.is_affirmative?(' Yes ').should be_true
|
35
|
+
# Negative
|
36
|
+
DriveTime.is_affirmative?('No').should be_false
|
37
|
+
DriveTime.is_affirmative?('').should be_false
|
38
|
+
DriveTime.is_affirmative?('N').should be_false
|
39
|
+
DriveTime.is_affirmative?('Yeses').should be_false
|
40
|
+
DriveTime.is_affirmative?('Example').should be_false
|
41
|
+
end
|
42
|
+
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,55 @@
|
|
1
|
+
namespace: DriveTime
|
2
|
+
spreadsheets:
|
3
|
+
- title: Fixture 1
|
4
|
+
worksheets:
|
5
|
+
- title: Group
|
6
|
+
map_to_class: Act
|
7
|
+
key: name
|
8
|
+
fields:
|
9
|
+
- name: name
|
10
|
+
- name: formed
|
11
|
+
associations:
|
12
|
+
- name: member
|
13
|
+
builder: multi
|
14
|
+
|
15
|
+
- title: Album
|
16
|
+
key: name
|
17
|
+
fields:
|
18
|
+
- name: year
|
19
|
+
associations:
|
20
|
+
- name: label
|
21
|
+
builder: use_fields
|
22
|
+
field_names: [label_1, label_2, label_3]
|
23
|
+
singular: true
|
24
|
+
- name: act
|
25
|
+
singular: true
|
26
|
+
|
27
|
+
- title: Label
|
28
|
+
key: name
|
29
|
+
fields:
|
30
|
+
- name: genre
|
31
|
+
- name: website
|
32
|
+
|
33
|
+
- title: Member
|
34
|
+
key: name
|
35
|
+
fields:
|
36
|
+
- name: name
|
37
|
+
- name: real_name
|
38
|
+
# from_fields: [forename, middle_names, surname]
|
39
|
+
- name: year_of_birth
|
40
|
+
- name: year_of_death
|
41
|
+
|
42
|
+
- title: Fixture 2
|
43
|
+
dependencies: [Fixture 1]
|
44
|
+
worksheets:
|
45
|
+
- title: Track
|
46
|
+
key:
|
47
|
+
builder: join
|
48
|
+
from_fields: [name, remix]
|
49
|
+
fields:
|
50
|
+
- name: name
|
51
|
+
- name: remix
|
52
|
+
- name: duration
|
53
|
+
associations:
|
54
|
+
- name: album
|
55
|
+
inverse: true
|
data/spec/full_tests.rb
ADDED
@@ -0,0 +1,48 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
class ModelBase
|
4
|
+
|
5
|
+
def initialize(data, params)
|
6
|
+
end
|
7
|
+
|
8
|
+
def save!
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
module DriveTime
|
13
|
+
|
14
|
+
class Act < ModelBase
|
15
|
+
attr_accessor :members
|
16
|
+
def initialize(data, params)
|
17
|
+
self.members = Array.new
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
class Album < ModelBase
|
22
|
+
attr_accessor :label
|
23
|
+
attr_accessor :act
|
24
|
+
attr_accessor :tracks
|
25
|
+
def initialize(data, params)
|
26
|
+
self.tracks = Array.new
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
class Label < ModelBase; end
|
31
|
+
|
32
|
+
class Member < ModelBase; end
|
33
|
+
|
34
|
+
class Track < ModelBase; end
|
35
|
+
|
36
|
+
describe DriveTime do
|
37
|
+
|
38
|
+
context 'with full spreadsheet and mapping' do
|
39
|
+
it 'should load spreadsheet and map to models' do
|
40
|
+
mappings_path = File.join(File.dirname(__FILE__),'fixtures/mapping.yml')
|
41
|
+
converter = SpreadsheetsConverter.new
|
42
|
+
converter.load mappings_path
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
48
|
+
end
|