pikelet 1.1.2 → 2.0.0.beta.1

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: 92134160fa79ab2d8985325efe9593aab5380451
4
- data.tar.gz: 48510ce920f6fd195814d84688584b0d5c079da2
3
+ metadata.gz: 580f25b1ccc1b345208d99f759cbca4d42e86933
4
+ data.tar.gz: 6e333e33e68c71825143a2b393c0376f20f35c5f
5
5
  SHA512:
6
- metadata.gz: ebfab61d3e579d5316e86c2495eba1ad7d57795c3fbed235c4f969ae9dc5892ee26f24622809a34c3e75f1a292dd5affb53365cf4e5e118f9fa756640c081e6d
7
- data.tar.gz: fa71ad390ba4ece29732b2917b7f0de1ae4b4e6121755b7390241aa9859753a17a696397296c83a28ab007a32064a43fda10c2b14b17b8b9e32d38f012e40f26
6
+ metadata.gz: cd176128b19db2521917463563b00e5e6ca4caefd8086be747ae24b6ee36f80273690e33fcbe36879cfc9e9afd327dd4e65415d35554cf420fa234b7f9cd8166
7
+ data.tar.gz: 6ad11890c1fb69fc6c3641faeba9183b71a13153a350466df873ba37a12abbd27c46866a651198d0d41e28061c47d111a9e1b4035c90619ba526eaf9dd1a3ff9
data/README.md CHANGED
@@ -4,6 +4,16 @@
4
4
  [![Build status][build-badge]][build]
5
5
  [![Coverage Status][coverage-badge]][coverage]
6
6
 
7
+ ## Beta notes
8
+
9
+ The next release of Pikelet will be capable of formatting flat-file databases
10
+ for output. As part of this I will be dropping CSV support as it is
11
+ constraining my options and, as far as I know, nobody is using it. For the
12
+ time being I want to let it evolve as a pure flat-file database parser. In a
13
+ future release I may restore CSV support, but I make no promises.
14
+
15
+ ## Introduction
16
+
7
17
  A [pikelet][pikelet-recipe] is a small, delicious pancake popular in Australia
8
18
  and New Zealand. Also, the stage name of Australian musician
9
19
  [Evelyn Morris][pikelet-musician]. Also, a simple flat-file database parser
@@ -17,8 +27,7 @@ record types. Each record type has a different structure, though some types
17
27
  share common fields, and all types have a type signature.
18
28
 
19
29
  However, Pikelet will also handle more typical flat-file databases comprised
20
- of homogeneous records. Additionally, it will work equally as well with CSV
21
- files as it will with fixed-width records.
30
+ of homogeneous records.
22
31
 
23
32
  ## Installation
24
33
 
@@ -124,38 +133,6 @@ When we parse the data, we end up with this:
124
133
  postal_code="45678Y",
125
134
  state="Someplace">
126
135
 
127
- ### Handling CSV files
128
-
129
- What happens if we were given the data in the previous example in CSV form?
130
-
131
- NAME,Nicolaus,Copernicus
132
- ADDR,123 South Street,Nowhereville,45678Y,Someplace
133
-
134
- In this case instead of describing fields with a boundary range, we just
135
- give it a simple (zero-based) index, like so:
136
-
137
- Pikelet.define do
138
- type_signature 0
139
-
140
- record "NAME" do
141
- first_name 1
142
- last_name 2
143
- end
144
-
145
- record "ADDR" do
146
- street_address 1
147
- city 2
148
- postal_code 3
149
- state 4
150
- end
151
- end
152
-
153
- This yields the same results as above.
154
-
155
- Note that this ability to handle CSV was not planned - it just sprang
156
- fully-formed from the implementation. One of those pleasant little surprises
157
- that happens sometimes. If only I had a use for it.
158
-
159
136
  ### Inheritance
160
137
 
161
138
  Now we go back to our original example, starting with a simple list of names,
@@ -1,17 +1,38 @@
1
1
  module Pikelet
2
2
  class FieldDefinition
3
- attr_reader :index, :parser
3
+ attr_reader :index, :parser, :width
4
4
 
5
- def initialize(index, parse: nil, &parser)
5
+ def initialize(index, parse: nil, &block)
6
+ raise ArgumentError, "index must be a range" unless index.is_a? Range
6
7
  @index = index
7
- @parser = parser || parse || :strip
8
+ @width = index.size
9
+ @parser = parse || block || :strip
8
10
  @parser = @parser.to_proc unless @parser.respond_to? :call
9
11
  end
10
12
 
11
- def parse(text)
12
- if value = text[index]
13
+ def parse(record)
14
+ if value = record[index]
13
15
  parser.call(value)
14
16
  end
15
17
  end
18
+
19
+ def format(value)
20
+ pad(truncate(value))
21
+ end
22
+
23
+ def insert(value, record)
24
+ record[index] = format(value)
25
+ record
26
+ end
27
+
28
+ private
29
+
30
+ def truncate(value)
31
+ value.to_s[0...width]
32
+ end
33
+
34
+ def pad(value)
35
+ (" " * (width - value.size)) + value
36
+ end
16
37
  end
17
38
  end
@@ -23,8 +23,22 @@ module Pikelet
23
23
  parse_records(hashes, method: :parse_hash, &block)
24
24
  end
25
25
 
26
+ def format(records)
27
+ records.map { |record| format_record(record, width: width) }
28
+ end
29
+
30
+ def width
31
+ record_definitions.values.map(&:width).max
32
+ end
33
+
26
34
  private
27
35
 
36
+ def format_record(record, width:)
37
+ record_definition = record.respond_to?(:type_signature) && record_definitions[record.type_signature]
38
+ record_definition ||= base_record_definition
39
+ record_definition.format(record, width: width)
40
+ end
41
+
28
42
  def parse_records(data, method:, &block)
29
43
  records = Enumerator.new do |y|
30
44
  data.each do |data|
@@ -22,8 +22,19 @@ module Pikelet
22
22
  record_class.new(*hash.values_at(*field_definitions.keys))
23
23
  end
24
24
 
25
+ def format(record, width: nil)
26
+ width ||= self.width
27
+ field_definitions.each_with_object(" " * width) do |(field_name, field_definition), result|
28
+ field_definition.insert(record.send(field_name.to_sym), result)
29
+ end
30
+ end
31
+
25
32
  def record_class
26
33
  @record_class ||= Struct.new(*field_definitions.keys.map(&:to_sym))
27
34
  end
35
+
36
+ def width
37
+ field_definitions.values.map(&:width).inject(&:+)
38
+ end
28
39
  end
29
40
  end
@@ -1,3 +1,3 @@
1
1
  module Pikelet
2
- VERSION = "1.1.2"
2
+ VERSION = "2.0.0.beta.1"
3
3
  end
@@ -3,90 +3,139 @@ require "pikelet"
3
3
  require "csv"
4
4
 
5
5
  describe Pikelet::FieldDefinition do
6
- let(:data) { "The quick brown fox" }
7
- let(:definition) { Pikelet::FieldDefinition.new(index) }
6
+ describe "#parse" do
7
+ let(:data) { "The quick brown fox" }
8
+ let(:definition) { Pikelet::FieldDefinition.new(index) }
8
9
 
9
- subject(:result) { definition.parse(data) }
10
+ subject(:parsed) { definition.parse(data) }
10
11
 
11
- context "for a fixed-width field" do
12
- let(:index) { 4...9 }
12
+ context "for a fixed-width field" do
13
+ let(:index) { 4...9 }
13
14
 
14
- it "extracts the field content from the data" do
15
- expect(result).to eq "quick"
15
+ it "extracts the field content from the data" do
16
+ expect(parsed).to eq "quick"
17
+ end
16
18
  end
17
- end
18
19
 
19
- context "given whitespace" do
20
- let(:index) { 3...16 }
20
+ context "given whitespace" do
21
+ let(:index) { 3...16 }
21
22
 
22
- it "strips leading and trailing whitespace" do
23
- expect(result).to eq "quick brown"
23
+ it "strips leading and trailing whitespace" do
24
+ expect(parsed).to eq "quick brown"
25
+ end
24
26
  end
25
- end
26
27
 
27
- context "given a CSV row" do
28
- let(:data) { CSV.parse("The,quick,brown,fox").first }
29
- let(:index) { 2 }
28
+ context "given a custom parser" do
29
+ let(:parser) { ->(value) { value } }
30
30
 
31
- it "extracts the field" do
32
- expect(result).to eq "brown"
33
- end
34
- end
31
+ before do
32
+ allow(parser).to receive(:call)
33
+ parsed
34
+ end
35
35
 
36
- context "given a custom parser" do
37
- let(:parser) { ->(value) { value } }
36
+ context "as a block" do
37
+ let(:index) { 4...9 }
38
+ let(:definition) { Pikelet::FieldDefinition.new(index, &parser) }
38
39
 
39
- before do
40
- allow(parser).to receive(:call)
41
- result
40
+ it "yields the value to the parser" do
41
+ expect(parser).to have_received(:call).with("quick")
42
+ end
43
+ end
44
+
45
+ context "as a parse option" do
46
+ let(:index) { 10...15 }
47
+ let(:definition) { Pikelet::FieldDefinition.new(index, parse: parser) }
48
+
49
+ it "yields the value to the parser" do
50
+ expect(parser).to have_received(:call).with("brown")
51
+ end
52
+ end
42
53
  end
43
54
 
44
- context "as a block" do
45
- let(:index) { 4...9 }
46
- let(:definition) { Pikelet::FieldDefinition.new(index, &parser) }
55
+ context "given a shorthand parser" do
56
+ let(:parser) { :upcase }
57
+
58
+ context "as a block" do
59
+ let(:index) { 10...15 }
60
+ let(:definition) { Pikelet::FieldDefinition.new(index, &parser) }
61
+
62
+ it "invokes the named method on the value" do
63
+ expect(parsed).to eq "BROWN"
64
+ end
65
+ end
66
+
67
+ context "as a parse option" do
68
+ let(:index) { 4...9 }
69
+ let(:definition) { Pikelet::FieldDefinition.new(index, parse: parser) }
47
70
 
48
- it "yields the value to the parser" do
49
- expect(parser).to have_received(:call).with("quick")
71
+ it "invokes the named method on the value" do
72
+ expect(parsed).to eq "QUICK"
73
+ end
50
74
  end
51
75
  end
52
76
 
53
- context "as a parse option" do
54
- let(:index) { 10...15 }
55
- let(:definition) { Pikelet::FieldDefinition.new(index, parse: parser) }
77
+ context "given an index not covered in the data" do
78
+ let(:index) { 999..999 }
56
79
 
57
- it "yields the value to the parser" do
58
- expect(parser).to have_received(:call).with("brown")
80
+ it "parses as nil" do
81
+ expect(parsed).to be_nil
59
82
  end
60
83
  end
61
84
  end
62
85
 
63
- context "given a shorthand parser" do
64
- let(:parser) { :upcase }
86
+ describe "#insert" do
87
+ let(:index) { 4...9 }
88
+ let(:record) { "The _____ brown fox" }
89
+ let(:value) { "quick" }
90
+ let(:definition) { Pikelet::FieldDefinition.new(index) }
65
91
 
66
- context "as a block" do
67
- let(:index) { 10...15 }
68
- let(:definition) { Pikelet::FieldDefinition.new(index, &parser) }
92
+ subject(:result) { definition.insert(value, record) }
69
93
 
70
- it "invokes the named method on the value" do
71
- expect(result).to eq "BROWN"
72
- end
94
+ before do
95
+ allow(definition).to receive(:format).with(value) { value }
73
96
  end
74
97
 
75
- context "as a parse option" do
76
- let(:index) { 4...9 }
77
- let(:definition) { Pikelet::FieldDefinition.new(index, parse: parser) }
98
+ it "formats the value" do
99
+ result
100
+ expect(definition).to have_received(:format).with(value)
101
+ end
78
102
 
79
- it "invokes the named method on the value" do
80
- expect(result).to eq "QUICK"
81
- end
103
+ it "inserts the formatted value into record" do
104
+ expect(result).to eq "The quick brown fox"
82
105
  end
83
106
  end
84
107
 
85
- context "given an index not covered in the data" do
86
- let(:index) { 999..999 }
108
+ describe "#format" do
109
+ let(:index) { 4...9 }
110
+
111
+ subject(:formatted) { definition.format(value) }
112
+
113
+ context "with the default formatter" do
114
+ let(:definition) { Pikelet::FieldDefinition.new(index) }
87
115
 
88
- it "parses as nil" do
89
- expect(result).to be_nil
116
+ context "given a value that fits the field exactly" do
117
+ let(:value) { "quick" }
118
+
119
+ it "returns the value" do
120
+ expect(formatted).to eq "quick"
121
+ end
122
+ end
123
+
124
+ context "given a value larger than the field" do
125
+ let(:value) { "quickk" }
126
+
127
+ it "truncates the value" do
128
+ expect(formatted).to eq "quick"
129
+ end
130
+ end
131
+
132
+ context "givem a value smaller than the field" do
133
+ let(:value) { "quik" }
134
+
135
+ it "pads the the value with spaces at the left" do
136
+ expect(formatted).to eq " quik"
137
+ end
138
+ end
90
139
  end
91
140
  end
92
141
  end
@@ -5,17 +5,25 @@ describe Pikelet::RecordDefinition do
5
5
  let(:data) { "Hello world" }
6
6
  let(:definition) do
7
7
  Pikelet::RecordDefiner.new(nil, base_definition: nil).define do
8
- hello 0...5
9
- world 6..-1
8
+ hello 0... 5
9
+ world 6...11
10
10
  end
11
11
  end
12
- let(:record) { definition.parse(data) }
13
12
 
14
13
  describe "#parse_hash" do
15
- let(:record_hash) { Hash[record.to_h.to_a.reverse] }
14
+ let(:record) { definition.parse(data) }
15
+ let(:record_hash) { Hash[record.to_h.to_a.reverse] }
16
16
 
17
17
  subject { definition.parse_hash(record_hash) }
18
18
 
19
19
  it { is_expected.to eq record }
20
20
  end
21
+
22
+ describe "#format" do
23
+ let(:record) { OpenStruct.new(hello: "Hello", world: "world") }
24
+
25
+ subject { definition.format(record) }
26
+
27
+ it { is_expected.to eq "Hello world" }
28
+ end
21
29
  end
data/spec/pikelet_spec.rb CHANGED
@@ -9,190 +9,205 @@ describe Pikelet do
9
9
  end
10
10
  end
11
11
 
12
- let(:records) { definition.parse(data).to_a }
13
-
14
- subject { records }
15
-
16
- describe "for a simple flat file" do
12
+ describe "#format" do
17
13
  let(:definition) do
18
14
  Pikelet.define do
19
- name 0... 4
20
- number 4...13
15
+ type_signature 0...4
16
+
17
+ record "NAME" do
18
+ first_name 4...14
19
+ last_name 14...24
20
+ end
21
+
22
+ record "ADDR" do
23
+ street_address 4...24
24
+ city 24...44
25
+ postal_code 44...54
26
+ state 54...74
27
+ end
21
28
  end
22
29
  end
23
30
 
24
- let(:data) do
25
- <<-FILE.gsub(/^\s*/, "").split(/[\r\n]+/)
26
- John012345678
27
- Sue 087654321
28
- FILE
31
+ let(:records) do
32
+ [
33
+ { type_signature: 'NAME', first_name: "Nicolaus", last_name: 'Copernicus' },
34
+ { type_signature: 'ADDR', street_address: "123 South Street", city: "Nowhereville", postal_code: "45678Y", state: "Someplace" }
35
+ ].map(&OpenStruct.method(:new))
29
36
  end
30
37
 
31
- it { is_expected.to have(2).records }
38
+ subject(:formatted) { definition.format(records) }
32
39
 
33
- its(:first) { is_expected.to match_hash(name: "John", number: "012345678") }
34
- its(:last) { is_expected.to match_hash(name: "Sue", number: "087654321") }
40
+ it { is_expected.to have(2).lines }
41
+
42
+ its(:first) { is_expected.to eq "NAME NicolausCopernicus " }
43
+ its(:last) { is_expected.to eq "ADDR 123 South Street Nowhereville 45678Y Someplace" }
35
44
  end
36
45
 
37
- describe "for a file with heterogeneous records" do
38
- let(:definition) do
39
- Pikelet.define do
40
- type_signature 0...1
46
+ describe "#parse" do
47
+ let(:records) { definition.parse(data).to_a }
41
48
 
42
- record 'A' do
43
- name 1... 5
44
- number 5...14
45
- end
49
+ subject { records }
46
50
 
47
- record 'B' do
48
- number 1...10
49
- name 10...14
51
+ describe "for a simple flat file" do
52
+ let(:definition) do
53
+ Pikelet.define do
54
+ name 0... 4
55
+ number 4...13
50
56
  end
51
57
  end
52
- end
53
58
 
54
- let(:data) do
55
- <<-FILE.gsub(/^\s*/, "").split(/[\r\n]+/)
56
- AJohn012345678
57
- B087654321Sue
58
- FILE
59
+ let(:data) do
60
+ <<-FILE.split(/[\r\n]+/).map(&:lstrip)
61
+ John012345678
62
+ Sue 087654321
63
+ FILE
64
+ end
65
+
66
+ it { is_expected.to have(2).records }
67
+
68
+ its(:first) { is_expected.to match_hash(name: "John", number: "012345678") }
69
+ its(:last) { is_expected.to match_hash(name: "Sue", number: "087654321") }
59
70
  end
60
71
 
72
+ describe "for a file with heterogeneous records" do
73
+ let(:definition) do
74
+ Pikelet.define do
75
+ type_signature 0...1
61
76
 
62
- it { is_expected.to have(2).records }
77
+ record 'A' do
78
+ name 1... 5
79
+ number 5...14
80
+ end
63
81
 
64
- its(:first) { is_expected.to match_hash(name: "John", number: "012345678", type_signature: "A") }
65
- its(:last) { is_expected.to match_hash(name: "Sue", number: "087654321", type_signature: "B") }
66
- end
82
+ record 'B' do
83
+ number 1...10
84
+ name 10...14
85
+ end
86
+ end
87
+ end
67
88
 
68
- describe "for a CSV file" do
69
- let(:definition) do
70
- Pikelet.define do
71
- name 0
72
- number 1
89
+ let(:data) do
90
+ <<-FILE.split(/[\r\n]+/).map(&:lstrip)
91
+ AJohn012345678
92
+ B087654321Sue
93
+ FILE
73
94
  end
74
- end
75
95
 
76
- let(:data) do
77
- CSV.parse <<-FILE.gsub(/^\s*/, "")
78
- John,012345678
79
- Sue,087654321
80
- FILE
81
- end
82
96
 
83
- it { is_expected.to have(2).records }
97
+ it { is_expected.to have(2).records }
84
98
 
85
- its(:first) { is_expected.to match_hash(name: "John", number: "012345678") }
86
- its(:last) { is_expected.to match_hash(name: "Sue", number: "087654321") }
87
- end
99
+ its(:first) { is_expected.to match_hash(name: "John", number: "012345678", type_signature: "A") }
100
+ its(:last) { is_expected.to match_hash(name: "Sue", number: "087654321", type_signature: "B") }
101
+ end
88
102
 
89
- describe "inheritance" do
90
- let(:definition) do
91
- Pikelet.define do
92
- type_signature 0...6
103
+ describe "inheritance" do
104
+ let(:definition) do
105
+ Pikelet.define do
106
+ type_signature 0...6
93
107
 
94
- record 'SIMPLE' do
95
- name 6...10
108
+ record 'SIMPLE' do
109
+ name 6...10
96
110
 
97
- record 'FANCY' do
98
- number 10...19
111
+ record 'FANCY' do
112
+ number 10...19
113
+ end
99
114
  end
100
115
  end
101
116
  end
102
- end
103
117
 
104
- let(:data) do
105
- <<-FILE.gsub(/^\s*/, "").split(/[\r\n]+/)
106
- SIMPLEJohn012345678
107
- FANCY Sue 087654321
108
- FILE
109
- end
118
+ let(:data) do
119
+ <<-FILE.split(/[\r\n]+/).map(&:lstrip)
120
+ SIMPLEJohn012345678
121
+ FANCY Sue 087654321
122
+ FILE
123
+ end
110
124
 
111
- it { is_expected.to have(2).records }
125
+ it { is_expected.to have(2).records }
112
126
 
113
- its(:first) { is_expected.to match_hash(name: "John", type_signature: "SIMPLE") }
114
- its(:last) { is_expected.to match_hash(name: "Sue", number: "087654321", type_signature: "FANCY") }
115
- end
127
+ its(:first) { is_expected.to match_hash(name: "John", type_signature: "SIMPLE") }
128
+ its(:last) { is_expected.to match_hash(name: "Sue", number: "087654321", type_signature: "FANCY") }
129
+ end
116
130
 
117
- describe "given a block for field parsing" do
118
- let(:definition) do
119
- Pikelet.define do
120
- value(0...4) { |value| value.to_i }
131
+ describe "given a block for field parsing" do
132
+ let(:definition) do
133
+ Pikelet.define do
134
+ value(0...4) { |value| value.to_i }
135
+ end
121
136
  end
122
- end
123
137
 
124
- let(:data) do
125
- <<-FILE.gsub(/^\s*/, "").split(/[\r\n]+/)
126
- 5637
127
- FILE
128
- end
138
+ let(:data) do
139
+ <<-FILE.split(/[\r\n]+/).map(&:lstrip)
140
+ 5637
141
+ FILE
142
+ end
129
143
 
130
- subject { records.first }
144
+ subject { records.first }
131
145
 
132
- its(:value) { is_expected.to eq 5637 }
133
- end
146
+ its(:value) { is_expected.to eq 5637 }
147
+ end
134
148
 
135
- describe "given a parse option" do
136
- let(:definition) do
137
- Pikelet.define do
138
- value 0...4, parse: ->(value) { value.to_i }
149
+ describe "given a parse option" do
150
+ let(:definition) do
151
+ Pikelet.define do
152
+ value 0...4, parse: ->(value) { value.to_i }
153
+ end
139
154
  end
140
- end
141
155
 
142
- let(:data) do
143
- <<-FILE.gsub(/^\s*/, "").split(/[\r\n]+/)
144
- 5637
145
- FILE
146
- end
156
+ let(:data) do
157
+ <<-FILE.split(/[\r\n]+/).map(&:lstrip)
158
+ 5637
159
+ FILE
160
+ end
147
161
 
148
- subject { records.first }
162
+ subject { records.first }
149
163
 
150
- its(:value) { is_expected.to eq 5637 }
151
- end
164
+ its(:value) { is_expected.to eq 5637 }
165
+ end
152
166
 
153
- describe "given a shorthand parse option" do
154
- let(:definition) do
155
- Pikelet.define do
156
- value 0...4, parse: :to_i
167
+ describe "given a shorthand parse option" do
168
+ let(:definition) do
169
+ Pikelet.define do
170
+ value 0...4, parse: :to_i
171
+ end
157
172
  end
158
- end
159
173
 
160
- let(:data) do
161
- <<-FILE.gsub(/^\s*/, "").split(/[\r\n]+/)
162
- 5637
163
- FILE
164
- end
174
+ let(:data) do
175
+ <<-FILE.split(/[\r\n]+/).map(&:lstrip)
176
+ 5637
177
+ FILE
178
+ end
165
179
 
166
- subject { records.first }
180
+ subject { records.first }
167
181
 
168
- its(:value) { is_expected.to eq 5637 }
169
- end
182
+ its(:value) { is_expected.to eq 5637 }
183
+ end
170
184
 
171
- describe "given a block when parsing" do
172
- let(:collected_records) { [] }
185
+ describe "given a block when parsing" do
186
+ let(:collected_records) { [] }
173
187
 
174
- let(:definition) do
175
- Pikelet.define do
176
- name 0... 4
177
- number 4...13
188
+ let(:definition) do
189
+ Pikelet.define do
190
+ name 0... 4
191
+ number 4...13
192
+ end
178
193
  end
179
- end
180
194
 
181
- let(:data) do
182
- <<-FILE.gsub(/^\s*/, "").split(/[\r\n]+/)
183
- John012345678
184
- Sue 087654321
185
- FILE
186
- end
195
+ let(:data) do
196
+ <<-FILE.split(/[\r\n]+/).map(&:lstrip)
197
+ John012345678
198
+ Sue 087654321
199
+ FILE
200
+ end
187
201
 
188
- before do
189
- definition.parse(data) do |record|
190
- collected_records << record.to_h
202
+ before do
203
+ definition.parse(data) do |record|
204
+ collected_records << record.to_h
205
+ end
191
206
  end
192
- end
193
207
 
194
- it 'yields each record to the block' do
195
- expect(collected_records).to contain_exactly(*records.map(&:to_h))
208
+ it 'yields each record to the block' do
209
+ expect(collected_records).to contain_exactly(*records.map(&:to_h))
210
+ end
196
211
  end
197
212
  end
198
213
 
@@ -205,7 +220,7 @@ describe Pikelet do
205
220
  end
206
221
 
207
222
  let(:data) do
208
- <<-FILE.gsub(/^\s*/, "").split(/[\r\n]+/)
223
+ <<-FILE.split(/[\r\n]+/).map(&:lstrip)
209
224
  John012345678
210
225
  Sue 087654321
211
226
  FILE
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pikelet
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.1.2
4
+ version: 2.0.0.beta.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - John Carney
@@ -151,9 +151,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
151
151
  version: 2.1.0
152
152
  required_rubygems_version: !ruby/object:Gem::Requirement
153
153
  requirements:
154
- - - ">="
154
+ - - ">"
155
155
  - !ruby/object:Gem::Version
156
- version: '0'
156
+ version: 1.3.1
157
157
  requirements: []
158
158
  rubyforge_project:
159
159
  rubygems_version: 2.4.3