csv_lazy 0.0.8 → 0.0.9
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/Gemfile +4 -3
- data/Gemfile.lock +59 -14
- data/README.md +47 -0
- data/VERSION +1 -1
- data/csv_lazy.gemspec +15 -13
- data/lib/csv_lazy.rb +59 -59
- data/shippable.yml +11 -0
- data/spec/csv_lazy_spec.rb +78 -77
- data/spec/spec_helper.rb +4 -2
- metadata +26 -40
- data/README.rdoc +0 -19
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 80463bf9c65eb3d8711f447ee1755b953cb2cf01
|
4
|
+
data.tar.gz: b2a280caed3b92b8e284bb272fe55cf8648cb251
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 611b869e291df218be3919c8aa6a46e07d24b9f188f53b1ebdb2f0dfec367e5a7b992fa4454d51b4cdee03b85b6253a967ab848c056b71e59349f69204f6fcf9
|
7
|
+
data.tar.gz: 5e009d83697815f04a17761da901d5745937c17b6fba584ad48105e05a3009b05145f95b0d481adf00c1a9c59ce8bb974cc6bb9cf200a894de7715de7a276f06
|
data/Gemfile
CHANGED
@@ -3,13 +3,14 @@ source "http://rubygems.org"
|
|
3
3
|
# Example:
|
4
4
|
# gem "activesupport", ">= 2.3.5"
|
5
5
|
|
6
|
-
gem "string-strtr", :
|
6
|
+
gem "string-strtr", require: false
|
7
|
+
gem "codeclimate-test-reporter", group: :test, require: nil
|
7
8
|
|
8
9
|
# Add dependencies to develop your gem here.
|
9
10
|
# Include everything needed to run rake, tests, features, etc.
|
10
11
|
group :development do
|
11
|
-
gem "rspec", "~> 2.
|
12
|
+
gem "rspec", "~> 3.2.0"
|
12
13
|
gem "rdoc", "~> 3.12"
|
13
14
|
gem "bundler", ">= 1.0.0"
|
14
|
-
gem "jeweler", "~> 1.8.
|
15
|
+
gem "jeweler", "~> 1.8.8"
|
15
16
|
end
|
data/Gemfile.lock
CHANGED
@@ -1,33 +1,78 @@
|
|
1
1
|
GEM
|
2
2
|
remote: http://rubygems.org/
|
3
3
|
specs:
|
4
|
-
|
5
|
-
|
6
|
-
|
4
|
+
addressable (2.3.8)
|
5
|
+
builder (3.2.2)
|
6
|
+
codeclimate-test-reporter (0.4.7)
|
7
|
+
simplecov (>= 0.7.1, < 1.0.0)
|
8
|
+
diff-lcs (1.2.5)
|
9
|
+
docile (1.1.5)
|
10
|
+
faraday (0.8.9)
|
11
|
+
multipart-post (~> 1.2.0)
|
12
|
+
git (1.2.9.1)
|
13
|
+
github_api (0.10.1)
|
14
|
+
addressable
|
15
|
+
faraday (~> 0.8.1)
|
16
|
+
hashie (>= 1.2)
|
17
|
+
multi_json (~> 1.4)
|
18
|
+
nokogiri (~> 1.5.2)
|
19
|
+
oauth2
|
20
|
+
hashie (3.4.1)
|
21
|
+
highline (1.7.1)
|
22
|
+
jeweler (1.8.8)
|
23
|
+
builder
|
7
24
|
bundler (~> 1.0)
|
8
25
|
git (>= 1.2.5)
|
26
|
+
github_api (= 0.10.1)
|
27
|
+
highline (>= 1.6.15)
|
28
|
+
nokogiri (= 1.5.10)
|
9
29
|
rake
|
10
30
|
rdoc
|
11
31
|
json (1.7.7)
|
12
|
-
|
32
|
+
json (1.7.7-java)
|
33
|
+
jwt (1.4.1)
|
34
|
+
multi_json (1.11.0)
|
35
|
+
multi_xml (0.5.5)
|
36
|
+
multipart-post (1.2.0)
|
37
|
+
nokogiri (1.5.10)
|
38
|
+
oauth2 (1.0.0)
|
39
|
+
faraday (>= 0.8, < 0.10)
|
40
|
+
jwt (~> 1.0)
|
41
|
+
multi_json (~> 1.3)
|
42
|
+
multi_xml (~> 0.5)
|
43
|
+
rack (~> 1.2)
|
44
|
+
rack (1.6.0)
|
45
|
+
rake (10.4.2)
|
13
46
|
rdoc (3.12.2)
|
14
47
|
json (~> 1.4)
|
15
|
-
rspec (2.
|
16
|
-
rspec-core (~> 2.
|
17
|
-
rspec-expectations (~> 2.
|
18
|
-
rspec-mocks (~> 2.
|
19
|
-
rspec-core (2.
|
20
|
-
|
21
|
-
|
22
|
-
|
48
|
+
rspec (3.2.0)
|
49
|
+
rspec-core (~> 3.2.0)
|
50
|
+
rspec-expectations (~> 3.2.0)
|
51
|
+
rspec-mocks (~> 3.2.0)
|
52
|
+
rspec-core (3.2.3)
|
53
|
+
rspec-support (~> 3.2.0)
|
54
|
+
rspec-expectations (3.2.1)
|
55
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
56
|
+
rspec-support (~> 3.2.0)
|
57
|
+
rspec-mocks (3.2.1)
|
58
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
59
|
+
rspec-support (~> 3.2.0)
|
60
|
+
rspec-support (3.2.2)
|
61
|
+
simplecov (0.9.2)
|
62
|
+
docile (~> 1.1.0)
|
63
|
+
multi_json (~> 1.0)
|
64
|
+
simplecov-html (~> 0.9.0)
|
65
|
+
simplecov-html (0.9.0)
|
23
66
|
string-strtr (0.0.3)
|
24
67
|
|
25
68
|
PLATFORMS
|
69
|
+
java
|
26
70
|
ruby
|
27
71
|
|
28
72
|
DEPENDENCIES
|
29
73
|
bundler (>= 1.0.0)
|
30
|
-
|
74
|
+
codeclimate-test-reporter
|
75
|
+
jeweler (~> 1.8.8)
|
31
76
|
rdoc (~> 3.12)
|
32
|
-
rspec (~> 2.
|
77
|
+
rspec (~> 3.2.0)
|
33
78
|
string-strtr
|
data/README.md
ADDED
@@ -0,0 +1,47 @@
|
|
1
|
+
[![Build Status](https://api.shippable.com/projects/540e7b9a3479c5ea8f9ec209/badge?branchName=master)](https://app.shippable.com/projects/540e7b9a3479c5ea8f9ec209/builds/latest)
|
2
|
+
[![Code Climate](https://codeclimate.com/github/kaspernj/csv_lazy/badges/gpa.svg)](https://codeclimate.com/github/kaspernj/csv_lazy)
|
3
|
+
[![Test Coverage](https://codeclimate.com/github/kaspernj/csv_lazy/badges/coverage.svg)](https://codeclimate.com/github/kaspernj/csv_lazy)
|
4
|
+
|
5
|
+
# csv_lazy
|
6
|
+
|
7
|
+
## Install
|
8
|
+
|
9
|
+
Add to your Gemfile and bundle
|
10
|
+
|
11
|
+
```ruby
|
12
|
+
gem "csv_lazy"
|
13
|
+
```
|
14
|
+
|
15
|
+
## Usage
|
16
|
+
|
17
|
+
### Example
|
18
|
+
|
19
|
+
```ruby
|
20
|
+
CsvLazy.new(io: StringIO.new(csv_content)) do |row|
|
21
|
+
puts "Row: #{row}" #=> [1, 2, 3]
|
22
|
+
end
|
23
|
+
```
|
24
|
+
|
25
|
+
### With a lot of options
|
26
|
+
|
27
|
+
```ruby
|
28
|
+
CsvLazy.new(io: some_io, col_sep: ",", row_sep: "\r\n", headers: true, quote_char: "'", debug: false) do |row|
|
29
|
+
end
|
30
|
+
```
|
31
|
+
|
32
|
+
Description goes here.
|
33
|
+
|
34
|
+
## Contributing to csv_lazy
|
35
|
+
|
36
|
+
* Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet.
|
37
|
+
* Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it.
|
38
|
+
* Fork the project.
|
39
|
+
* Start a feature/bugfix branch.
|
40
|
+
* Commit and push until you are happy with your contribution.
|
41
|
+
* Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
|
42
|
+
* Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
|
43
|
+
|
44
|
+
## Copyright
|
45
|
+
|
46
|
+
Copyright (c) 2012 Kasper Johansen. See LICENSE.txt for
|
47
|
+
further details.
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.0.
|
1
|
+
0.0.9
|
data/csv_lazy.gemspec
CHANGED
@@ -2,19 +2,21 @@
|
|
2
2
|
# DO NOT EDIT THIS FILE DIRECTLY
|
3
3
|
# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
|
4
4
|
# -*- encoding: utf-8 -*-
|
5
|
+
# stub: csv_lazy 0.0.9 ruby lib
|
5
6
|
|
6
7
|
Gem::Specification.new do |s|
|
7
8
|
s.name = "csv_lazy"
|
8
|
-
s.version = "0.0.
|
9
|
+
s.version = "0.0.9"
|
9
10
|
|
10
11
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
12
|
+
s.require_paths = ["lib"]
|
11
13
|
s.authors = ["Kasper Johansen"]
|
12
|
-
s.date = "
|
14
|
+
s.date = "2015-04-22"
|
13
15
|
s.description = "A small CSV lib that skips whitespace-format-bugs and more."
|
14
16
|
s.email = "k@spernj.org"
|
15
17
|
s.extra_rdoc_files = [
|
16
18
|
"LICENSE.txt",
|
17
|
-
"README.
|
19
|
+
"README.md"
|
18
20
|
]
|
19
21
|
s.files = [
|
20
22
|
".document",
|
@@ -22,11 +24,12 @@ Gem::Specification.new do |s|
|
|
22
24
|
"Gemfile",
|
23
25
|
"Gemfile.lock",
|
24
26
|
"LICENSE.txt",
|
25
|
-
"README.
|
27
|
+
"README.md",
|
26
28
|
"Rakefile",
|
27
29
|
"VERSION",
|
28
30
|
"csv_lazy.gemspec",
|
29
31
|
"lib/csv_lazy.rb",
|
32
|
+
"shippable.yml",
|
30
33
|
"spec/csv_lazy_spec.rb",
|
31
34
|
"spec/spec_helper.rb",
|
32
35
|
"spec/test1.csv.gz",
|
@@ -34,32 +37,31 @@ Gem::Specification.new do |s|
|
|
34
37
|
]
|
35
38
|
s.homepage = "http://github.com/kaspernj/csv_lazy"
|
36
39
|
s.licenses = ["MIT"]
|
37
|
-
s.
|
38
|
-
s.rubygems_version = "1.8.25"
|
40
|
+
s.rubygems_version = "2.4.0"
|
39
41
|
s.summary = "A small CSV lib that skips whitespace-format-bugs and more."
|
40
42
|
|
41
43
|
if s.respond_to? :specification_version then
|
42
|
-
s.specification_version =
|
44
|
+
s.specification_version = 4
|
43
45
|
|
44
46
|
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
45
47
|
s.add_runtime_dependency(%q<string-strtr>, [">= 0"])
|
46
|
-
s.add_development_dependency(%q<rspec>, ["~> 2.
|
48
|
+
s.add_development_dependency(%q<rspec>, ["~> 3.2.0"])
|
47
49
|
s.add_development_dependency(%q<rdoc>, ["~> 3.12"])
|
48
50
|
s.add_development_dependency(%q<bundler>, [">= 1.0.0"])
|
49
|
-
s.add_development_dependency(%q<jeweler>, ["~> 1.8.
|
51
|
+
s.add_development_dependency(%q<jeweler>, ["~> 1.8.8"])
|
50
52
|
else
|
51
53
|
s.add_dependency(%q<string-strtr>, [">= 0"])
|
52
|
-
s.add_dependency(%q<rspec>, ["~> 2.
|
54
|
+
s.add_dependency(%q<rspec>, ["~> 3.2.0"])
|
53
55
|
s.add_dependency(%q<rdoc>, ["~> 3.12"])
|
54
56
|
s.add_dependency(%q<bundler>, [">= 1.0.0"])
|
55
|
-
s.add_dependency(%q<jeweler>, ["~> 1.8.
|
57
|
+
s.add_dependency(%q<jeweler>, ["~> 1.8.8"])
|
56
58
|
end
|
57
59
|
else
|
58
60
|
s.add_dependency(%q<string-strtr>, [">= 0"])
|
59
|
-
s.add_dependency(%q<rspec>, ["~> 2.
|
61
|
+
s.add_dependency(%q<rspec>, ["~> 3.2.0"])
|
60
62
|
s.add_dependency(%q<rdoc>, ["~> 3.12"])
|
61
63
|
s.add_dependency(%q<bundler>, [">= 1.0.0"])
|
62
|
-
s.add_dependency(%q<jeweler>, ["~> 1.8.
|
64
|
+
s.add_dependency(%q<jeweler>, ["~> 1.8.8"])
|
63
65
|
end
|
64
66
|
end
|
65
67
|
|
data/lib/csv_lazy.rb
CHANGED
@@ -4,24 +4,24 @@ require "rubygems"
|
|
4
4
|
require "string-strtr"
|
5
5
|
|
6
6
|
#A simple library for parsing CSV-files through IO's. Solves corrupt file formats automatically like when files contains several spaces after a column and more.
|
7
|
-
class
|
7
|
+
class CsvLazy
|
8
8
|
include Enumerable
|
9
|
-
|
9
|
+
|
10
10
|
#===Examples
|
11
11
|
# File.open("csvfile.csv", "r") do |fp|
|
12
|
-
#
|
12
|
+
# CsvLazy.new(io: fp, quote_char: '"', col_sep: ";", row_sep: "\n", encode: "utf-8") do |row_array|
|
13
13
|
# puts "Row: #{row_array}"
|
14
14
|
# end
|
15
15
|
# end
|
16
16
|
def initialize(args = {}, &blk)
|
17
17
|
@args = {
|
18
|
-
:
|
19
|
-
:
|
20
|
-
:
|
21
|
-
:
|
22
|
-
:
|
18
|
+
quote_char: '"',
|
19
|
+
row_sep: "\n",
|
20
|
+
col_sep: ";",
|
21
|
+
headers: false,
|
22
|
+
buffer_length: 4096
|
23
23
|
}.merge(args)
|
24
|
-
|
24
|
+
|
25
25
|
@io = @args[:io]
|
26
26
|
@eof = false
|
27
27
|
@buffer = ""
|
@@ -32,43 +32,41 @@ class Csv_lazy
|
|
32
32
|
@escape_char = "\\"
|
33
33
|
@escaped_quote = "#{@escape_char}#{@args[:quote_char]}"
|
34
34
|
@escaped_quote_double = "#{@escape_char}#{@escape_char}#{@args[:quote_char]}"
|
35
|
-
|
35
|
+
|
36
36
|
#@debug = true
|
37
|
-
|
37
|
+
|
38
38
|
accepted = [:encode, :quote_char, :row_sep, :col_sep, :io, :debug, :headers, :buffer_length]
|
39
39
|
@args.each do |key, val|
|
40
|
-
|
41
|
-
raise "Unknown argument: '#{key}'."
|
42
|
-
end
|
40
|
+
raise "Unknown argument: '#{key}'." unless accepted.include?(key)
|
43
41
|
end
|
44
|
-
|
42
|
+
|
45
43
|
raise "No ':quote_char' was given." if @args[:quote_char].to_s.strip.empty?
|
46
44
|
raise "No ':col_sep' was given." if @args[:col_sep].to_s.empty?
|
47
45
|
raise "No ':row_sep' was given." if @args[:row_sep].to_s.empty?
|
48
|
-
raise "No ':io' was given."
|
49
|
-
|
46
|
+
raise "No ':io' was given." unless @args[:io]
|
47
|
+
|
50
48
|
@regex_begin_quote_char = /\A\s*#{Regexp.escape(@args[:quote_char])}/
|
51
|
-
|
49
|
+
|
52
50
|
@regex_row_end = /\A\s*?#{Regexp.escape(@args[:row_sep])}/
|
53
51
|
@regex_colsep_next = /\A#{Regexp.escape(@args[:col_sep])}/
|
54
|
-
|
52
|
+
|
55
53
|
@regex_read_until_quote_char = /\A(.*?)#{Regexp.escape(@args[:quote_char])}/
|
56
54
|
@regex_read_until_col_sep = /\A(.*?)#{Regexp.escape(@args[:col_sep])}/
|
57
55
|
@regex_read_until_row_sep = /\A(.+?)#{Regexp.escape(@args[:row_sep])}/
|
58
56
|
@regex_read_until_end = /\A(.+?)\Z/
|
59
|
-
|
57
|
+
|
60
58
|
if @args[:headers]
|
61
59
|
headers = []
|
62
60
|
read_row.each do |key|
|
63
61
|
headers << key.to_sym
|
64
62
|
end
|
65
|
-
|
63
|
+
|
66
64
|
@headers = headers
|
67
65
|
end
|
68
|
-
|
66
|
+
|
69
67
|
self.each(&blk) if blk
|
70
68
|
end
|
71
|
-
|
69
|
+
|
72
70
|
#Yields each row as an array.
|
73
71
|
def each
|
74
72
|
if block_given?
|
@@ -87,20 +85,20 @@ class Csv_lazy
|
|
87
85
|
end
|
88
86
|
end
|
89
87
|
end
|
90
|
-
|
88
|
+
|
91
89
|
#Returns the next row.
|
92
90
|
def read_row
|
93
91
|
@row = []
|
94
|
-
while !@eof
|
95
|
-
break
|
92
|
+
while !@eof || !@buffer.empty?
|
93
|
+
break unless read_next_col
|
96
94
|
end
|
97
|
-
|
95
|
+
|
98
96
|
row = @row
|
99
97
|
@row = nil
|
100
|
-
|
98
|
+
|
101
99
|
puts "csv_lazy: Row: #{row}\n\n" if @debug
|
102
|
-
|
103
|
-
if row.empty?
|
100
|
+
|
101
|
+
if row.empty? && @eof
|
104
102
|
return false
|
105
103
|
else
|
106
104
|
if @headers
|
@@ -108,34 +106,36 @@ class Csv_lazy
|
|
108
106
|
row.length.times do |count|
|
109
107
|
ret[@headers[count]] = row[count]
|
110
108
|
end
|
111
|
-
|
109
|
+
|
112
110
|
return ret
|
113
111
|
else
|
114
112
|
return row
|
115
113
|
end
|
116
114
|
end
|
117
115
|
end
|
118
|
-
|
119
|
-
|
120
|
-
|
116
|
+
|
117
|
+
private
|
118
|
+
|
121
119
|
#Reads more content into the buffer.
|
122
120
|
def read_buffer
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
121
|
+
while @buffer.length < @buffer_length && !@eof
|
122
|
+
read = @io.gets
|
123
|
+
|
124
|
+
if read == nil
|
125
|
+
@eof = true
|
126
|
+
else
|
127
|
+
read = read.encode(@encode) if @encode
|
128
|
+
@buffer << read
|
129
|
+
end
|
130
130
|
end
|
131
131
|
end
|
132
|
-
|
132
|
+
|
133
133
|
#Runs a regex against the buffer. If matched it also removes it from the buffer.
|
134
134
|
def read_remove_regex(regex)
|
135
135
|
if match = @buffer.match(regex)
|
136
136
|
oldbuffer = @buffer
|
137
137
|
@buffer = @buffer.gsub(regex, "")
|
138
|
-
|
138
|
+
|
139
139
|
if @debug
|
140
140
|
print "csv_lazy: Regex: #{regex.to_s}\n"
|
141
141
|
print "csv_lazy: Match: #{match.to_a}\n"
|
@@ -143,14 +143,14 @@ class Csv_lazy
|
|
143
143
|
print "csv_lazy: Buffer after: #{@buffer}\n"
|
144
144
|
print "\n"
|
145
145
|
end
|
146
|
-
|
146
|
+
|
147
147
|
raise "Buffer was the same before regex?" if oldbuffer == @buffer
|
148
148
|
return match
|
149
149
|
end
|
150
|
-
|
150
|
+
|
151
151
|
return false
|
152
152
|
end
|
153
|
-
|
153
|
+
|
154
154
|
def unescape(str)
|
155
155
|
return str.strtr(
|
156
156
|
"\\\\" => "\\",
|
@@ -160,18 +160,18 @@ class Csv_lazy
|
|
160
160
|
"\\\"" => "\""
|
161
161
|
)
|
162
162
|
end
|
163
|
-
|
163
|
+
|
164
164
|
#Adds the next column to the row. Returns true if more columns should be read or false if this was the end of the row.
|
165
165
|
def read_next_col
|
166
166
|
read_buffer if @buffer.length < @buffer_length
|
167
|
-
return false if @buffer.empty?
|
168
|
-
|
169
|
-
if @buffer.empty?
|
167
|
+
return false if @buffer.empty? && @eof
|
168
|
+
|
169
|
+
if @buffer.empty? || read_remove_regex(@regex_row_end)
|
170
170
|
return false
|
171
171
|
elsif match = read_remove_regex(@regex_begin_quote_char)
|
172
172
|
read = ""
|
173
173
|
col_content = ""
|
174
|
-
|
174
|
+
|
175
175
|
loop do
|
176
176
|
match_read = read_remove_regex(@regex_read_until_quote_char)
|
177
177
|
if !match_read
|
@@ -187,8 +187,8 @@ class Csv_lazy
|
|
187
187
|
escaped_quote_char = all[-@escaped_quote.length, @escaped_quote.length]
|
188
188
|
double_escaped_quote_char = all[-@escaped_quote_double.length, @escaped_quote_double.length]
|
189
189
|
all_without_quote = match_read[1]
|
190
|
-
|
191
|
-
if escaped_quote_char == @escaped_quote
|
190
|
+
|
191
|
+
if escaped_quote_char == @escaped_quote && double_escaped_quote_char != @escaped_quote_double
|
192
192
|
#continue reading - the quote char is escaped.
|
193
193
|
col_content << all
|
194
194
|
else
|
@@ -198,12 +198,12 @@ class Csv_lazy
|
|
198
198
|
end
|
199
199
|
end
|
200
200
|
end
|
201
|
-
|
201
|
+
|
202
202
|
read_buffer if @buffer.length < 4096
|
203
|
-
|
203
|
+
|
204
204
|
if read_remove_regex(@regex_colsep_next)
|
205
205
|
return true
|
206
|
-
elsif @eof
|
206
|
+
elsif @eof && @buffer.empty?
|
207
207
|
puts "csv_lazy: End-of-file and empty buffer." if @debug
|
208
208
|
return false
|
209
209
|
elsif read_remove_regex(@regex_row_end)
|
@@ -225,7 +225,7 @@ class Csv_lazy
|
|
225
225
|
add_col(match[1])
|
226
226
|
return false
|
227
227
|
end
|
228
|
-
|
228
|
+
|
229
229
|
#The end-of-file hasnt been reached. Add more data to buffer and try again.
|
230
230
|
@buffer << match[0]
|
231
231
|
read_buffer
|
@@ -237,9 +237,9 @@ class Csv_lazy
|
|
237
237
|
puts "csv_lazy: Retry! Probably we ran out of buffer..." if @debug
|
238
238
|
retry
|
239
239
|
end
|
240
|
-
|
240
|
+
|
241
241
|
#Adds a new column to the current row.
|
242
242
|
def add_col(str)
|
243
243
|
@row << str
|
244
244
|
end
|
245
|
-
end
|
245
|
+
end
|
data/shippable.yml
ADDED
data/spec/csv_lazy_spec.rb
CHANGED
@@ -3,145 +3,146 @@ require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
|
3
3
|
describe "CsvLazy" do
|
4
4
|
it "should be able to read CSV" do
|
5
5
|
cont = "1;2;3;4;5\n6;7;8;9;10"
|
6
|
-
|
6
|
+
|
7
7
|
count = 0
|
8
|
-
|
9
|
-
|
10
|
-
|
8
|
+
CsvLazy.new(io: StringIO.new(cont)) do |csv|
|
9
|
+
expect(csv.length).to eq 5
|
10
|
+
|
11
11
|
csv.each do |csv_ele|
|
12
|
-
|
12
|
+
expect(csv_ele.to_s).to match /^(\d+)$/
|
13
13
|
end
|
14
|
-
|
14
|
+
|
15
15
|
count += 1
|
16
16
|
end
|
17
|
-
|
18
|
-
|
17
|
+
|
18
|
+
expect(count).to eq 2
|
19
19
|
end
|
20
|
-
|
20
|
+
|
21
21
|
it "should be able to read mixed CSV" do
|
22
22
|
cont = "1;\"2\";3;\"4\";5\n6;7;8;9;10"
|
23
|
-
|
23
|
+
|
24
24
|
count = 0
|
25
|
-
|
26
|
-
|
27
|
-
|
25
|
+
CsvLazy.new(io: StringIO.new(cont)) do |csv|
|
26
|
+
expect(csv.length).to eq 5
|
27
|
+
|
28
28
|
csv.each do |csv_ele|
|
29
|
-
|
29
|
+
expect(csv_ele.to_s).to match /^(\d+)$/
|
30
30
|
end
|
31
|
-
|
31
|
+
|
32
32
|
count += 1
|
33
33
|
end
|
34
|
-
|
35
|
-
|
34
|
+
|
35
|
+
expect(count).to eq 2
|
36
36
|
end
|
37
|
-
|
37
|
+
|
38
38
|
it "should be able to handle ending whitespaces" do
|
39
39
|
cont = "1;2;3;4;\"5\" \n6;7;8;9;\"10\""
|
40
|
-
|
40
|
+
|
41
41
|
count = 0
|
42
|
-
|
43
|
-
|
44
|
-
|
42
|
+
CsvLazy.new(io: StringIO.new(cont)) do |csv|
|
43
|
+
expect(csv.length).to eq 5
|
44
|
+
|
45
45
|
csv.each do |csv_ele|
|
46
|
-
|
46
|
+
expect(csv_ele.to_s).to match /^(\d+)$/
|
47
47
|
end
|
48
|
-
|
48
|
+
|
49
49
|
count += 1
|
50
50
|
end
|
51
|
-
|
52
|
-
|
51
|
+
|
52
|
+
expect(count).to eq 2
|
53
53
|
end
|
54
|
-
|
55
|
-
it "
|
54
|
+
|
55
|
+
it "reads sample 1" do
|
56
56
|
require "zlib"
|
57
|
-
|
57
|
+
|
58
58
|
count = 0
|
59
59
|
Zlib::GzipReader.open("#{File.dirname(__FILE__)}/test1.csv.gz") do |gz|
|
60
|
-
|
61
|
-
|
60
|
+
CsvLazy.new(io: gz, col_sep: ",", row_sep: "\r\n") do |row|
|
61
|
+
expect(row.length).to eq 32
|
62
62
|
raise "Expected C-format or 'contract_id' column as the first but it wasnt: #{row[0]}" if !row[0].to_s.match(/^C(\d+)$/) and row[0] != "contract_id"
|
63
|
+
expect(row[0].to_s).to match /^C(\d+)$/ if row[0] != "contract_id"
|
63
64
|
count += 1
|
64
65
|
end
|
65
66
|
end
|
66
|
-
|
67
|
-
|
67
|
+
|
68
|
+
expect(count).to eq 23
|
68
69
|
end
|
69
|
-
|
70
|
-
it "
|
70
|
+
|
71
|
+
it "is able to use a whitespace as col-sep" do
|
71
72
|
cont = "1\t2\t\"3\"\t4\n"
|
72
|
-
|
73
|
+
|
73
74
|
expect = 0
|
74
75
|
lines_found = 0
|
75
|
-
|
76
|
+
CsvLazy.new(col_sep: "\t", io: StringIO.new(cont)) do |csv|
|
76
77
|
lines_found += 1
|
77
|
-
|
78
|
+
|
78
79
|
csv.each do |key|
|
79
80
|
expect += 1
|
80
|
-
key.
|
81
|
+
expect(key).to eq expect.to_s
|
81
82
|
end
|
82
83
|
end
|
83
|
-
|
84
|
-
lines_found.
|
84
|
+
|
85
|
+
expect(lines_found).to eq 1
|
85
86
|
end
|
86
|
-
|
87
|
-
it "
|
87
|
+
|
88
|
+
it "is able to use headers and return hashes instead" do
|
88
89
|
cont = "\"name\",age\r\n"
|
89
90
|
cont << "\"Kasper Johansen\",27\r\n"
|
90
91
|
cont << "\"Christina Stoeckel\",\"25\"\r\n"
|
91
|
-
|
92
|
+
|
92
93
|
line = 0
|
93
|
-
|
94
|
-
csv.class.
|
94
|
+
CsvLazy.new(col_sep: ",", io: StringIO.new(cont), headers: true, row_sep: "\r\n") do |csv|
|
95
|
+
expect(csv.class).to eq Hash
|
95
96
|
line += 1
|
96
|
-
csv.keys.length.
|
97
|
-
csv.length.
|
98
|
-
|
97
|
+
expect(csv.keys.length).to eq 2
|
98
|
+
expect(csv.length).to eq 2
|
99
|
+
|
99
100
|
if line == 1
|
100
|
-
csv[:name].
|
101
|
-
csv[:age].
|
101
|
+
expect(csv[:name]).to eq "Kasper Johansen"
|
102
|
+
expect(csv[:age]).to eq "27"
|
102
103
|
elsif line == 2
|
103
|
-
csv[:name].
|
104
|
-
csv[:age].
|
104
|
+
expect(csv[:name]).to eq "Christina Stoeckel"
|
105
|
+
expect(csv[:age]).to eq "25"
|
105
106
|
else
|
106
107
|
raise "Wrong line: #{line}"
|
107
108
|
end
|
108
109
|
end
|
109
|
-
|
110
|
-
line.
|
110
|
+
|
111
|
+
expect(line).to eq 2
|
111
112
|
end
|
112
|
-
|
113
|
+
|
113
114
|
it "should be able to encode incoming strings from weird files without crashing" do
|
114
|
-
File.open("#{File.dirname(__FILE__)}/test2.csv", "rb", :
|
115
|
+
File.open("#{File.dirname(__FILE__)}/test2.csv", "rb", encoding: "UTF-16LE") do |fp|
|
115
116
|
#Remove invalid UTF content.
|
116
117
|
fp.read(2)
|
117
|
-
|
118
|
-
|
119
|
-
csv.keys[0].
|
120
|
-
csv.keys[1].
|
121
|
-
csv.keys[2].
|
122
|
-
csv.keys.length.
|
118
|
+
|
119
|
+
CsvLazy.new(col_sep: ",", io: fp, headers: true, row_sep: "\r\n", quote_char: '"', encode: "US-ASCII", debug: false) do |csv|
|
120
|
+
expect(csv.keys[0]).to eq :legacy_user_id
|
121
|
+
expect(csv.keys[1]).to eq :savings_percentage
|
122
|
+
expect(csv.keys[2]).to eq :active
|
123
|
+
expect(csv.keys.length).to eq 3
|
123
124
|
end
|
124
125
|
end
|
125
126
|
end
|
126
|
-
|
127
|
+
|
127
128
|
it "should do proper escaping" do
|
128
129
|
cont = "\"Test1\";\"Test2 \\\"Wee\\\"\"\r\n"
|
129
130
|
cont << "\"Test3\";\"Test4 \\\"Wee\\\"\";\"Test5 \\\"Wee\\\"\"\r\n"
|
130
|
-
|
131
|
-
csv =
|
132
|
-
|
131
|
+
|
132
|
+
csv = CsvLazy.new(col_sep: ";", io: StringIO.new(cont), row_sep: "\r\n")
|
133
|
+
|
133
134
|
row = csv.read_row
|
134
|
-
row[0].
|
135
|
-
row[1].
|
136
|
-
row.length.
|
137
|
-
|
135
|
+
expect(row[0]).to eq "Test1"
|
136
|
+
expect(row[1]).to eq "Test2 \"Wee\""
|
137
|
+
expect(row.length).to eq 2
|
138
|
+
|
138
139
|
row = csv.read_row
|
139
|
-
row[0].
|
140
|
-
row[1].
|
141
|
-
row[2].
|
142
|
-
row.length.
|
143
|
-
|
140
|
+
expect(row[0]).to eq "Test3"
|
141
|
+
expect(row[1]).to eq "Test4 \"Wee\""
|
142
|
+
expect(row[2]).to eq "Test5 \"Wee\""
|
143
|
+
expect(row.length).to eq 3
|
144
|
+
|
144
145
|
row = csv.read_row
|
145
|
-
row.
|
146
|
+
expect(row).to eq false
|
146
147
|
end
|
147
148
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -1,3 +1,6 @@
|
|
1
|
+
require "codeclimate-test-reporter"
|
2
|
+
CodeClimate::TestReporter.start
|
3
|
+
|
1
4
|
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
2
5
|
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
3
6
|
require 'rspec'
|
@@ -5,8 +8,7 @@ require 'csv_lazy'
|
|
5
8
|
|
6
9
|
# Requires supporting files with custom matchers and macros, etc,
|
7
10
|
# in ./support/ and its subdirectories.
|
8
|
-
Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f}
|
11
|
+
Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each { |f| require f }
|
9
12
|
|
10
13
|
RSpec.configure do |config|
|
11
|
-
|
12
14
|
end
|
metadata
CHANGED
@@ -1,114 +1,104 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: csv_lazy
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
5
|
-
prerelease:
|
4
|
+
version: 0.0.9
|
6
5
|
platform: ruby
|
7
6
|
authors:
|
8
7
|
- Kasper Johansen
|
9
8
|
autorequire:
|
10
9
|
bindir: bin
|
11
10
|
cert_chain: []
|
12
|
-
date:
|
11
|
+
date: 2015-04-22 00:00:00.000000000 Z
|
13
12
|
dependencies:
|
14
13
|
- !ruby/object:Gem::Dependency
|
15
14
|
name: string-strtr
|
16
15
|
requirement: !ruby/object:Gem::Requirement
|
17
|
-
none: false
|
18
16
|
requirements:
|
19
|
-
- -
|
17
|
+
- - ">="
|
20
18
|
- !ruby/object:Gem::Version
|
21
19
|
version: '0'
|
22
20
|
type: :runtime
|
23
21
|
prerelease: false
|
24
22
|
version_requirements: !ruby/object:Gem::Requirement
|
25
|
-
none: false
|
26
23
|
requirements:
|
27
|
-
- -
|
24
|
+
- - ">="
|
28
25
|
- !ruby/object:Gem::Version
|
29
26
|
version: '0'
|
30
27
|
- !ruby/object:Gem::Dependency
|
31
28
|
name: rspec
|
32
29
|
requirement: !ruby/object:Gem::Requirement
|
33
|
-
none: false
|
34
30
|
requirements:
|
35
|
-
- - ~>
|
31
|
+
- - "~>"
|
36
32
|
- !ruby/object:Gem::Version
|
37
|
-
version: 2.
|
33
|
+
version: 3.2.0
|
38
34
|
type: :development
|
39
35
|
prerelease: false
|
40
36
|
version_requirements: !ruby/object:Gem::Requirement
|
41
|
-
none: false
|
42
37
|
requirements:
|
43
|
-
- - ~>
|
38
|
+
- - "~>"
|
44
39
|
- !ruby/object:Gem::Version
|
45
|
-
version: 2.
|
40
|
+
version: 3.2.0
|
46
41
|
- !ruby/object:Gem::Dependency
|
47
42
|
name: rdoc
|
48
43
|
requirement: !ruby/object:Gem::Requirement
|
49
|
-
none: false
|
50
44
|
requirements:
|
51
|
-
- - ~>
|
45
|
+
- - "~>"
|
52
46
|
- !ruby/object:Gem::Version
|
53
47
|
version: '3.12'
|
54
48
|
type: :development
|
55
49
|
prerelease: false
|
56
50
|
version_requirements: !ruby/object:Gem::Requirement
|
57
|
-
none: false
|
58
51
|
requirements:
|
59
|
-
- - ~>
|
52
|
+
- - "~>"
|
60
53
|
- !ruby/object:Gem::Version
|
61
54
|
version: '3.12'
|
62
55
|
- !ruby/object:Gem::Dependency
|
63
56
|
name: bundler
|
64
57
|
requirement: !ruby/object:Gem::Requirement
|
65
|
-
none: false
|
66
58
|
requirements:
|
67
|
-
- -
|
59
|
+
- - ">="
|
68
60
|
- !ruby/object:Gem::Version
|
69
61
|
version: 1.0.0
|
70
62
|
type: :development
|
71
63
|
prerelease: false
|
72
64
|
version_requirements: !ruby/object:Gem::Requirement
|
73
|
-
none: false
|
74
65
|
requirements:
|
75
|
-
- -
|
66
|
+
- - ">="
|
76
67
|
- !ruby/object:Gem::Version
|
77
68
|
version: 1.0.0
|
78
69
|
- !ruby/object:Gem::Dependency
|
79
70
|
name: jeweler
|
80
71
|
requirement: !ruby/object:Gem::Requirement
|
81
|
-
none: false
|
82
72
|
requirements:
|
83
|
-
- - ~>
|
73
|
+
- - "~>"
|
84
74
|
- !ruby/object:Gem::Version
|
85
|
-
version: 1.8.
|
75
|
+
version: 1.8.8
|
86
76
|
type: :development
|
87
77
|
prerelease: false
|
88
78
|
version_requirements: !ruby/object:Gem::Requirement
|
89
|
-
none: false
|
90
79
|
requirements:
|
91
|
-
- - ~>
|
80
|
+
- - "~>"
|
92
81
|
- !ruby/object:Gem::Version
|
93
|
-
version: 1.8.
|
82
|
+
version: 1.8.8
|
94
83
|
description: A small CSV lib that skips whitespace-format-bugs and more.
|
95
84
|
email: k@spernj.org
|
96
85
|
executables: []
|
97
86
|
extensions: []
|
98
87
|
extra_rdoc_files:
|
99
88
|
- LICENSE.txt
|
100
|
-
- README.
|
89
|
+
- README.md
|
101
90
|
files:
|
102
|
-
- .document
|
103
|
-
- .rspec
|
91
|
+
- ".document"
|
92
|
+
- ".rspec"
|
104
93
|
- Gemfile
|
105
94
|
- Gemfile.lock
|
106
95
|
- LICENSE.txt
|
107
|
-
- README.
|
96
|
+
- README.md
|
108
97
|
- Rakefile
|
109
98
|
- VERSION
|
110
99
|
- csv_lazy.gemspec
|
111
100
|
- lib/csv_lazy.rb
|
101
|
+
- shippable.yml
|
112
102
|
- spec/csv_lazy_spec.rb
|
113
103
|
- spec/spec_helper.rb
|
114
104
|
- spec/test1.csv.gz
|
@@ -116,29 +106,25 @@ files:
|
|
116
106
|
homepage: http://github.com/kaspernj/csv_lazy
|
117
107
|
licenses:
|
118
108
|
- MIT
|
109
|
+
metadata: {}
|
119
110
|
post_install_message:
|
120
111
|
rdoc_options: []
|
121
112
|
require_paths:
|
122
113
|
- lib
|
123
114
|
required_ruby_version: !ruby/object:Gem::Requirement
|
124
|
-
none: false
|
125
115
|
requirements:
|
126
|
-
- -
|
116
|
+
- - ">="
|
127
117
|
- !ruby/object:Gem::Version
|
128
118
|
version: '0'
|
129
|
-
segments:
|
130
|
-
- 0
|
131
|
-
hash: 1526481408762468229
|
132
119
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
133
|
-
none: false
|
134
120
|
requirements:
|
135
|
-
- -
|
121
|
+
- - ">="
|
136
122
|
- !ruby/object:Gem::Version
|
137
123
|
version: '0'
|
138
124
|
requirements: []
|
139
125
|
rubyforge_project:
|
140
|
-
rubygems_version:
|
126
|
+
rubygems_version: 2.4.0
|
141
127
|
signing_key:
|
142
|
-
specification_version:
|
128
|
+
specification_version: 4
|
143
129
|
summary: A small CSV lib that skips whitespace-format-bugs and more.
|
144
130
|
test_files: []
|
data/README.rdoc
DELETED
@@ -1,19 +0,0 @@
|
|
1
|
-
= csv_lazy
|
2
|
-
|
3
|
-
Description goes here.
|
4
|
-
|
5
|
-
== Contributing to csv_lazy
|
6
|
-
|
7
|
-
* Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet.
|
8
|
-
* Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it.
|
9
|
-
* Fork the project.
|
10
|
-
* Start a feature/bugfix branch.
|
11
|
-
* Commit and push until you are happy with your contribution.
|
12
|
-
* Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
|
13
|
-
* Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
|
14
|
-
|
15
|
-
== Copyright
|
16
|
-
|
17
|
-
Copyright (c) 2012 Kasper Johansen. See LICENSE.txt for
|
18
|
-
further details.
|
19
|
-
|