bamfcsv 0.3.1 → 0.3.2

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 CHANGED
@@ -23,5 +23,13 @@ irb(1.9.2): table.first["foo"]
23
23
  irb(1.9.2): table[1]["bar"]
24
24
  ==========> "4"
25
25
 
26
+ DOUBLE-AND/ALSO it supports custom field separators!!
27
+
28
+ irb(1.9.2): BAMFCSV.parse(<<EOF, separator: '|')
29
+ ?> foo|bar
30
+ ?> baz|quux
31
+ ?> EOF
32
+ ==========> [["foo", "bar"], ["baz", "quux"]]
33
+
26
34
 
27
35
  (*) Results may vary.
@@ -28,10 +28,11 @@ bool quotes_end_line(char* cur) {
28
28
  return *(cur-1) == '"' || (*(cur-1) == '\r' && *(cur-2) == '"');
29
29
  }
30
30
 
31
- VALUE bamfcsv_parse_string(VALUE self, VALUE string) {
31
+ VALUE bamfcsv_parse_string(VALUE self, VALUE string, VALUE rstr_sep) {
32
32
  char *buf = RSTRING_PTR(string);
33
33
  long bufsize = RSTRING_LEN(string);
34
34
  rb_encoding *enc = rb_enc_from_index(ENCODING_GET(string));
35
+ char separator = *RSTRING_PTR(rstr_sep);
35
36
 
36
37
  unsigned long num_rows = 1, cell_count = 1;
37
38
  int quote_count = 0, quotes_matched = 1;
@@ -62,7 +63,7 @@ VALUE bamfcsv_parse_string(VALUE self, VALUE string) {
62
63
 
63
64
  if (quotes_matched) {
64
65
 
65
- if (*cur == ',') {
66
+ if (*cur == separator) {
66
67
 
67
68
  if (quote_count && *(cur-1) != '"')
68
69
  rb_raise(BAMFCSV_MalformedCSVError_class, "Unclosed quoted field on line %lu, cell %lu.", num_rows, cell_count);
@@ -124,7 +125,7 @@ void Init_bamfcsv() {
124
125
 
125
126
  BAMFCSV_module = rb_define_module("BAMFCSV");
126
127
  VALUE bamfcsv_singleton_class = rb_singleton_class(BAMFCSV_module);
127
- rb_define_private_method(bamfcsv_singleton_class, "__parse_string", bamfcsv_parse_string, 1);
128
+ rb_define_private_method(bamfcsv_singleton_class, "__parse_string", bamfcsv_parse_string, 2);
128
129
 
129
130
  BAMFCSV_MalformedCSVError_class = rb_define_class_under(BAMFCSV_module, "MalformedCSVError", rb_eRuntimeError);
130
131
  }
@@ -14,7 +14,10 @@ module BAMFCSV
14
14
  # copy the pointer, not the contents. So we make a copy, parse
15
15
  # that, and throw away the copy.
16
16
  copy = "" + csv_str
17
- matrix = __parse_string(copy)
17
+ separator = opts.fetch(:separator, ',')
18
+ raise InvalidSeparator, "Separator must be exactly one character long" if separator.size != 1
19
+ raise InvalidSeparator, "Separator cannot be '\"'" if separator == '"'
20
+ matrix = __parse_string(copy, separator)
18
21
  if opts[:headers]
19
22
  Table.new(matrix)
20
23
  else
@@ -22,4 +25,5 @@ module BAMFCSV
22
25
  end
23
26
  end
24
27
 
28
+ class InvalidSeparator < StandardError; end
25
29
  end
@@ -1,3 +1,3 @@
1
1
  module BAMFCSV
2
- VERSION = "0.3.1"
2
+ VERSION = "0.3.2"
3
3
  end
@@ -0,0 +1,2 @@
1
+ foo|bar
2
+ pipe|delimited
@@ -38,6 +38,28 @@ describe BAMFCSV do
38
38
  BAMFCSV.read("spec/fixtures/terminated-with-cr.csv").should == [["a"],["b"]]
39
39
  end
40
40
 
41
+ describe "Alternate separators" do
42
+ it "raises BAMFCSV::InvalidSeparator if :separator is not exactly one character long" do
43
+ expect { BAMFCSV.read("spec/fixtures/pipe-delimited.csv", :separator => '') }.should raise_error(BAMFCSV::InvalidSeparator)
44
+ expect { BAMFCSV.read("spec/fixtures/pipe-delimited.csv", :separator => 'as') }.should raise_error(BAMFCSV::InvalidSeparator)
45
+ end
46
+
47
+ it "raises BAMFCSV::InvalidSeparator if :separator is a double-quote" do
48
+ expect { BAMFCSV.read("spec/fixtures/pipe-delimited.csv", :separator => '"') }.should raise_error(BAMFCSV::InvalidSeparator)
49
+ end
50
+
51
+ it "accepts a single character, non-quote :separator option" do
52
+ parsed = BAMFCSV.read("spec/fixtures/pipe-delimited.csv", :separator => '|')
53
+ parsed.should == [["foo", "bar"], ["pipe", "delimited"]]
54
+ end
55
+
56
+ it "works with tables too" do
57
+ table = BAMFCSV.read("spec/fixtures/pipe-delimited.csv", :headers => true, :separator => '|')
58
+ table.first["foo"].should == "pipe"
59
+ table.first["bar"].should == "delimited"
60
+ end
61
+ end
62
+
41
63
  it "raises Errno::ENOENT when the file does not exist" do
42
64
  expect do
43
65
  BAMFCSV.read("spec/fixtures/this-file-does-not-not-exist.csv")
@@ -250,5 +272,29 @@ CSV
250
272
  BAMFCSV.parse(csv, :headers => true).first.inspect.should == inspected
251
273
  end
252
274
  end
275
+ describe "Alternate separators" do
276
+ it "raises BAMFCSV::InvalidSeparator if :separator is not exactly one character long" do
277
+ expect { BAMFCSV.parse("1,2", :separator => '') }.should raise_error(BAMFCSV::InvalidSeparator)
278
+ expect { BAMFCSV.parse("1,2", :separator => 'as') }.should raise_error(BAMFCSV::InvalidSeparator)
279
+ end
280
+
281
+ it "raises BAMFCSV::InvalidSeparator if :separator is a double-quote" do
282
+ expect { BAMFCSV.parse("1,2", :separator => '"') }.should raise_error(BAMFCSV::InvalidSeparator)
283
+ end
284
+
285
+ it "accepts a single character, non-quote :separator option" do
286
+ semicolon = BAMFCSV.parse("foo;bar\n1;2", :separator => ';')
287
+ semicolon.should == [["foo", "bar"], ["1", "2"]]
288
+ pipe = BAMFCSV.parse("foo|bar\n1|2", :separator => '|')
289
+ pipe.should == [["foo", "bar"], ["1", "2"]]
290
+ end
291
+
292
+ it "works with tables too" do
293
+ table = BAMFCSV.parse("foo;bar\nbaz;qux", :headers => true, :separator => ';')
294
+ table.first["foo"].should == "baz"
295
+ table.first["bar"].should == "qux"
296
+ end
297
+ end
253
298
  end
299
+
254
300
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bamfcsv
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.1
4
+ version: 0.3.2
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -10,11 +10,11 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2011-08-10 00:00:00.000000000Z
13
+ date: 2011-08-27 00:00:00.000000000Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: rspec
17
- requirement: &2157181100 !ruby/object:Gem::Requirement
17
+ requirement: &2156352680 !ruby/object:Gem::Requirement
18
18
  none: false
19
19
  requirements:
20
20
  - - ~>
@@ -22,10 +22,10 @@ dependencies:
22
22
  version: 2.5.0
23
23
  type: :development
24
24
  prerelease: false
25
- version_requirements: *2157181100
25
+ version_requirements: *2156352680
26
26
  - !ruby/object:Gem::Dependency
27
27
  name: fuubar
28
- requirement: &2157180600 !ruby/object:Gem::Requirement
28
+ requirement: &2156352180 !ruby/object:Gem::Requirement
29
29
  none: false
30
30
  requirements:
31
31
  - - ~>
@@ -33,10 +33,10 @@ dependencies:
33
33
  version: 0.0.2
34
34
  type: :development
35
35
  prerelease: false
36
- version_requirements: *2157180600
36
+ version_requirements: *2156352180
37
37
  - !ruby/object:Gem::Dependency
38
38
  name: rake-compiler
39
- requirement: &2157180140 !ruby/object:Gem::Requirement
39
+ requirement: &2156351720 !ruby/object:Gem::Requirement
40
40
  none: false
41
41
  requirements:
42
42
  - - ~>
@@ -44,7 +44,7 @@ dependencies:
44
44
  version: 0.7.1
45
45
  type: :development
46
46
  prerelease: false
47
- version_requirements: *2157180140
47
+ version_requirements: *2156351720
48
48
  description: BAMFCSV parses csv like a BAMF. BAMF!!
49
49
  email:
50
50
  - jon@thinkrelevance.com
@@ -71,6 +71,7 @@ files:
71
71
  - spec/fixtures/empty.csv
72
72
  - spec/fixtures/escapes.csv
73
73
  - spec/fixtures/one-column.csv
74
+ - spec/fixtures/pipe-delimited.csv
74
75
  - spec/fixtures/terminated-with-cr.csv
75
76
  - spec/fixtures/test.csv
76
77
  - spec/lib/bamfcsv_spec.rb
@@ -108,6 +109,7 @@ test_files:
108
109
  - spec/fixtures/empty.csv
109
110
  - spec/fixtures/escapes.csv
110
111
  - spec/fixtures/one-column.csv
112
+ - spec/fixtures/pipe-delimited.csv
111
113
  - spec/fixtures/terminated-with-cr.csv
112
114
  - spec/fixtures/test.csv
113
115
  - spec/lib/bamfcsv_spec.rb