csv_record 2.0.0 → 2.1.0

Sign up to get free protection for your applications and to get access to all the features.
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