anixe_csv 0.0.1 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/anixe_csv.rb +1 -3
- data/lib/anixe_csv/formatter.rb +104 -84
- data/lib/anixe_csv/version.rb +1 -1
- data/test/formatter_index_assignment_test.rb +14 -0
- data/test/formatter_len_test.rb +27 -0
- data/test/formatter_multi_instance_test.rb +22 -0
- data/test/formatter_test.rb +2 -1
- metadata +9 -3
data/lib/anixe_csv.rb
CHANGED
data/lib/anixe_csv/formatter.rb
CHANGED
@@ -59,25 +59,31 @@ module AnixeCsv
|
|
59
59
|
def create_accessor(name)
|
60
60
|
self.module_eval <<-end_eval
|
61
61
|
def #{name}
|
62
|
-
|
62
|
+
data[:#{name}]
|
63
63
|
end
|
64
|
+
def #{name}!
|
65
|
+
fields[:#{name}].to_s(data[:#{name}])
|
66
|
+
end
|
64
67
|
def #{name}= (value)
|
65
|
-
|
68
|
+
data[:#{name}] = value
|
66
69
|
end
|
67
70
|
end_eval
|
68
71
|
end
|
69
72
|
end
|
70
73
|
|
71
74
|
module InstanceMethods # visible in the including class
|
72
|
-
|
73
75
|
# returns the value of the field by name or index
|
74
76
|
def [](arg)
|
75
|
-
return
|
76
|
-
return
|
77
|
+
return data[arg.to_sym] if arg.kind_of? String
|
78
|
+
return data.values[arg.to_i] if arg.kind_of? Fixnum
|
77
79
|
|
78
80
|
nil
|
79
81
|
end
|
80
82
|
|
83
|
+
def []=(key, value)
|
84
|
+
data[key.to_sym] = value
|
85
|
+
end
|
86
|
+
|
81
87
|
# Reset all fields to nil or their default value
|
82
88
|
def clear!
|
83
89
|
set_field_values([])
|
@@ -93,86 +99,100 @@ module AnixeCsv
|
|
93
99
|
end
|
94
100
|
|
95
101
|
alias kernel_to_s to_s # candy - otherwise formatting definition in field blocks would be called e.g. in irb
|
96
|
-
def inspect
|
97
|
-
to_hash
|
98
|
-
end
|
99
|
-
|
100
|
-
def to_hash
|
101
|
-
ary = fields.values.collect {|field| [field.name, field.value]}
|
102
|
-
Hash[ary]
|
103
|
-
end
|
104
|
-
|
105
|
-
# outputs all fields in one line and formats each field with a block if given
|
106
|
-
def to_s
|
107
|
-
values = fields.values.collect do |field|
|
108
|
-
value = field.to_s.to_s
|
109
|
-
value = value.tr(*singleton.get_escape)
|
110
|
-
validate_field(field, value) if validate?
|
111
|
-
|
112
|
-
value
|
113
|
-
end
|
114
|
-
|
115
|
-
singleton.rules.each do |rule|
|
116
|
-
rule.call(self)
|
117
|
-
end
|
118
|
-
|
119
|
-
values.join(delimiter)
|
120
|
-
end
|
121
|
-
|
122
|
-
def validate?
|
123
|
-
@validate
|
124
|
-
end
|
125
|
-
|
126
|
-
def validate=(value=true)
|
127
|
-
@validate = value
|
128
|
-
end
|
129
|
-
|
130
|
-
def values=(ary)
|
131
|
-
set_field_values(ary)
|
132
|
-
end
|
133
|
-
|
134
|
-
def values
|
135
|
-
fields.values.collect(&:value)
|
136
|
-
end
|
137
|
-
end
|
138
|
-
|
139
|
-
private
|
140
|
-
def singleton
|
141
|
-
self.class
|
142
|
-
end
|
143
|
-
|
144
|
-
def validate_field(field, value)
|
145
|
-
raise RegexpError, "Field '#{field.name}' contains an invalid value '#{value}' it should match #{field.regexp}" if field.regexp && value !~ field.regexp
|
146
|
-
end
|
147
|
-
|
148
|
-
# assign all the fields their values from an array, if nil is passed the default value is used
|
149
|
-
def set_field_values(array)
|
150
|
-
fields.values.each_index do |idx|
|
151
|
-
value = array[idx]
|
152
|
-
field = fields.values[idx]
|
153
|
-
value = field.default if value.nil?
|
154
|
-
field.value = value
|
155
|
-
end
|
156
|
-
end
|
157
102
|
|
158
|
-
|
159
|
-
|
103
|
+
def data
|
104
|
+
@data ||= set_field_values([])
|
105
|
+
end
|
160
106
|
|
161
|
-
|
162
|
-
|
163
|
-
@value = @default = args[1] unless args[1].nil?
|
164
|
-
end
|
107
|
+
alias_method :to_hash, :data
|
108
|
+
alias_method :inspect, :data
|
165
109
|
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
110
|
+
# outputs all fields in one line and formats each field with a block if given
|
111
|
+
def to_s
|
112
|
+
values = fields.values.collect do |field|
|
113
|
+
value = field.to_s(data[field.name]).to_s
|
114
|
+
value = value.tr(*singleton.get_escape)
|
115
|
+
validate_field(field, value) if validate?
|
116
|
+
|
117
|
+
value
|
118
|
+
end
|
119
|
+
|
120
|
+
singleton.rules.each do |rule|
|
121
|
+
rule.call(self)
|
122
|
+
end
|
123
|
+
|
124
|
+
values.join(delimiter)
|
125
|
+
end
|
126
|
+
|
127
|
+
def validate?
|
128
|
+
@validate
|
129
|
+
end
|
130
|
+
|
131
|
+
def validate=(value=true)
|
132
|
+
@validate = value
|
133
|
+
end
|
134
|
+
|
135
|
+
def values=(ary)
|
136
|
+
set_field_values(ary)
|
137
|
+
end
|
138
|
+
|
139
|
+
def values
|
140
|
+
data.values
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
private
|
145
|
+
def singleton
|
146
|
+
self.class
|
147
|
+
end
|
148
|
+
|
149
|
+
def validate_field(field, value)
|
150
|
+
raise RegexpError, "Field '#{field.name}' contains an invalid value '#{value}' it should match #{field.regexp}" if field.regexp && value !~ field.regexp
|
151
|
+
end
|
152
|
+
|
153
|
+
# assign all the fields their values from an array, if nil is passed the default value is used
|
154
|
+
def set_field_values(array)
|
155
|
+
@data = {}
|
156
|
+
fields.values.each_index do |idx|
|
157
|
+
value = array[idx]
|
158
|
+
field = fields.values[idx]
|
159
|
+
value = field.default if value.nil?
|
160
|
+
@data[field.name] = value
|
161
|
+
end
|
162
|
+
@data
|
163
|
+
end
|
164
|
+
|
165
|
+
class Field
|
166
|
+
attr_accessor :name, :block, :default, :regexp
|
167
|
+
|
168
|
+
def value
|
169
|
+
raise "The use of value is deprecated, use the instance methods instead"
|
170
|
+
end
|
171
|
+
|
172
|
+
def initialize(*args)
|
173
|
+
@name = args[0]
|
174
|
+
@default = args[1] unless args[1].nil?
|
175
|
+
@opts = args[2] || {}
|
176
|
+
end
|
177
|
+
|
178
|
+
def to_s(s=nil)
|
179
|
+
return prepare_value(s) if @opts.empty?
|
180
|
+
|
181
|
+
pad = @opts[:pad] || ' '
|
182
|
+
return prepare_value(s).ljust(@opts[:ljust], pad) if @opts[:ljust]
|
183
|
+
return prepare_value(s).rjust(@opts[:rjust], pad) if @opts[:rjust]
|
184
|
+
end
|
185
|
+
|
186
|
+
def prepare_value(s)
|
187
|
+
unless block.nil?
|
188
|
+
block.call(s, self)
|
189
|
+
else
|
190
|
+
s
|
191
|
+
end
|
192
|
+
end
|
193
|
+
end
|
194
|
+
|
195
|
+
class RuleError < StandardError
|
196
|
+
end
|
197
|
+
end
|
178
198
|
end
|
data/lib/anixe_csv/version.rb
CHANGED
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'test_config'
|
2
|
+
require 'anixe_csv/formatter'
|
3
|
+
|
4
|
+
context 'Formatter should allow to assign values by index operator' do
|
5
|
+
class IndexAssignmentTest
|
6
|
+
include AnixeCsv::Formatter
|
7
|
+
field :one
|
8
|
+
end
|
9
|
+
|
10
|
+
setup { IndexAssignmentTest.new }
|
11
|
+
|
12
|
+
should('assign with symbol') { topic[:one] = 1; topic.one }.equals 1
|
13
|
+
should('assign with string') { topic['one'] = 2; topic.one }.equals 2
|
14
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'test_config'
|
2
|
+
require 'anixe_csv/formatter'
|
3
|
+
|
4
|
+
context 'Formatter - lest and right justification' do
|
5
|
+
DEFAULT_TWO = "DefaultTwo"
|
6
|
+
VALUES = [1, nil, 3, 4, ';', nil]
|
7
|
+
|
8
|
+
class CsvWriterLenTest
|
9
|
+
include AnixeCsv::Formatter
|
10
|
+
|
11
|
+
delimiter '' # field delimiter
|
12
|
+
escape ";&", "_" # escapes characters using string.tr
|
13
|
+
|
14
|
+
field :one, '.', :ljust => 5
|
15
|
+
field :two, '.', :rjust => 5
|
16
|
+
field :three, '.', :ljust => 5, :pad => '0'
|
17
|
+
field :four, '.', :rjust => 5, :pad => '0'
|
18
|
+
|
19
|
+
end
|
20
|
+
|
21
|
+
setup { CsvWriterLenTest.new }
|
22
|
+
should('left justify') { topic.one! == '. ' }
|
23
|
+
should('right justify') { topic.two! == ' .' }
|
24
|
+
should('left justify with a padding string: ') { topic.three! }.equals '.0000'
|
25
|
+
should('right justify with a padding string: ') { topic.four! }.equals '0000.'
|
26
|
+
should('format the whole thing correctly: ') { topic.to_s }.equals '. ..00000000.'
|
27
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'test_config'
|
2
|
+
require 'anixe_csv/formatter'
|
3
|
+
|
4
|
+
context 'Formatter should return different values for two instances' do
|
5
|
+
class MultiInstanceFormatter
|
6
|
+
include AnixeCsv::Formatter
|
7
|
+
field :one
|
8
|
+
field :two, '--'
|
9
|
+
end
|
10
|
+
|
11
|
+
setup {
|
12
|
+
instances = [MultiInstanceFormatter.new, MultiInstanceFormatter.new]
|
13
|
+
instances[0].one = "01"
|
14
|
+
instances[1].one = "11"
|
15
|
+
instances
|
16
|
+
}
|
17
|
+
|
18
|
+
should('01 = 01') { topic[0].one }.equals('01')
|
19
|
+
should('11 = 11') { topic[1].one }.equals('11')
|
20
|
+
should('first.to_s') { topic[0].to_s }.equals('01,--')
|
21
|
+
should('second.to_s') { topic[1].to_s }.equals('11,--')
|
22
|
+
end
|
data/test/formatter_test.rb
CHANGED
@@ -51,7 +51,7 @@ context 'Formatter' do
|
|
51
51
|
asserts(:to_s).equals("one;DefaultTwo;3;4k;_;;bread _ butter")
|
52
52
|
asserts(:to_hash).equals({:one => 1, :two => DEFAULT_TWO, :three => 3, :four => 4, :five => ";", :six => nil, :seven => "bread & butter"})
|
53
53
|
end
|
54
|
-
|
54
|
+
|
55
55
|
context "#clear!" do
|
56
56
|
setup do
|
57
57
|
CsvWriterTest.new.tap do |writer|
|
@@ -63,4 +63,5 @@ context 'Formatter' do
|
|
63
63
|
asserts(:values).equals([nil, DEFAULT_TWO, nil, nil, nil, nil, nil])
|
64
64
|
asserts(:to_s).raises(RegexpError)
|
65
65
|
end
|
66
|
+
|
66
67
|
end
|
metadata
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
name: anixe_csv
|
3
3
|
version: !ruby/object:Gem::Version
|
4
4
|
prerelease:
|
5
|
-
version: 0.0
|
5
|
+
version: 0.3.0
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- Piotr Zolnierek
|
@@ -10,7 +10,7 @@ autorequire:
|
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
12
|
|
13
|
-
date: 2011-
|
13
|
+
date: 2011-06-24 00:00:00 +02:00
|
14
14
|
default_executable:
|
15
15
|
dependencies: []
|
16
16
|
|
@@ -36,6 +36,9 @@ files:
|
|
36
36
|
- lib/anixe_csv/reader.rb
|
37
37
|
- lib/anixe_csv/row.rb
|
38
38
|
- lib/anixe_csv/version.rb
|
39
|
+
- test/formatter_index_assignment_test.rb
|
40
|
+
- test/formatter_len_test.rb
|
41
|
+
- test/formatter_multi_instance_test.rb
|
39
42
|
- test/formatter_rule_test.rb
|
40
43
|
- test/formatter_test.rb
|
41
44
|
- test/gzip_reader_test.rb
|
@@ -67,11 +70,14 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
67
70
|
requirements: []
|
68
71
|
|
69
72
|
rubyforge_project: anixe_csv
|
70
|
-
rubygems_version: 1.
|
73
|
+
rubygems_version: 1.6.2
|
71
74
|
signing_key:
|
72
75
|
specification_version: 3
|
73
76
|
summary: Read and write Csv files, easily
|
74
77
|
test_files:
|
78
|
+
- test/formatter_index_assignment_test.rb
|
79
|
+
- test/formatter_len_test.rb
|
80
|
+
- test/formatter_multi_instance_test.rb
|
75
81
|
- test/formatter_rule_test.rb
|
76
82
|
- test/formatter_test.rb
|
77
83
|
- test/gzip_reader_test.rb
|