csv_record 2.0.0 → 2.1.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.
Files changed (37) hide show
  1. data/.gitignore +1 -0
  2. data/.travis.yml +2 -0
  3. data/README.md +3 -3
  4. data/Rakefile +1 -1
  5. data/csv_record.gemspec +6 -7
  6. data/lib/csv_record/callbacks.rb +3 -3
  7. data/lib/csv_record/connector.rb +7 -7
  8. data/lib/csv_record/csv_fields.rb +45 -0
  9. data/lib/csv_record/csv_queries/query.rb +1 -1
  10. data/lib/csv_record/{reader.rb → csv_readers/class_reader.rb} +11 -29
  11. data/lib/csv_record/csv_readers/instance_reader.rb +29 -0
  12. data/lib/csv_record/csv_readers/reader.rb +9 -0
  13. data/lib/csv_record/csv_validations/custom_validation.rb +1 -1
  14. data/lib/csv_record/csv_validations/validations.rb +2 -2
  15. data/lib/csv_record/csv_writers/class_writer.rb +52 -0
  16. data/lib/csv_record/{writer.rb → csv_writers/instance_writer.rb} +4 -21
  17. data/lib/csv_record/csv_writers/writer.rb +9 -0
  18. data/lib/csv_record/document.rb +11 -12
  19. data/lib/csv_record/exceptions.rb +1 -0
  20. data/lib/csv_record/field.rb +21 -0
  21. data/lib/csv_record/helpers.rb +1 -1
  22. data/lib/csv_record/timestamps.rb +11 -2
  23. data/lib/csv_record/version.rb +4 -1
  24. data/test/csv_record/associations_test.rb +0 -3
  25. data/test/csv_record/callbacks_test.rb +0 -1
  26. data/test/csv_record/connector_test.rb +0 -2
  27. data/test/csv_record/helpers_test.rb +0 -1
  28. data/test/csv_record/query_test.rb +0 -1
  29. data/test/csv_record/reader_test.rb +122 -116
  30. data/test/csv_record/timestamps_test.rb +2 -5
  31. data/test/csv_record/validation_test.rb +13 -14
  32. data/test/csv_record/writer_test.rb +60 -18
  33. data/test/helpers.rb +7 -0
  34. data/test/models/customized_class.rb +11 -0
  35. data/test/monkey_patches/object_test.rb +2 -4
  36. data/test/test_helper.rb +9 -6
  37. metadata +38 -43
@@ -1,7 +1,5 @@
1
1
  require_relative '../test_helper'
2
2
 
3
- require_relative '../models/jedi'
4
-
5
3
  describe CsvRecord::Reader do
6
4
  describe 'initializing class methods' do
7
5
  it ('responds to fields') { Jedi.must_respond_to :fields }
@@ -18,8 +16,8 @@ describe CsvRecord::Reader do
18
16
  it ('responds to !=') { klass.must_respond_to :!= }
19
17
  end
20
18
 
21
- describe 'validating the methods behavior' do
22
- it 'building an instance' do
19
+ describe '#build' do
20
+ it 'traditionally' do
23
21
  new_jedi = Jedi.build(
24
22
  name: 'Yoda the red',
25
23
  age: 148,
@@ -29,167 +27,175 @@ describe CsvRecord::Reader do
29
27
  new_jedi.must_be_instance_of Jedi
30
28
  end
31
29
 
32
- it 'Check the current fields' do
33
- Jedi.fields.must_equal [:id, :created_at, :updated_at, :name, :age, :midi_chlorians, "jedi_order_id"]
30
+ it 'with a block' do
31
+ new_jedi = Jedi.build do |jedi|
32
+ jedi.name = 'Yoda the red',
33
+ jedi.age = 148,
34
+ jedi.midi_chlorians = '0.5k'
35
+ end
36
+ new_jedi.wont_be_nil
37
+ new_jedi.must_be_instance_of Jedi
34
38
  end
39
+ end
35
40
 
36
- it 'Check the current values' do
37
- luke.values.must_equal [nil, nil, nil, "Luke Skywalker", 18, "12k", 0]
41
+ it '.fields' do
42
+ [:id, :created_at, :updated_at, :name, :age, :midi_chlorians, "jedi_order_id"].each do |field|
43
+ Jedi.fields.must_include field
38
44
  end
45
+ end
39
46
 
40
- it 'Check the current attributes' do
41
- expected_result = {:id=>nil, :created_at=>nil, :updated_at=>nil, :name=>"Luke Skywalker", age: 18, midi_chlorians: '12k', 'jedi_order_id' => 0}
42
- luke.attributes.must_equal expected_result
43
- end
47
+ it '.values' do
48
+ luke.values.must_equal [nil, nil, nil, "Luke Skywalker", 18, "12k", 0]
49
+ end
50
+
51
+ describe 'retrieving resources' do
52
+ before { luke.save }
44
53
 
45
54
  it "Retrieves all registries" do
46
- luke.save
47
55
  Jedi.all.size.must_equal 1
48
56
  yoda.save
49
57
  Jedi.all.size.must_equal 2
50
58
  end
51
59
 
52
60
  it "counting the registries" do
53
- luke.save
54
61
  Jedi.count.must_equal 1
55
62
  yoda.save
56
63
  Jedi.count.must_equal 2
57
64
  end
58
65
 
59
66
  it 'checking to_param' do
60
- luke.save
61
67
  luke.to_param.wont_be_nil
62
68
  luke.to_param.must_equal '1'
63
69
  end
70
+ end
64
71
 
65
- describe '==' do
66
- before do
67
- yoda.save
68
- luke.save
69
- jedi_council.save
70
- end
72
+ describe '==' do
73
+ before do
74
+ yoda.save
75
+ luke.save
76
+ jedi_council.save
77
+ end
71
78
 
72
- it 'comparing with the same registry' do
73
- (yoda == yoda).must_equal true
74
- end
79
+ it 'comparing with the same registry' do
80
+ (yoda == yoda).must_equal true
81
+ end
75
82
 
76
- it 'comparing with a diferent registry' do
77
- (yoda == luke).must_equal false
78
- end
83
+ it 'comparing with a diferent registry' do
84
+ (yoda == luke).must_equal false
85
+ end
79
86
 
80
- it 'comparing with another class registry' do
81
- (yoda == jedi_council).must_equal false
82
- end
87
+ it 'comparing with another class registry' do
88
+ (yoda == jedi_council).must_equal false
83
89
  end
90
+ end
84
91
 
85
- describe '!=' do
86
- before do
87
- yoda.save
88
- luke.save
89
- jedi_council.save
90
- end
92
+ describe '!=' do
93
+ before do
94
+ yoda.save
95
+ luke.save
96
+ jedi_council.save
97
+ end
91
98
 
92
- it 'comparing with the same registry' do
93
- (yoda != yoda).must_equal false
94
- end
99
+ it 'comparing with the same registry' do
100
+ (yoda != yoda).must_equal false
101
+ end
95
102
 
96
- it 'comparing with a diferent registry' do
97
- (yoda != luke).must_equal true
98
- end
103
+ it 'comparing with a diferent registry' do
104
+ (yoda != luke).must_equal true
105
+ end
99
106
 
100
- it 'comparing with another class registry' do
101
- (yoda != jedi_council).must_equal true
102
- end
107
+ it 'comparing with another class registry' do
108
+ (yoda != jedi_council).must_equal true
103
109
  end
110
+ end
104
111
 
105
- describe 'simple query' do
106
- let (:jedis) { [] }
112
+ describe 'simple query' do
113
+ let (:jedis) { [] }
107
114
 
108
- before do
109
- 3.times do
110
- jedis << luke.clone
111
- jedis.last.save
112
- end
115
+ before do
116
+ 3.times do
117
+ jedis << luke.clone
118
+ jedis.last.save
113
119
  end
120
+ end
114
121
 
115
- it 'querying by id' do
116
- Jedi.find(jedis.first.id).wont_be_nil
117
- Jedi.find(jedis.first.id).must_be_instance_of Jedi
118
- end
122
+ it 'querying by id' do
123
+ Jedi.find(jedis.first.id).wont_be_nil
124
+ Jedi.find(jedis.first.id).must_be_instance_of Jedi
125
+ end
119
126
 
120
- it 'querying by object' do
121
- Jedi.find(jedis.first).wont_be_nil
122
- Jedi.find(jedis.first.id).must_be_instance_of Jedi
123
- end
127
+ it 'querying by object' do
128
+ Jedi.find(jedis.first).wont_be_nil
129
+ Jedi.find(jedis.first.id).must_be_instance_of Jedi
130
+ end
124
131
 
125
- it 'gets the first' do
126
- first_jedi = Jedi.first
127
- first_jedi.wont_be_nil
128
- first_jedi.must_be_instance_of Jedi
129
- end
132
+ it 'gets the first' do
133
+ first_jedi = Jedi.first
134
+ first_jedi.wont_be_nil
135
+ first_jedi.must_be_instance_of Jedi
136
+ end
130
137
 
131
- it 'gets the last' do
132
- last_jedi = Jedi.last
133
- last_jedi.wont_be_nil
134
- last_jedi.must_be_instance_of Jedi
135
- end
138
+ it 'gets the last' do
139
+ last_jedi = Jedi.last
140
+ last_jedi.wont_be_nil
141
+ last_jedi.must_be_instance_of Jedi
136
142
  end
143
+ end
137
144
 
138
- describe 'complex queries' do
139
- before do
140
- luke.save
141
- qui_gon_jinn.save
142
- end
145
+ describe 'complex queries' do
146
+ before do
147
+ luke.save
148
+ qui_gon_jinn.save
149
+ end
143
150
 
144
- it 'with a single parameter' do
145
- result = Jedi.where age: 37
146
- result.wont_be_empty
147
- result.first.age.must_equal '37'
148
- end
151
+ it 'with a single parameter' do
152
+ result = Jedi.where age: 37
153
+ result.wont_be_empty
154
+ result.first.age.must_equal '37'
155
+ end
149
156
 
150
- it 'with multiple parameters' do
151
- result = Jedi.where age: 37, name: 'Qui-Gon Jinn', midi_chlorians: '3k'
152
- result.wont_be_empty
153
- result.first.age.must_equal '37'
154
- end
157
+ it 'with multiple parameters' do
158
+ result = Jedi.where age: 37, name: 'Qui-Gon Jinn', midi_chlorians: '3k'
159
+ result.wont_be_empty
160
+ result.first.age.must_equal '37'
161
+ end
155
162
 
156
- it 'with invalid parameter' do
157
- result = Jedi.where age: 22, name: 'Obi Wan Kenobi'
158
- result.must_be_empty
159
- end
163
+ it 'with invalid parameter' do
164
+ result = Jedi.where age: 22, name: 'Obi Wan Kenobi'
165
+ result.must_be_empty
160
166
  end
167
+ end
161
168
 
162
- describe 'dynamic finders' do
163
- before do
164
- luke.save
165
- yoda.save
166
- end
169
+ describe 'dynamic finders' do
170
+ before do
171
+ luke.save
172
+ yoda.save
173
+ end
167
174
 
168
- let (:properties) { Jedi.fields }
175
+ let (:properties) { Jedi.fields }
169
176
 
170
- it 'respond to certain dynamic methods' do
171
- Jedi.must_respond_to "find_by_#{properties.sample}"
172
- end
177
+ it 'respond to certain dynamic methods' do
178
+ Jedi.must_respond_to "find_by_#{properties.sample}"
179
+ end
173
180
 
174
- it 'finding with a single field' do
175
- found_jedis = Jedi.find_by_age 852
176
- found_jedis.wont_be_empty
177
- found_jedis.first.must_be_instance_of Jedi
178
- end
181
+ it 'finding with a single field' do
182
+ found_jedis = Jedi.find_by_age 852
183
+ found_jedis.wont_be_empty
184
+ found_jedis.first.must_be_instance_of Jedi
185
+ end
179
186
 
180
- it 'finding with multiple fields' do
181
- conditions = []
182
- properties.each_with_index do |property, i|
183
- values = []
184
- i.times do |k|
185
- conditions[i] = conditions[i] ? "#{conditions[i]}_and_#{properties[k]}" : properties[k]
186
- values << luke.send(properties[k])
187
- end
188
- if conditions[i]
189
- found_jedis = Jedi.public_send "find_by_#{conditions[i]}", *values
190
- found_jedis.wont_be_empty
191
- found_jedis.first.must_be_instance_of Jedi
192
- end
187
+ it 'finding with multiple fields' do
188
+ conditions = []
189
+ properties.each_with_index do |property, i|
190
+ values = []
191
+ i.times do |k|
192
+ conditions[i] = conditions[i] ? "#{conditions[i]}_and_#{properties[k]}" : properties[k]
193
+ values << luke.send(properties[k].name)
194
+ end
195
+ if conditions[i]
196
+ found_jedis = Jedi.public_send "find_by_#{conditions[i]}", *values
197
+ found_jedis.wont_be_empty
198
+ found_jedis.first.must_be_instance_of Jedi
193
199
  end
194
200
  end
195
201
  end
@@ -10,19 +10,16 @@ describe CsvRecord::Timestamps do
10
10
  describe 'defines on create' do
11
11
  before do
12
12
  Timecop.freeze(Time.now.utc)
13
+ luke.save
13
14
  end
14
15
 
15
- after do
16
- Timecop.return
17
- end
16
+ after { Timecop.return }
18
17
 
19
18
  it 'sets the time wich the object was created' do
20
- luke.save
21
19
  luke.created_at.must_equal Time.now.utc
22
20
  end
23
21
 
24
22
  it 'sets the updated time on created' do
25
- luke.save
26
23
  luke.updated_at.must_equal Time.now.utc
27
24
  end
28
25
  end
@@ -1,8 +1,4 @@
1
1
  require_relative '../test_helper'
2
- require 'pry'
3
- require_relative '../models/jedi'
4
- require_relative '../models/jedi_order'
5
- require_relative '../models/custom_errors_class'
6
2
 
7
3
  describe CsvRecord::Validations do
8
4
  let (:invalid_jedi) { Jedi.new }
@@ -13,12 +9,14 @@ describe CsvRecord::Validations do
13
9
  end
14
10
 
15
11
  describe 'initializing instance methods' do
16
- it ('responds to valid?') { Jedi.new.must_respond_to :valid? }
17
- it ('responds to invalid?') { Jedi.new.must_respond_to :invalid? }
18
- it ('responds to errors') { Jedi.new.must_respond_to :errors }
12
+ let (:jedi) { Jedi.new }
13
+
14
+ it ('responds to valid?') { jedi.must_respond_to :valid? }
15
+ it ('responds to invalid?') { jedi.must_respond_to :invalid? }
16
+ it ('responds to errors') { jedi.must_respond_to :errors }
19
17
  end
20
18
 
21
- describe 'validates_presence_of' do
19
+ describe '.validates_presence_of' do
22
20
  it 'all fields valid' do
23
21
  yoda.valid?.must_equal true
24
22
  end
@@ -37,7 +35,7 @@ describe CsvRecord::Validations do
37
35
  end
38
36
  end
39
37
 
40
- describe 'invalid?' do
38
+ describe '#invalid?' do
41
39
  it 'invalid object' do
42
40
  invalid_jedi.invalid?.must_equal true
43
41
  end
@@ -47,7 +45,7 @@ describe CsvRecord::Validations do
47
45
  end
48
46
  end
49
47
 
50
- describe 'errors' do
48
+ describe '#errors' do
51
49
  it 'wont be empty when invalid' do
52
50
  invalid_jedi.valid?
53
51
  invalid_jedi.errors.wont_be_empty
@@ -77,7 +75,7 @@ describe CsvRecord::Validations do
77
75
  end
78
76
  end
79
77
 
80
- describe 'validates_uniqueness_of' do
78
+ describe '.validates_uniqueness_of' do
81
79
  before { yoda.save }
82
80
 
83
81
  let :fake_yoda do
@@ -89,12 +87,13 @@ describe CsvRecord::Validations do
89
87
  end
90
88
  end
91
89
 
92
- describe 'custom_validator' do
93
- it ('responds to validate') { CustomErrorsClass.must_respond_to :validate }
94
-
90
+ describe '.custom_validator' do
95
91
  let(:custom_error_class) { CustomErrorsClass.new }
92
+
96
93
  before { custom_error_class.valid? }
97
94
 
95
+ it ('responds to validate') { CustomErrorsClass.must_respond_to :validate }
96
+
98
97
  it 'adding a custom validator' do
99
98
  custom_error_class.errors.must_include :custom_error
100
99
  end
@@ -10,8 +10,6 @@ describe CsvRecord::Writer do
10
10
  describe 'initializing instance methods' do
11
11
  it ('responds to save') { luke.must_respond_to :save }
12
12
  it ('responds to new_record?') { luke.must_respond_to :new_record? }
13
- it ('responds to calculate_id') { luke.must_respond_to :calculate_id }
14
- it ('responds to write_object') { luke.must_respond_to :write_object }
15
13
  it ('responds to id') { luke.must_respond_to :id }
16
14
  it ('responds to update_attribute') { luke.must_respond_to :update_attribute }
17
15
  it ('responds to update_attributes') { luke.must_respond_to :update_attributes }
@@ -19,7 +17,7 @@ describe CsvRecord::Writer do
19
17
  end
20
18
 
21
19
  describe 'validating the methods behavior' do
22
- describe 'create' do
20
+ describe '.create' do
23
21
  it "Creates more than one registry" do
24
22
  luke.save
25
23
  yoda.save
@@ -44,9 +42,18 @@ describe CsvRecord::Writer do
44
42
  yoda.save
45
43
  yoda.id.must_equal 2
46
44
  end
45
+
46
+ it 'should take a block' do
47
+ jedi = Jedi.create do |jedi|
48
+ jedi.name = 'Lukas Alexandre'
49
+ jedi.age = '24'
50
+ jedi.midi_chlorians = '99k'
51
+ end
52
+ jedi.new_record?.must_equal false
53
+ end
47
54
  end
48
55
 
49
- describe 'new_record' do
56
+ describe '#new_record' do
50
57
  it "Checks whether is a new record" do
51
58
  luke.new_record?.must_equal true
52
59
  luke.save
@@ -60,21 +67,33 @@ describe CsvRecord::Writer do
60
67
  end
61
68
 
62
69
  describe 'updates' do
63
- it "Updates a single field" do
64
- luke.save
65
- luke.update_attribute :age, 24
66
- Jedi.find(luke).age.must_equal '24'
70
+ before { luke.save }
71
+
72
+ describe '#update_attribute' do
73
+ it "Updates a single field" do
74
+ luke.update_attribute :age, 24
75
+ Jedi.find(luke).age.must_equal '24'
76
+ end
67
77
  end
68
78
 
69
- it "Updates multiple fields at the same time" do
70
- luke.save
71
- luke.update_attributes name: 'lukas', midi_chlorians: '99999k'
72
- Jedi.find(luke).name.must_equal 'lukas'
73
- Jedi.find(luke).midi_chlorians.must_equal '99999k'
79
+ describe '#update_attributes' do
80
+ it "Updates multiple fields at the same time" do
81
+ luke.update_attributes name: 'lukas', midi_chlorians: '99999k'
82
+ Jedi.find(luke).name.must_equal 'lukas'
83
+ Jedi.find(luke).midi_chlorians.must_equal '99999k'
84
+ end
85
+
86
+ it 'should take a block' do
87
+ luke.update_attributes do |jedi|
88
+ jedi.age = 25
89
+ jedi.name = 'Lukas Skywalker'
90
+ end
91
+ luke.age.must_equal 25
92
+ luke.name.must_equal 'Lukas Skywalker'
93
+ end
74
94
  end
75
95
 
76
96
  it "Updates multiple fields using save" do
77
- luke.save
78
97
  luke.name = 'lukas'
79
98
  luke.age = 24
80
99
  luke.save
@@ -84,20 +103,43 @@ describe CsvRecord::Writer do
84
103
  end
85
104
  end
86
105
 
87
- describe 'destroy' do
88
- it 'remove the object from the database' do
106
+ describe '#destroy' do
107
+ before do
89
108
  luke.save
90
109
  luke.destroy
110
+ end
111
+
112
+ it 'remove the object from the database' do
91
113
  Jedi.count.must_equal 0
92
114
  end
93
115
 
94
116
  it 'by destroying the object its timestamps and id should be empty' do
95
- luke.save
96
- luke.destroy
97
117
  luke.id.must_be_nil
98
118
  luke.created_at.must_be_nil
99
119
  luke.updated_at.must_be_nil
100
120
  end
101
121
  end
102
122
  end
123
+
124
+ describe '.store_as' do
125
+ it 'uses the default class name' do
126
+ Jedi.table_name.must_equal 'jedis'
127
+ end
128
+
129
+ it 'uses a custom database name' do
130
+ CustomizedClass.table_name.must_equal 'wierd_names'
131
+ end
132
+ end
133
+
134
+ describe '.mapping' do
135
+ it 'checking the fields initialization' do
136
+ CustomizedClass.fields.must_include :wierd_field
137
+ CustomizedClass.doppelganger_fields.wont_include :name
138
+ end
139
+
140
+ it 'checking the recovery of the custom field' do
141
+ CustomizedClass.create name: 'Ruppert'
142
+ CustomizedClass.first.name.must_equal 'Ruppert'
143
+ end
144
+ end
103
145
  end
data/test/helpers.rb ADDED
@@ -0,0 +1,7 @@
1
+ module Helpers
2
+ BASE_PATH = File.expand_path("../fixtures", __FILE__)
3
+
4
+ def fetch_fixture_path(path)
5
+ File.join(BASE_PATH, path)
6
+ end
7
+ end
@@ -0,0 +1,11 @@
1
+ class CustomizedClass
2
+ include CsvRecord::Document
3
+
4
+ store_as :wierd_name
5
+
6
+ mapping :name => :wierd_field
7
+
8
+ attr_accessor :name
9
+ end
10
+
11
+ # raise UndefienedCsvField unless self.fields.include? key
@@ -41,16 +41,14 @@ describe Object do
41
41
  'abc'.to_param.must_equal 'abc'
42
42
  end
43
43
 
44
- it 'passing a string' do
44
+ it 'passing a float' do
45
45
  (15.50).to_param.must_equal 15.50
46
46
  end
47
47
  end
48
48
 
49
49
  describe 'underscored_class_name' do
50
50
  it 'custom class' do
51
- new_class = Class.new
52
- MyCustomClass = new_class
53
-
51
+ MyCustomClass = Class.new
54
52
  MyCustomClass.new.underscored_class_name.must_equal 'my_custom_class'
55
53
  end
56
54
  end
data/test/test_helper.rb CHANGED
@@ -3,15 +3,18 @@ require 'minitest/autorun'
3
3
  require 'turn'
4
4
  require 'csv_record'
5
5
 
6
- module TestHelper
7
- BASE_PATH = File.expand_path("../fixtures", __FILE__)
6
+ require_relative 'helpers'
8
7
 
9
- def fetch_fixture_path(path)
10
- File.join(BASE_PATH, path)
11
- end
12
- end
8
+ require_relative 'models/jedi'
9
+ require_relative 'models/jedi_order'
10
+ require_relative 'models/padawan'
11
+ require_relative 'models/callback_test_class'
12
+ require_relative 'models/custom_errors_class'
13
+ require_relative 'models/customized_class'
13
14
 
14
15
  class MiniTest::Spec
16
+ include Helpers
17
+
15
18
  after :each do
16
19
  FileUtils.rm_rf 'db'
17
20
  end