csvrecord 0.2.0 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: ea4f015ade2a8b105eb89aec99e4a9bd7f5be01c
4
- data.tar.gz: 2738c2e3655a29e3a626eb7aee228d9b7275a3bd
3
+ metadata.gz: f60b9d15d91c6d20b625bb343d895ad750f43a81
4
+ data.tar.gz: 5510e7921a509fe40906de7f533f185bf244e8bd
5
5
  SHA512:
6
- metadata.gz: '0290ce3db55dfa7e3e24f00db9aa4c918be94b04c408415844015d09fa8f0eabee4f8989ac7f9dfb7fc917dbd428727da25ee1d84200057b5bbe6c9add3e18ce'
7
- data.tar.gz: 6c47502227af693814a99f7d34bd9fede8afadc556d1797c1cf365437e7491312bd7d1037c23eb0923775884bb0ed5e55ac5a62642d940810db7fa9bdb3e4a5d
6
+ metadata.gz: 9853722319a53c73469238440eb2c249cd8c3829711acbd35efc60996316f8d8e763d5f61decdc4e3186baebf13536c46c72217fd92f08e6d675b7a6c088568b
7
+ data.tar.gz: bd2922bf8c44a458abe70b5dceee9b405904f878eacdaf34a1454a2313c43517329d31841c2bc4faca5c6d3492220d9c5c3091115171046c087a2889a4415339
data/Manifest.txt CHANGED
@@ -6,7 +6,12 @@ Rakefile
6
6
  lib/csvrecord.rb
7
7
  lib/csvrecord/base.rb
8
8
  lib/csvrecord/builder.rb
9
+ lib/csvrecord/reader.rb
9
10
  lib/csvrecord/version.rb
10
11
  test/data/beer.csv
12
+ test/data/beer11.csv
11
13
  test/helper.rb
12
- test/test_beer.rb
14
+ test/test_reader.rb
15
+ test/test_record.rb
16
+ test/test_record_auto.rb
17
+ test/test_version.rb
data/README.md CHANGED
@@ -74,11 +74,18 @@ pretty prints (pp):
74
74
  Or loop over the records. Example:
75
75
 
76
76
  ``` ruby
77
- Beer.read( data ).each do |rec|
77
+ Beer.read( 'beer.csv' ).each do |rec|
78
+ puts "#{rec.name} (#{rec.abv}%) by #{rec.brewery}, #{rec.city}"
79
+ end
80
+
81
+ # -or-
82
+
83
+ Beer.foreach( 'beer.csv' ) do |rec|
78
84
  puts "#{rec.name} (#{rec.abv}%) by #{rec.brewery}, #{rec.city}"
79
85
  end
80
86
  ```
81
87
 
88
+
82
89
  printing:
83
90
 
84
91
  ```
@@ -97,11 +104,11 @@ Or create new records from scratch. Example:
97
104
  beer = Beer.new( 'Andechser Klosterbrauerei',
98
105
  'Andechs',
99
106
  'Doppelbock Dunkel',
100
- '7.0%' )
107
+ '7%' )
101
108
 
102
109
  # -or-
103
110
 
104
- values = ['Andechser Klosterbrauerei', 'Andechs', 'Doppelbock Dunkel', '7.0%']
111
+ values = ['Andechser Klosterbrauerei', 'Andechs', 'Doppelbock Dunkel', '7%']
105
112
  beer = Beer.new( values )
106
113
 
107
114
  # -or-
@@ -109,14 +116,14 @@ beer = Beer.new( values )
109
116
  beer = Beer.new( brewery: 'Andechser Klosterbrauerei',
110
117
  city: 'Andechs',
111
118
  name: 'Doppelbock Dunkel',
112
- abv: '7.0%' )
119
+ abv: '7%' )
113
120
 
114
121
  # -or-
115
122
 
116
123
  hash = { brewery: 'Andechser Klosterbrauerei',
117
124
  city: 'Andechs',
118
125
  name: 'Doppelbock Dunkel',
119
- abv: '7.0%' }
126
+ abv: '7%' }
120
127
  beer = Beer.new( hash )
121
128
 
122
129
 
@@ -126,24 +133,24 @@ beer = Beer.new
126
133
  beer.update( brewery: 'Andechser Klosterbrauerei',
127
134
  city: 'Andechs',
128
135
  name: 'Doppelbock Dunkel' )
129
- beer.update( abv: 12.7 )
136
+ beer.update( abv: 7.0 )
130
137
 
131
138
  # -or-
132
139
 
133
140
  beer = Beer.new
134
- beer.parse( ['Andechser Klosterbrauerei', 'Andechs', 'Doppelbock Dunkel', '7.0%'] )
141
+ beer.parse( ['Andechser Klosterbrauerei', 'Andechs', 'Doppelbock Dunkel', '7%'] )
135
142
 
136
143
  # -or-
137
144
 
138
145
  beer = Beer.new
139
- beer.parse( 'Andechser Klosterbrauerei,Andechs,Doppelbock Dunkel,7.0%' )
146
+ beer.parse( 'Andechser Klosterbrauerei,Andechs,Doppelbock Dunkel,7%' )
140
147
 
141
148
  # -or-
142
149
 
143
150
  beer = Beer.new
144
151
  beer.brewery = 'Andechser Klosterbrauerei'
145
152
  beer.name = 'Doppelbock Dunkel'
146
- beer.abv = 12.7
153
+ beer.abv = 7.0
147
154
  ```
148
155
 
149
156
 
data/lib/csvrecord.rb CHANGED
@@ -10,6 +10,7 @@ require 'pp'
10
10
  require 'csvrecord/version' # let version always go first
11
11
  require 'csvrecord/base'
12
12
  require 'csvrecord/builder'
13
+ require 'csvrecord/reader'
13
14
 
14
15
 
15
16
 
@@ -100,6 +100,40 @@ module CsvRecord
100
100
  end
101
101
 
102
102
 
103
+ ###########################################
104
+ ## "magic" lazy auto-build schema from headers versions
105
+
106
+ def self.build_class( headers ) ## check: find a better name - why? why not?
107
+ ## (auto-)build record class from an array of headers
108
+ ## add fields (all types will be string for now)
109
+ clazz = Class.new(Base)
110
+ headers.each do |header|
111
+ ## downcase and remove all non-ascii chars etc.
112
+ ## todo/fix: remove all non-ascii chars!!!
113
+ ## todo: check if header starts with a number too!!
114
+ name = header.downcase.gsub( ' ', '_' )
115
+ name = name.to_sym ## symbol-ify
116
+ clazz.field( name )
117
+ end
118
+ clazz
119
+ end
120
+
121
+ def self.read( path, sep: Csv.config.sep )
122
+ headers = CsvReader.header( path, sep: sep )
123
+
124
+ clazz = build_class( headers )
125
+ clazz.read( path, sep: sep )
126
+ end
127
+
128
+ def self.foreach( path, sep: Csv.config.sep, &block )
129
+ headers = CsvReader.header( path, sep: sep )
130
+
131
+ clazz = build_class( headers )
132
+ clazz.foreach( path, sep: sep, &block )
133
+ end
134
+
135
+
136
+
103
137
 
104
138
  class Base
105
139
 
@@ -234,11 +268,21 @@ def to_csv ## use/rename/alias to to_row too - why? why not?
234
268
  end
235
269
 
236
270
 
271
+ def self.foreach( path, sep: Csv.config.sep, headers: true )
272
+ CsvReader.foreach( path, sep: sep, headers: headers ) do |row|
273
+ rec = new
274
+ values = CsvReader.unwrap( row )
275
+ rec.parse( values )
276
+
277
+ yield( rec ) ## check: use block.class( rec ) - why? why not?
278
+ end
279
+ end
280
+
237
281
 
238
- def self.parse( txt_or_rows ) ## note: returns an (lazy) enumarator
282
+ def self.parse( txt_or_rows, sep: Csv.config.sep, headers: true ) ## note: returns an (lazy) enumarator
239
283
  if txt_or_rows.is_a? String
240
284
  txt = txt_or_rows
241
- rows = CSV.parse( txt, headers: true )
285
+ rows = CsvReader.parse( txt, sep: sep, headers: headers )
242
286
  else
243
287
  ### todo/fix: use only self.create( array-like ) for array-like data - why? why not?
244
288
  rows = txt_or_rows ## assume array-like records that responds to :each
@@ -248,25 +292,19 @@ def self.parse( txt_or_rows ) ## note: returns an (lazy) enumarator
248
292
 
249
293
  Enumerator.new do |yielder|
250
294
  rows.each do |row|
251
- ## check - check for to_h - why? why not? supported/built-into by CSV::Row??
252
- ## if row.respond_to?( :to_h )
253
- ## else
254
- ## pp row.fields
255
- ## pp row.to_hash
256
- ## fix/todo!!!!!!!!!!!!!
257
- ## check for CSV::Row etc. - use row.to_hash ?
258
- rec = new
259
- rec.parse( row.fields )
260
- ## end
261
- yielder.yield( rec )
295
+ rec = new
296
+ values = CsvReader.unwrap( row )
297
+ rec.parse( values )
298
+
299
+ yielder.yield( rec )
262
300
  end
263
301
  end
264
302
  end
265
303
 
266
304
 
267
- def self.read( path ) ## not returns an enumarator
305
+ def self.read( path, sep: Csv.config.sep, headers: true ) ## not returns an enumarator
268
306
  txt = File.open( path, 'r:utf-8' ).read
269
- parse( txt )
307
+ parse( txt, sep: sep, headers: headers )
270
308
  end
271
309
 
272
310
 
@@ -0,0 +1,188 @@
1
+ # encoding: utf-8
2
+
3
+
4
+ module Csv ## check: rename to CsvSettings / CsvPref / CsvGlobals or similar - why? why not???
5
+
6
+ ## STD_CSV_ENGINE = CSV ## to avoid name confusion use longer name - why? why not? find a better name?
7
+ ## use __CSV__ or similar? or just ::CSV ??
8
+
9
+ class Configuration
10
+
11
+ puts "CSV::VERSION:"
12
+ puts CSV::VERSION
13
+
14
+ puts "builtin CSV::Converters:"
15
+ pp CSV::Converters
16
+
17
+ puts "CSV::DEFAULT_OPTIONS:"
18
+ pp CSV::DEFAULT_OPTIONS
19
+
20
+ ## register our own converters
21
+ ## check if strip gets called for nil values too?
22
+ CSV::Converters[:strip] = ->(field) { field.strip }
23
+
24
+
25
+ attr_accessor :sep ## col_sep (column separator)
26
+
27
+ def initialize
28
+ @sep = ','
29
+ ## note: do NOT add headers as global - should ALWAYS be explicit
30
+ ## headers (true/false) - changes resultset and requires different processing!!!
31
+
32
+ self ## return self for chaining
33
+ end
34
+
35
+ def blank?( line )
36
+ ## note: blank line does NOT include "blank" with spaces only!!
37
+ ## use BLANK_REGEX in skip_lines to clean-up/skip/remove/ignore
38
+ ## see skip_blanks in default_options
39
+ line.empty?
40
+ end
41
+
42
+ ## lines starting with # (note: only leading spaces allowed)
43
+ COMMENTS_REGEX = /^\s*#/
44
+ BLANK_REGEX = /^\s*$/ ## skip all whitespace lines - note: use "" or , for a blank record!!!
45
+ SKIP_REGEX = Regexp.union( COMMENTS_REGEX, BLANK_REGEX )
46
+
47
+ def skip?( line )
48
+ ## check if comment line - skip comments
49
+ ## see skip_lines in default_options
50
+ line =~ SKIP_REGEX
51
+ end
52
+
53
+ ## built-in (default) options
54
+ ## todo: find a better name?
55
+ def default_options
56
+ ## note:
57
+ ## do NOT include sep character and
58
+ ## do NOT include headers true/false here
59
+ ##
60
+ ## make default sep its own "global" default config
61
+ ## e.g. Csv.config.sep =
62
+
63
+ ## common options
64
+ ## skip comments starting with #
65
+ ## skip blank lines
66
+ ## strip leading and trailing spaces
67
+ ## NOTE/WARN: leading and trailing spaces NOT allowed/working with double quoted values!!!!
68
+ defaults = {
69
+ skip_blanks: true, ## note: skips lines with no whitespaces only!! (e.g. line with space is NOT blank!!)
70
+ skip_lines: SKIP_REGEX,
71
+ :converters => :strip
72
+ }
73
+ defaults
74
+ end
75
+ end # class Configuration
76
+
77
+
78
+ ## lets you use
79
+ ## Csv.configure do |config|
80
+ ## config.sep = ',' ## or "/t"
81
+ ## end
82
+
83
+ def self.configure
84
+ yield( config )
85
+ end
86
+
87
+ def self.config
88
+ @config ||= Configuration.new
89
+ end
90
+ end # module Csvv
91
+
92
+
93
+
94
+ ####
95
+ ## use our own wrapper
96
+
97
+ class CsvReader
98
+
99
+ ####################
100
+ # helper methods
101
+ def self.unwrap( row_or_array ) ## unwrap row - find a better name? why? why not?
102
+ ## return row values as array of strings
103
+ if row_or_array.is_a?( CSV::Row )
104
+ row = row_or_array
105
+ row.fields ## gets array of string of field values
106
+ else ## assume "classic" array of strings
107
+ array = row_or_array
108
+ end
109
+ end
110
+
111
+
112
+
113
+ def self.foreach( path, sep: Csv.config.sep, headers: true )
114
+ csv_options = Csv.config.default_options.merge(
115
+ headers: headers,
116
+ col_sep: sep,
117
+ external_encoding: 'utf-8' ## note: always (auto-)add utf-8 external encoding for now!!!
118
+ )
119
+
120
+ CSV.foreach( path, csv_options ) do |row|
121
+ yield( row ) ## check/todo: use block.call( row ) ## why? why not?
122
+ end
123
+ end
124
+
125
+
126
+ def self.read( path, sep: Csv.config.sep, headers: true )
127
+ ## note: use our own file.open
128
+ ## always use utf-8 for now
129
+ ## check/todo: add skip option bom too - why? why not?
130
+ txt = File.open( path, 'r:utf-8' )
131
+ parse( txt, sep: sep, headers: headers )
132
+ end
133
+
134
+ def self.parse( txt, sep: Csv.config.sep, headers: true )
135
+ csv_options = Csv.config.default_options.merge(
136
+ headers: headers,
137
+ col_sep: sep
138
+ )
139
+ ## pp csv_options
140
+ CSV.parse( txt, csv_options )
141
+ end
142
+
143
+ def self.parse_line( txt, sep: Csv.config.sep )
144
+ ## note: do NOT include headers option (otherwise single row gets skipped as first header row :-)
145
+ csv_options = Csv.config.default_options.merge(
146
+ headers: false, ## note: always turn off headers!!!!!!
147
+ col_sep: sep
148
+ )
149
+ ## pp csv_options
150
+ CSV.parse_line( txt, csv_options )
151
+ end
152
+
153
+
154
+
155
+ def self.header( path, sep: Csv.config.sep ) ## use header or headers - or use both (with alias)?
156
+ # read first lines (only)
157
+ # and parse with csv to get header from csv library itself
158
+ #
159
+ # check - if there's an easier or built-in way for the csv library
160
+
161
+ ## readlines until
162
+ ## - NOT a comments line or
163
+ ## - NOT a blank line
164
+
165
+ lines = ''
166
+ File.open( path, 'r:utf-8' ) do |f|
167
+
168
+ ## todo/fix: how to handle empty files or files without headers?!
169
+
170
+ ## todo/check if readline includes \n\r too??
171
+ ## yes! - line include \n e.g.
172
+ ## "Brewery,City,Name,Abv\n" or
173
+ ## "#######\n# try with some comments\n# and blank lines even before header\n\nBrewery,City,Name,Abv\n"
174
+ loop do
175
+ line = f.readline
176
+ lines << line
177
+ break unless Csv.config.skip?( line ) || Csv.config.blank?( line )
178
+ end
179
+ end
180
+
181
+ ## puts "lines:"
182
+ ## pp lines
183
+
184
+ ## note: do NOT use headers: true to get "plain" data array (no hash records)
185
+ ## hash record does NOT work for single line/row
186
+ parse_line( lines, sep: sep )
187
+ end # method self.header
188
+ end # class CsvReader
@@ -4,7 +4,7 @@
4
4
  module CsvRecord
5
5
 
6
6
  MAJOR = 0 ## todo: namespace inside version or something - why? why not??
7
- MINOR = 2
7
+ MINOR = 3
8
8
  PATCH = 0
9
9
  VERSION = [MAJOR,MINOR,PATCH].join('.')
10
10
 
@@ -0,0 +1,51 @@
1
+ #######
2
+ # try with some comments
3
+ # and blank lines even before header
4
+
5
+ Brewery,City,Name,Abv
6
+ Andechser Klosterbrauerei,Andechs,Doppelbock Dunkel,7%
7
+ Augustiner Bräu München,München,Edelstoff,5.6%
8
+ Bayerische Staatsbrauerei Weihenstephan,Freising,Hefe Weissbier,5.4%
9
+
10
+ Brauerei Spezial, Bamberg, Rauchbier Märzen, 5.1%
11
+
12
+ Hacker-Pschorr Bräu, München, Münchner Dunkel, 5.0%
13
+
14
+ ## some more comments here
15
+
16
+ Staatliches Hofbräuhaus München,München,Hofbräu Oktoberfestbier,6.3%
17
+
18
+ ## check for nil
19
+ "", ,,"",
20
+
21
+ ## check for blank line with spaces
22
+ ## yes, will get added as a record!! e.g. ["", nil, nil, nil]
23
+ ## use regex to skip blank lines with spaces!!!!
24
+
25
+
26
+ ## test double quotes and double quotes escaped
27
+ ## note: double quotes do NOT work with leading AND/OR trailing spaces
28
+ ## leads to:
29
+ ## CSV::MalformedCSVError - Missing or stray quote in line xxx
30
+ ##
31
+ ## note: for now double quote does not accept leading AND/OR trailing spaces!!!!
32
+ ##
33
+ ## todo/fix: check liberal_quote option starting in csv ruby 2.4 ???
34
+ ##
35
+ ## examples:
36
+ ## "value with comma, comma","some ""hello""","some ""hello""",
37
+ ## works - but does NOT work (note the leading and trailing spaces for double quotes):
38
+ ## "value with comma, comma" ,"some ""hello""", "some ""hello""",
39
+ ##
40
+ ## check for "multi-line":
41
+ ## "hello
42
+ ## and another line
43
+ ## and another",two,three,
44
+
45
+
46
+ "value with comma, comma","some ""hello""","some ""hello""",
47
+
48
+ ## check for "multi-line"
49
+ "hello
50
+ and another line
51
+ and another",two,three,
@@ -0,0 +1,119 @@
1
+ # encoding: utf-8
2
+
3
+ ###
4
+ # to run use
5
+ # ruby -I ./lib -I ./test test/test_reader.rb
6
+
7
+
8
+ require 'helper'
9
+
10
+ class TestReader < MiniTest::Test
11
+
12
+ def test_read
13
+ puts "== read: beer.csv:"
14
+ table = CsvReader.read( "#{CsvRecord.test_data_dir}/beer.csv" ) ## returns CSV::Table
15
+
16
+ pp table.class.name
17
+ pp table
18
+ pp table.to_a ## note: includes header (first row with column names)
19
+
20
+ table.each do |row| ## note: will skip (NOT include) header row!!
21
+ pp row
22
+ end
23
+ puts " #{table.size} rows" ## note: again will skip (NOT include) header row in count!!!
24
+ assert_equal 6, table.size
25
+ end
26
+
27
+ def test_read_header_false
28
+ puts "== read (headers: false): beer.csv:"
29
+ data = CsvReader.read( "#{CsvRecord.test_data_dir}/beer.csv", headers: false )
30
+
31
+ pp data.class.name
32
+ pp data
33
+
34
+ data.each do |row|
35
+ pp row
36
+ end
37
+ puts " #{data.size} rows"
38
+ assert_equal 7, data.size ## note: include header row in count
39
+ end
40
+
41
+
42
+ def test_read11
43
+ puts "== read: beer11.csv:"
44
+ table = CsvReader.read( "#{CsvRecord.test_data_dir}/beer11.csv" )
45
+ pp table
46
+ pp table.to_a ## note: includes header (first row with column names)
47
+
48
+ assert true
49
+ end
50
+
51
+
52
+ def test_parse_line
53
+ puts "== parse_line:"
54
+ row = CsvReader.parse_line( <<TXT )
55
+ Augustiner Bräu München, München, Edelstoff, 5.6%
56
+ Bayerische Staatsbrauerei Weihenstephan, Freising, Hefe Weissbier, 5.4%
57
+ TXT
58
+
59
+ pp row
60
+ assert_equal ['Augustiner Bräu München', 'München', 'Edelstoff', '5.6%'], row
61
+ end
62
+
63
+ def test_parse_line11
64
+ puts "== parse_line:"
65
+ row = CsvReader.parse_line( <<TXT )
66
+ #######
67
+ # try with some comments
68
+ # and blank lines even before header
69
+
70
+ Augustiner Bräu München, München, Edelstoff, 5.6%
71
+ Bayerische Staatsbrauerei Weihenstephan, Freising, Hefe Weissbier, 5.4%
72
+ TXT
73
+
74
+ pp row
75
+ assert_equal ['Augustiner Bräu München', 'München', 'Edelstoff', '5.6%'], row
76
+ end
77
+
78
+ def test_header
79
+ puts "== header: beer.csv:"
80
+ header = CsvReader.header( "#{CsvRecord.test_data_dir}/beer.csv" )
81
+ pp header
82
+ assert_equal ['Brewery','City','Name','Abv'], header
83
+ end
84
+
85
+ def test_header11
86
+ puts "== header: beer11.csv:"
87
+ header = CsvReader.header( "#{CsvRecord.test_data_dir}/beer11.csv" )
88
+ pp header
89
+ assert_equal ['Brewery','City','Name','Abv'], header
90
+ end
91
+
92
+
93
+ def test_foreach
94
+ puts "== foreach: beer.csv:"
95
+ CsvReader.foreach( "#{CsvRecord.test_data_dir}/beer.csv" ) do |row|
96
+ pp row
97
+ pp row.fields
98
+ end
99
+ assert true
100
+ end
101
+
102
+ def test_foreach11
103
+ puts "== foreach: beer11.csv:"
104
+ CsvReader.foreach( "#{CsvRecord.test_data_dir}/beer11.csv" ) do |row|
105
+ pp row
106
+ pp row.fields
107
+ end
108
+ assert true
109
+ end
110
+
111
+ def test_foreach_header_false
112
+ puts "== foreach (headers: false): beer11.csv:"
113
+ CsvReader.foreach( "#{CsvRecord.test_data_dir}/beer11.csv", headers: false ) do |row|
114
+ pp row ## note: is Array (no .fields available!!!!!)
115
+ end
116
+ assert true
117
+ end
118
+
119
+ end # class TestReader
@@ -2,21 +2,12 @@
2
2
 
3
3
  ###
4
4
  # to run use
5
- # ruby -I ./lib -I ./test test/test_beer.rb
5
+ # ruby -I ./lib -I ./test test/test_record.rb
6
6
 
7
7
 
8
8
  require 'helper'
9
9
 
10
- class TestBeer < MiniTest::Test
11
-
12
- def test_version
13
- pp CsvRecord::VERSION
14
- pp CsvRecord.banner
15
- pp CsvRecord.root
16
-
17
- assert true ## assume ok if we get here
18
- end
19
-
10
+ class TestRecord < MiniTest::Test
20
11
 
21
12
  def test_class_style1
22
13
  clazz1 = CsvRecord.define do
@@ -104,6 +95,35 @@ class TestBeer < MiniTest::Test
104
95
  assert true ## assume ok if we get here
105
96
  end
106
97
 
98
+
99
+ def test_foreach
100
+ puts "== foreach:"
101
+ Beer.foreach( "#{CsvRecord.test_data_dir}/beer.csv" ) do |rec|
102
+ puts "#{rec.name} (#{rec.abv}%) by #{rec.brewery}, #{rec.city}"
103
+ end
104
+
105
+ assert true ## assume ok if we get here
106
+ end
107
+
108
+
109
+ def test_parse_array_or_arrays
110
+ data=[
111
+ ['Brewery','City','Name','Abv'],
112
+ ['Andechser Klosterbrauerei','Andechs','Doppelbock Dunkel','7%'],
113
+ ['Augustiner Bräu München','München','Edelstoff','5.6%'],
114
+ ['Bayerische Staatsbrauerei Weihenstephan','Freising','Hefe Weissbier','5.4%'],
115
+ ['Brauerei Spezial','Bamberg','Rauchbier Märzen','5.1%'],
116
+ ['Hacker-Pschorr Bräu','München','Münchner Dunkel','5.0%'],
117
+ ['Staatliches Hofbräuhaus München','München','Hofbräu Oktoberfestbier','6.3%']]
118
+
119
+ beers = Beer.parse( data ).to_a
120
+ puts "#{beers.size} beers:"
121
+ pp beers
122
+
123
+ assert true ## assume ok if we get here
124
+ end
125
+
126
+
107
127
  def test_classic
108
128
  puts "== read( data ).to_a:"
109
129
  beers = BeerClassic.read( "#{CsvRecord.test_data_dir}/beer.csv" ).to_a
@@ -227,4 +247,4 @@ class TestBeer < MiniTest::Test
227
247
  assert_equal values[3].to_f, beer['Abv']
228
248
  end
229
249
 
230
- end # class TestBeer
250
+ end # class TestRecord
@@ -0,0 +1,34 @@
1
+ # encoding: utf-8
2
+
3
+ ###
4
+ # to run use
5
+ # ruby -I ./lib -I ./test test/test_record_auto.rb
6
+
7
+
8
+ require 'helper'
9
+
10
+ class TestRecordAuto < MiniTest::Test
11
+
12
+
13
+ def test_read
14
+ beers = CsvRecord.read( "#{CsvRecord.test_data_dir}/beer.csv" ).to_a
15
+ pp beers
16
+
17
+ assert_equal 6, beers.size
18
+ assert_equal 'Andechser Klosterbrauerei', beers[0].brewery
19
+ assert_equal 'Andechs', beers[0].city
20
+ assert_equal 'Doppelbock Dunkel', beers[0].name
21
+ assert_equal '7%', beers[0].abv
22
+ end
23
+
24
+
25
+ def test_foreach
26
+ CsvRecord.foreach( "#{CsvRecord.test_data_dir}/beer.csv" ) do |rec|
27
+ pp rec
28
+ puts "#{rec.name} (#{rec.abv}%) by #{rec.brewery}, #{rec.city}"
29
+ end
30
+
31
+ assert true
32
+ end
33
+
34
+ end # class TestRecordAuto
@@ -0,0 +1,20 @@
1
+ # encoding: utf-8
2
+
3
+ ###
4
+ # to run use
5
+ # ruby -I ./lib -I ./test test/test_version.rb
6
+
7
+
8
+ require 'helper'
9
+
10
+ class TestVersion < MiniTest::Test
11
+
12
+ def test_version
13
+ pp CsvRecord::VERSION
14
+ pp CsvRecord.banner
15
+ pp CsvRecord.root
16
+
17
+ assert true ## assume ok if we get here
18
+ end
19
+
20
+ end # class TestVersion
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: csvrecord
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Gerald Bauer
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-08-13 00:00:00.000000000 Z
11
+ date: 2018-08-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rdoc
@@ -57,10 +57,15 @@ files:
57
57
  - lib/csvrecord.rb
58
58
  - lib/csvrecord/base.rb
59
59
  - lib/csvrecord/builder.rb
60
+ - lib/csvrecord/reader.rb
60
61
  - lib/csvrecord/version.rb
61
62
  - test/data/beer.csv
63
+ - test/data/beer11.csv
62
64
  - test/helper.rb
63
- - test/test_beer.rb
65
+ - test/test_reader.rb
66
+ - test/test_record.rb
67
+ - test/test_record_auto.rb
68
+ - test/test_version.rb
64
69
  homepage: https://github.com/csv11/csvrecord
65
70
  licenses:
66
71
  - Public Domain