csv_record 1.9.0 → 2.0.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/README.md +13 -221
- data/csv_record.gemspec +1 -0
- data/lib/csv_record/associations.rb +27 -29
- data/lib/csv_record/callback.rb +12 -0
- data/lib/csv_record/callbacks.rb +79 -77
- data/lib/csv_record/connector.rb +52 -46
- data/lib/csv_record/csv_queries/condition.rb +18 -0
- data/lib/csv_record/csv_queries/query.rb +73 -0
- data/lib/csv_record/csv_validations/custom_validation.rb +20 -0
- data/lib/csv_record/csv_validations/presence_validation.rb +13 -0
- data/lib/csv_record/csv_validations/uniqueness_validation.rb +16 -0
- data/lib/csv_record/csv_validations/validations.rb +87 -0
- data/lib/csv_record/document.rb +18 -21
- data/lib/csv_record/reader.rb +76 -97
- data/lib/csv_record/timestamps.rb +29 -29
- data/lib/csv_record/version.rb +1 -1
- data/lib/csv_record/writer.rb +78 -80
- data/test/csv_record/callbacks_test.rb +1 -1
- data/test/csv_record/condition_test.rb +35 -0
- data/test/csv_record/connector_test.rb +11 -11
- data/test/csv_record/query_test.rb +58 -0
- data/test/csv_record/reader_test.rb +64 -75
- data/test/csv_record/timestamps_test.rb +9 -16
- data/test/csv_record/validation_test.rb +8 -29
- data/test/csv_record/writer_test.rb +51 -65
- data/test/models/jedi.rb +1 -2
- data/test/test_helper.rb +1 -11
- metadata +30 -10
- data/lib/csv_record/validations.rb +0 -83
- data/test/csv_record/csv_record_test.rb +0 -8
- data/test/csv_record/document_test.rb +0 -6
- data/test/models/car.rb +0 -11
data/lib/csv_record/writer.rb
CHANGED
@@ -1,105 +1,103 @@
|
|
1
|
-
module CsvRecord
|
2
|
-
module
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
end
|
1
|
+
module CsvRecord::Writer
|
2
|
+
module ClassMethods
|
3
|
+
def __create__(attributes={})
|
4
|
+
instance = self.build attributes
|
5
|
+
result = instance.save
|
6
|
+
instance
|
7
|
+
end
|
9
8
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
end
|
9
|
+
[:attr_accessor, :attr_writer].each do |custom_accessor|
|
10
|
+
define_method custom_accessor do |*args|
|
11
|
+
@relevant_instance_variables ||= []
|
12
|
+
args.each { |arg| @relevant_instance_variables << arg }
|
13
|
+
super *args
|
16
14
|
end
|
17
|
-
|
18
|
-
alias :create :__create__
|
19
15
|
end
|
20
16
|
|
21
|
-
|
22
|
-
|
23
|
-
receiver.send :attr_accessor, :id
|
24
|
-
end
|
17
|
+
alias :create :__create__
|
18
|
+
end
|
25
19
|
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
false
|
31
|
-
end
|
32
|
-
end
|
20
|
+
module InstanceMethods
|
21
|
+
def self.included(receiver)
|
22
|
+
receiver.send :attr_accessor, :id
|
23
|
+
end
|
33
24
|
|
34
|
-
|
35
|
-
|
25
|
+
def __save__(validate=true)
|
26
|
+
if (not validate) || self.valid?
|
27
|
+
self.new_record? ? self.append_registry : self.update_registry
|
28
|
+
else
|
29
|
+
false
|
36
30
|
end
|
31
|
+
end
|
37
32
|
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
33
|
+
def new_record?
|
34
|
+
self.created_at.nil? || self.id.nil?
|
35
|
+
end
|
36
|
+
|
37
|
+
def __update_attribute__(field, value)
|
38
|
+
self.public_send "#{field}=", value
|
39
|
+
self.save false
|
40
|
+
end
|
42
41
|
|
43
|
-
|
44
|
-
|
45
|
-
|
42
|
+
def __update_attributes__(params={validate: true})
|
43
|
+
validate = params[:validate]
|
44
|
+
params.delete(:validate)
|
46
45
|
|
47
|
-
|
48
|
-
|
49
|
-
end
|
50
|
-
self.save validate
|
46
|
+
params.each do |field, value|
|
47
|
+
self.public_send "#{field}=", value
|
51
48
|
end
|
49
|
+
self.save validate
|
50
|
+
end
|
52
51
|
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
end
|
59
|
-
empty_fields
|
60
|
-
true
|
52
|
+
def __destroy__
|
53
|
+
self.class.parse_database_file do |row|
|
54
|
+
new_row = row
|
55
|
+
new_row = nil if self.id.to_i == row.field('id').to_i
|
56
|
+
new_row
|
61
57
|
end
|
58
|
+
empty_fields
|
59
|
+
true
|
60
|
+
end
|
62
61
|
|
63
|
-
|
62
|
+
protected
|
64
63
|
|
65
|
-
|
66
|
-
|
67
|
-
|
64
|
+
def calculate_id
|
65
|
+
@id = self.class.count + 1
|
66
|
+
end
|
68
67
|
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
68
|
+
def append_registry
|
69
|
+
set_created_at
|
70
|
+
write_object
|
71
|
+
end
|
73
72
|
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
end
|
81
|
-
true
|
73
|
+
def update_registry
|
74
|
+
set_updated_at
|
75
|
+
self.class.parse_database_file do |row|
|
76
|
+
new_row = row
|
77
|
+
new_row = self.values if self.id.to_i == row.field('id').to_i
|
78
|
+
new_row
|
82
79
|
end
|
80
|
+
true
|
81
|
+
end
|
83
82
|
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
end
|
89
|
-
true
|
83
|
+
def __write_object__
|
84
|
+
calculate_id
|
85
|
+
self.class.open_database_file CsvRecord::Connector::APPEND_MODE do |csv|
|
86
|
+
csv << values
|
90
87
|
end
|
88
|
+
true
|
89
|
+
end
|
91
90
|
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
end
|
91
|
+
def empty_fields
|
92
|
+
%w(id created_at updated_at).each do |field|
|
93
|
+
self.public_send "#{field}=", nil
|
96
94
|
end
|
97
|
-
|
98
|
-
alias :save :__save__
|
99
|
-
alias :write_object :__write_object__
|
100
|
-
alias :update_attribute :__update_attribute__
|
101
|
-
alias :destroy :__destroy__
|
102
|
-
alias :update_attributes :__update_attributes__
|
103
95
|
end
|
96
|
+
|
97
|
+
alias :save :__save__
|
98
|
+
alias :write_object :__write_object__
|
99
|
+
alias :update_attribute :__update_attribute__
|
100
|
+
alias :destroy :__destroy__
|
101
|
+
alias :update_attributes :__update_attributes__
|
104
102
|
end
|
105
103
|
end
|
@@ -1,5 +1,4 @@
|
|
1
1
|
require_relative '../test_helper'
|
2
|
-
require_relative '../models/car'
|
3
2
|
require_relative '../models/callback_test_class'
|
4
3
|
|
5
4
|
describe CsvRecord::Callbacks do
|
@@ -85,6 +84,7 @@ describe CsvRecord::Callbacks do
|
|
85
84
|
it 'after_destroy' do
|
86
85
|
object_destroyed.after_destroy_called.must_equal true
|
87
86
|
end
|
87
|
+
|
88
88
|
it 'before_destroy' do
|
89
89
|
object_destroyed.before_destroy_called.must_equal true
|
90
90
|
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require_relative '../test_helper'
|
2
|
+
|
3
|
+
describe CsvRecord::Condition do
|
4
|
+
let (:condition) { CsvRecord::Condition.new :age, 37 }
|
5
|
+
|
6
|
+
describe 'checking query initialization' do
|
7
|
+
it 'field should be "age"' do
|
8
|
+
condition.field.must_equal :age
|
9
|
+
end
|
10
|
+
|
11
|
+
it 'value should be "37"' do
|
12
|
+
condition.value.must_equal 37
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
describe '.create_from_hashes' do
|
17
|
+
it 'with one' do
|
18
|
+
conditions = CsvRecord::Condition.create_from_hashes age: 37
|
19
|
+
conditions.size.must_equal 1
|
20
|
+
conditions.first.must_be_instance_of CsvRecord::Condition
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'more than one' do
|
24
|
+
conditions = CsvRecord::Condition.create_from_hashes age: 37, midi_chlorians: '3k'
|
25
|
+
conditions.size.must_equal 2
|
26
|
+
conditions.first.must_be_instance_of CsvRecord::Condition
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
describe '#to_code' do
|
31
|
+
it 'trasforming the field and value' do
|
32
|
+
condition.to_code.must_equal "attributes['age'] == '37'"
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -1,30 +1,30 @@
|
|
1
1
|
require_relative '../test_helper'
|
2
2
|
|
3
|
-
require_relative '../models/
|
3
|
+
require_relative '../models/jedi'
|
4
4
|
|
5
5
|
describe CsvRecord::Connector do
|
6
6
|
describe 'initializing methods' do
|
7
|
-
it ('responds to initialize_db_directory') {
|
8
|
-
it ('responds to initialize_db') {
|
9
|
-
it ('responds to db_initialized?') {
|
10
|
-
it ('responds to open_database_file') {
|
7
|
+
it ('responds to initialize_db_directory') { Jedi.must_respond_to :initialize_db_directory }
|
8
|
+
it ('responds to initialize_db') { Jedi.must_respond_to :initialize_db }
|
9
|
+
it ('responds to db_initialized?') { Jedi.must_respond_to :db_initialized? }
|
10
|
+
it ('responds to open_database_file') { Jedi.must_respond_to :open_database_file }
|
11
11
|
end
|
12
12
|
|
13
13
|
describe 'validating the methods behavior' do
|
14
14
|
it "Creates the database folder" do
|
15
|
-
|
15
|
+
Jedi.initialize_db_directory.wont_be_nil
|
16
16
|
Dir.exists?('db').must_equal true
|
17
17
|
end
|
18
18
|
|
19
19
|
it "Checks the database initialization state" do
|
20
|
-
|
21
|
-
|
22
|
-
|
20
|
+
Jedi.db_initialized?.must_equal false
|
21
|
+
luke.save
|
22
|
+
Jedi.db_initialized?.must_equal true
|
23
23
|
end
|
24
24
|
|
25
25
|
it "Creates the database file" do
|
26
|
-
|
27
|
-
File.exists?(
|
26
|
+
luke.save
|
27
|
+
File.exists?(Jedi::DATABASE_LOCATION).must_equal true
|
28
28
|
end
|
29
29
|
end
|
30
30
|
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
require_relative '../test_helper'
|
2
|
+
require_relative '../models/jedi'
|
3
|
+
|
4
|
+
describe CsvRecord::Query do
|
5
|
+
let (:query) { CsvRecord::Query.new Jedi, age: 37 }
|
6
|
+
|
7
|
+
describe 'checking query initialization' do
|
8
|
+
describe 'setting the conditions' do
|
9
|
+
it 'checking the amount' do
|
10
|
+
query.conditions.length.must_equal 1
|
11
|
+
end
|
12
|
+
|
13
|
+
it 'checking the type' do
|
14
|
+
query.conditions.first.must_be_instance_of CsvRecord::Condition
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
describe '#where' do
|
20
|
+
describe 'adding more conditions' do
|
21
|
+
let (:second_query) { CsvRecord::Query.new Jedi, age: 852 }
|
22
|
+
|
23
|
+
it 'to one query' do
|
24
|
+
query.where name: 'Luke Skywalker'
|
25
|
+
query.conditions.length.must_equal 2
|
26
|
+
end
|
27
|
+
|
28
|
+
it 'two queries' do
|
29
|
+
query.where midi_chlorians: '4k'
|
30
|
+
|
31
|
+
query.conditions.length.must_equal 2
|
32
|
+
second_query.conditions.length.must_equal 1
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
describe 'lazy querying' do
|
38
|
+
before do
|
39
|
+
yoda.save
|
40
|
+
qui_gon_jinn.save
|
41
|
+
end
|
42
|
+
|
43
|
+
describe 'should trigger the query' do
|
44
|
+
it 'when calling the to_a' do
|
45
|
+
query.to_a.must_be_instance_of Array
|
46
|
+
query.to_a.first.must_be_instance_of Jedi
|
47
|
+
end
|
48
|
+
|
49
|
+
it 'when calling the first' do
|
50
|
+
query.last.must_be_instance_of Jedi
|
51
|
+
end
|
52
|
+
|
53
|
+
it 'when calling the last' do
|
54
|
+
query.first.must_be_instance_of Jedi
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -1,76 +1,65 @@
|
|
1
1
|
require_relative '../test_helper'
|
2
2
|
|
3
|
-
require_relative '../models/car'
|
4
3
|
require_relative '../models/jedi'
|
5
4
|
|
6
5
|
describe CsvRecord::Reader do
|
7
6
|
describe 'initializing class methods' do
|
8
|
-
it ('responds to fields') {
|
9
|
-
it ('responds to all') {
|
7
|
+
it ('responds to fields') { Jedi.must_respond_to :fields }
|
8
|
+
it ('responds to all') { Jedi.must_respond_to :all }
|
10
9
|
end
|
11
10
|
|
12
11
|
describe 'initializing instance methods' do
|
13
|
-
|
14
|
-
|
15
|
-
it ('responds to
|
16
|
-
it ('responds to
|
17
|
-
it ('responds to
|
12
|
+
let (:klass) { Jedi.new }
|
13
|
+
|
14
|
+
it ('responds to values') { klass.must_respond_to :values }
|
15
|
+
it ('responds to attributes') { klass.must_respond_to :attributes }
|
16
|
+
it ('responds to to_param') { klass.must_respond_to :to_param }
|
17
|
+
it ('responds to ==') { klass.must_respond_to :== }
|
18
|
+
it ('responds to !=') { klass.must_respond_to :!= }
|
18
19
|
end
|
19
20
|
|
20
21
|
describe 'validating the methods behavior' do
|
21
|
-
let(:second_car) do
|
22
|
-
Car.build(
|
23
|
-
year: 2007,
|
24
|
-
make: 'Chevrolet',
|
25
|
-
model: 'F450',
|
26
|
-
description: 'ac, abs, moon',
|
27
|
-
price: 5000.00
|
28
|
-
)
|
29
|
-
end
|
30
|
-
|
31
22
|
it 'building an instance' do
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
description: 'ac, abs, moon',
|
37
|
-
price: 5000.00
|
23
|
+
new_jedi = Jedi.build(
|
24
|
+
name: 'Yoda the red',
|
25
|
+
age: 148,
|
26
|
+
midi_chlorians: '0.5k'
|
38
27
|
)
|
39
|
-
|
40
|
-
|
28
|
+
new_jedi.wont_be_nil
|
29
|
+
new_jedi.must_be_instance_of Jedi
|
41
30
|
end
|
42
31
|
|
43
|
-
it
|
44
|
-
|
32
|
+
it 'Check the current fields' do
|
33
|
+
Jedi.fields.must_equal [:id, :created_at, :updated_at, :name, :age, :midi_chlorians, "jedi_order_id"]
|
45
34
|
end
|
46
35
|
|
47
|
-
it
|
48
|
-
|
36
|
+
it 'Check the current values' do
|
37
|
+
luke.values.must_equal [nil, nil, nil, "Luke Skywalker", 18, "12k", 0]
|
49
38
|
end
|
50
39
|
|
51
|
-
it
|
52
|
-
expected_result = {id
|
53
|
-
|
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
|
54
43
|
end
|
55
44
|
|
56
45
|
it "Retrieves all registries" do
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
46
|
+
luke.save
|
47
|
+
Jedi.all.size.must_equal 1
|
48
|
+
yoda.save
|
49
|
+
Jedi.all.size.must_equal 2
|
61
50
|
end
|
62
51
|
|
63
52
|
it "counting the registries" do
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
53
|
+
luke.save
|
54
|
+
Jedi.count.must_equal 1
|
55
|
+
yoda.save
|
56
|
+
Jedi.count.must_equal 2
|
68
57
|
end
|
69
58
|
|
70
59
|
it 'checking to_param' do
|
71
|
-
|
72
|
-
|
73
|
-
|
60
|
+
luke.save
|
61
|
+
luke.to_param.wont_be_nil
|
62
|
+
luke.to_param.must_equal '1'
|
74
63
|
end
|
75
64
|
|
76
65
|
describe '==' do
|
@@ -114,78 +103,78 @@ describe CsvRecord::Reader do
|
|
114
103
|
end
|
115
104
|
|
116
105
|
describe 'simple query' do
|
117
|
-
let (:
|
106
|
+
let (:jedis) { [] }
|
118
107
|
|
119
108
|
before do
|
120
109
|
3.times do
|
121
|
-
|
122
|
-
|
110
|
+
jedis << luke.clone
|
111
|
+
jedis.last.save
|
123
112
|
end
|
124
113
|
end
|
125
114
|
|
126
115
|
it 'querying by id' do
|
127
|
-
|
128
|
-
|
116
|
+
Jedi.find(jedis.first.id).wont_be_nil
|
117
|
+
Jedi.find(jedis.first.id).must_be_instance_of Jedi
|
129
118
|
end
|
130
119
|
|
131
120
|
it 'querying by object' do
|
132
|
-
|
133
|
-
|
121
|
+
Jedi.find(jedis.first).wont_be_nil
|
122
|
+
Jedi.find(jedis.first.id).must_be_instance_of Jedi
|
134
123
|
end
|
135
124
|
|
136
125
|
it 'gets the first' do
|
137
|
-
|
138
|
-
|
139
|
-
|
126
|
+
first_jedi = Jedi.first
|
127
|
+
first_jedi.wont_be_nil
|
128
|
+
first_jedi.must_be_instance_of Jedi
|
140
129
|
end
|
141
130
|
|
142
131
|
it 'gets the last' do
|
143
|
-
|
144
|
-
|
145
|
-
|
132
|
+
last_jedi = Jedi.last
|
133
|
+
last_jedi.wont_be_nil
|
134
|
+
last_jedi.must_be_instance_of Jedi
|
146
135
|
end
|
147
136
|
end
|
148
137
|
|
149
138
|
describe 'complex queries' do
|
150
139
|
before do
|
151
|
-
|
152
|
-
|
140
|
+
luke.save
|
141
|
+
qui_gon_jinn.save
|
153
142
|
end
|
154
143
|
|
155
144
|
it 'with a single parameter' do
|
156
|
-
result =
|
145
|
+
result = Jedi.where age: 37
|
157
146
|
result.wont_be_empty
|
158
|
-
result.first.
|
147
|
+
result.first.age.must_equal '37'
|
159
148
|
end
|
160
149
|
|
161
150
|
it 'with multiple parameters' do
|
162
|
-
result =
|
151
|
+
result = Jedi.where age: 37, name: 'Qui-Gon Jinn', midi_chlorians: '3k'
|
163
152
|
result.wont_be_empty
|
164
|
-
result.first.
|
153
|
+
result.first.age.must_equal '37'
|
165
154
|
end
|
166
155
|
|
167
156
|
it 'with invalid parameter' do
|
168
|
-
result =
|
157
|
+
result = Jedi.where age: 22, name: 'Obi Wan Kenobi'
|
169
158
|
result.must_be_empty
|
170
159
|
end
|
171
160
|
end
|
172
161
|
|
173
162
|
describe 'dynamic finders' do
|
174
163
|
before do
|
175
|
-
|
176
|
-
|
164
|
+
luke.save
|
165
|
+
yoda.save
|
177
166
|
end
|
178
167
|
|
179
|
-
let (:properties) {
|
168
|
+
let (:properties) { Jedi.fields }
|
180
169
|
|
181
170
|
it 'respond to certain dynamic methods' do
|
182
|
-
|
171
|
+
Jedi.must_respond_to "find_by_#{properties.sample}"
|
183
172
|
end
|
184
173
|
|
185
174
|
it 'finding with a single field' do
|
186
|
-
|
187
|
-
|
188
|
-
|
175
|
+
found_jedis = Jedi.find_by_age 852
|
176
|
+
found_jedis.wont_be_empty
|
177
|
+
found_jedis.first.must_be_instance_of Jedi
|
189
178
|
end
|
190
179
|
|
191
180
|
it 'finding with multiple fields' do
|
@@ -194,12 +183,12 @@ describe CsvRecord::Reader do
|
|
194
183
|
values = []
|
195
184
|
i.times do |k|
|
196
185
|
conditions[i] = conditions[i] ? "#{conditions[i]}_and_#{properties[k]}" : properties[k]
|
197
|
-
values <<
|
186
|
+
values << luke.send(properties[k])
|
198
187
|
end
|
199
188
|
if conditions[i]
|
200
|
-
|
201
|
-
|
202
|
-
|
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
|
203
192
|
end
|
204
193
|
end
|
205
194
|
end
|
@@ -2,16 +2,9 @@ require_relative '../test_helper'
|
|
2
2
|
|
3
3
|
require 'timecop'
|
4
4
|
|
5
|
-
require_relative '../models/car'
|
6
|
-
|
7
5
|
describe CsvRecord::Timestamps do
|
8
|
-
describe 'initializing instance methods' do
|
9
|
-
it ('responds to created_at') { car.must_respond_to :created_at }
|
10
|
-
it ('responds to set_created_at') { car.must_respond_to :set_created_at }
|
11
|
-
end
|
12
|
-
|
13
6
|
describe 'checking if it`s extracting the right fields' do
|
14
|
-
it ('checking created_at') {
|
7
|
+
it ('checking created_at') { Jedi.fields.must_include :created_at }
|
15
8
|
end
|
16
9
|
|
17
10
|
describe 'defines on create' do
|
@@ -24,22 +17,22 @@ describe CsvRecord::Timestamps do
|
|
24
17
|
end
|
25
18
|
|
26
19
|
it 'sets the time wich the object was created' do
|
27
|
-
|
28
|
-
|
20
|
+
luke.save
|
21
|
+
luke.created_at.must_equal Time.now.utc
|
29
22
|
end
|
30
23
|
|
31
24
|
it 'sets the updated time on created' do
|
32
|
-
|
33
|
-
|
25
|
+
luke.save
|
26
|
+
luke.updated_at.must_equal Time.now.utc
|
34
27
|
end
|
35
28
|
end
|
36
29
|
|
37
30
|
describe 'update on update' do
|
38
31
|
it 'sets the updated_at attribute on every save' do
|
39
|
-
|
40
|
-
previous_time =
|
41
|
-
|
42
|
-
|
32
|
+
luke.save
|
33
|
+
previous_time = luke.updated_at
|
34
|
+
luke.update_attribute :age, '18'
|
35
|
+
luke.updated_at.wont_equal previous_time
|
43
36
|
end
|
44
37
|
end
|
45
38
|
end
|
@@ -18,44 +18,23 @@ describe CsvRecord::Validations do
|
|
18
18
|
it ('responds to errors') { Jedi.new.must_respond_to :errors }
|
19
19
|
end
|
20
20
|
|
21
|
-
describe 'validates_presence_of
|
22
|
-
it '
|
23
|
-
yoda.name = nil
|
24
|
-
yoda.valid?.wont_equal true
|
25
|
-
end
|
26
|
-
|
27
|
-
it 'is not valid without age' do
|
28
|
-
yoda.age = nil
|
29
|
-
yoda.valid?.wont_equal true
|
30
|
-
end
|
31
|
-
|
32
|
-
it "is valid with all attributes filled" do
|
21
|
+
describe 'validates_presence_of' do
|
22
|
+
it 'all fields valid' do
|
33
23
|
yoda.valid?.must_equal true
|
34
24
|
end
|
35
25
|
|
36
|
-
it
|
37
|
-
yoda.save.must_equal true
|
38
|
-
end
|
39
|
-
|
40
|
-
it "doesn't save without name" do
|
41
|
-
yoda.name = nil
|
42
|
-
yoda.valid?.wont_equal true
|
43
|
-
yoda.save.wont_equal true
|
44
|
-
end
|
45
|
-
|
46
|
-
it "doesn't save without age" do
|
26
|
+
it 'one invalid field' do
|
47
27
|
yoda.age = nil
|
48
|
-
yoda.valid?.
|
49
|
-
yoda.save.wont_equal true
|
28
|
+
yoda.valid?.must_equal false
|
50
29
|
end
|
51
30
|
|
52
|
-
it
|
31
|
+
it 'all fields invalid' do
|
53
32
|
yoda.age = nil
|
54
33
|
yoda.name = nil
|
55
|
-
yoda.valid?.
|
56
|
-
yoda.
|
34
|
+
yoda.valid?.must_equal false
|
35
|
+
yoda.errors.must_include :age
|
36
|
+
yoda.errors.must_include :name
|
57
37
|
end
|
58
|
-
|
59
38
|
end
|
60
39
|
|
61
40
|
describe 'invalid?' do
|