anixe_csv 0.0.1 → 0.3.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/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
|