bamfcsv 0.3.1 → 0.3.2

Sign up to get free protection for your applications and to get access to all the features.
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