pikelet 2.0.0.beta.2 → 2.0.0.beta.3

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: 38ba6a85d7364f3d8a5b93bb24cc8d64bac5de91
4
- data.tar.gz: e6e9e5e60b8ac35c8669fa992327ee422d3871f6
3
+ metadata.gz: 68d81342d91b044e20a05a3b6f1529c4ecf92341
4
+ data.tar.gz: f15c6928d585b0d1a8e65674d5193c69a0a47efc
5
5
  SHA512:
6
- metadata.gz: b0a0c5500a5f72c17735608a678f78fbdd9c433c086be1875e1077d11da3e2463c3704cf75621f4a4c6ff569e8ea8873d82bd26d06f4042ee47b8b9a68a83c08
7
- data.tar.gz: e65c43af74592ffe8462c91dab56abc0d67bbb82880ba227b0342f3ea542827686653dadbf46873dc244a2e0d55313c5d23e5daf821ce78f200ea62e2ead15ab
6
+ metadata.gz: e1bc4ca7eda495fa16b92a000e41e62c017e4d1b043729e3e544f0b679dbc084b7b4ffebe7d03c1b1fdcb354f9a0d3d8aee37583730e2af552baf3aa53de90ea
7
+ data.tar.gz: 21aad39051235f6bb604f7151c3912bec8ac37c93ca084a07c83aa8863360522cfd4a1f796ad1c7f0ebadbd48209fd37e11fa75c5ab5ee0d4a630f82aacdca3a
@@ -16,11 +16,7 @@ module Pikelet
16
16
  end
17
17
 
18
18
  def parse(data, &block)
19
- parse_records(data, method: :parse, &block)
20
- end
21
-
22
- def parse_hashes(hashes, &block)
23
- parse_records(hashes, method: :parse_hash, &block)
19
+ parse_records(data, &block)
24
20
  end
25
21
 
26
22
  def format(records)
@@ -33,33 +29,38 @@ module Pikelet
33
29
 
34
30
  private
35
31
 
32
+ def records_with_type_signatures
33
+ [ base_record_definition, *record_definitions.values ].select(&:type_signature)
34
+ end
35
+
36
+ def type_signatures
37
+ records_with_type_signatures.map(&:type_signature).uniq
38
+ end
39
+
40
+ def best_definition(signatures)
41
+ signatures.map { |sig| record_definitions[sig] }.detect { |d| d } || base_record_definition
42
+ end
43
+
36
44
  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)
45
+ signatures = type_signatures.lazy.select(&record.method(:respond_to?)).map(&record.method(:send))
46
+ best_definition(signatures).format(record, width: width)
40
47
  end
41
48
 
42
- def parse_records(data, method:, &block)
43
- records = Enumerator.new do |y|
44
- data.each do |data|
45
- y.yield(parse_record(data, method: method))
49
+ def parse_records(data, &block)
50
+ data.map(&method(:parse_record)).tap do |records|
51
+ if block_given?
52
+ records.each(&block)
46
53
  end
47
54
  end
48
- if block_given?
49
- records.each(&block)
50
- else
51
- records
52
- end
53
55
  end
54
56
 
55
- def parse_record(data, method:)
56
- record = base_record_definition.send(method, data)
57
- if record.respond_to?(:type_signature)
58
- if definition = record_definitions[record.type_signature]
59
- record = definition.send(method, data)
60
- end
61
- end
62
- record
57
+ def signature_fields
58
+ records_with_type_signatures.map(&:signature_field).uniq
59
+ end
60
+
61
+ def parse_record(data)
62
+ signatures = signature_fields.lazy.map { |field| field.parse(data) }
63
+ best_definition(signatures).parse(data)
63
64
  end
64
65
  end
65
66
  end
@@ -18,6 +18,15 @@ module Pikelet
18
18
  definition.field(name, index, **options, &block)
19
19
  end
20
20
 
21
+ def type_signature(field_or_index, **options, &block)
22
+ if field_or_index.is_a? Range
23
+ field(:type_signature, field_or_index, **options, &block)
24
+ definition.type_signature = :type_signature
25
+ else
26
+ definition.type_signature = field_or_index
27
+ end
28
+ end
29
+
21
30
  def record(type_signature, &block)
22
31
  file_definition.record(type_signature, base_definition: definition, &block)
23
32
  end
@@ -3,6 +3,7 @@ require "pikelet/record_definer"
3
3
  module Pikelet
4
4
  class RecordDefinition
5
5
  attr_reader :file_definition, :field_definitions
6
+ attr_writer :type_signature
6
7
 
7
8
  def initialize(file_definition, base_definition:)
8
9
  @file_definition = file_definition
@@ -14,12 +15,19 @@ module Pikelet
14
15
  field_definitions[name] = Pikelet::FieldDefinition.new(index, **options, &block)
15
16
  end
16
17
 
17
- def parse(data)
18
- record_class.new(*field_definitions.values.map { |field| field.parse(data) })
18
+ def type_signature
19
+ unless defined? @type_signature
20
+ @type_signature = :type_signature if field_definitions.key? :type_signature
21
+ end
22
+ @type_signature
19
23
  end
20
24
 
21
- def parse_hash(hash)
22
- record_class.new(*hash.values_at(*field_definitions.keys))
25
+ def signature_field
26
+ type_signature && field_definitions[type_signature]
27
+ end
28
+
29
+ def parse(data)
30
+ record_class.new(*field_definitions.values.map { |field| field.parse(data) })
23
31
  end
24
32
 
25
33
  def format(record, width: nil)
@@ -1,3 +1,3 @@
1
1
  module Pikelet
2
- VERSION = "2.0.0.beta.2"
2
+ VERSION = "2.0.0.beta.3"
3
3
  end
@@ -0,0 +1,37 @@
1
+ require "spec_helper"
2
+ require "pikelet"
3
+
4
+ describe Pikelet::RecordDefiner do
5
+ let(:definer) { described_class.new(nil) }
6
+ let(:definition) { definer.definition }
7
+
8
+ describe "#type_signature" do
9
+ context "given a field name" do
10
+ before do
11
+ allow(definition).to receive(:type_signature=).and_call_original
12
+ definer.type_signature :type
13
+ end
14
+
15
+ it "sets the type signature field on the record definition" do
16
+ expect(definition).to have_received(:type_signature=).with(:type)
17
+ end
18
+ end
19
+
20
+ context "legacy usage" do
21
+ before do
22
+ allow(definition).to receive(:type_signature=).and_call_original
23
+ allow(definer).to receive(:field).and_call_original
24
+ definer.type_signature 0...4, align: :right, pad: "0", &:to_i
25
+ end
26
+
27
+ it "creates the field" do
28
+ expect(definer).to have_received(:field).with(:type_signature, 0...4, align: :right, pad: "0", &:to_i)
29
+ end
30
+
31
+ it "sets the type signature field on the record definition" do
32
+ expect(definition).to have_received(:type_signature=).with(:type_signature)
33
+ end
34
+ end
35
+ end
36
+ end
37
+
@@ -10,15 +10,6 @@ describe Pikelet::RecordDefinition do
10
10
  end
11
11
  end
12
12
 
13
- describe "#parse_hash" do
14
- let(:record) { definition.parse(data) }
15
- let(:record_hash) { Hash[record.to_h.to_a.reverse] }
16
-
17
- subject { definition.parse_hash(record_hash) }
18
-
19
- it { is_expected.to eq record }
20
- end
21
-
22
13
  describe "#format" do
23
14
  let(:record) { OpenStruct.new(hello: "Hello", world: "world") }
24
15
 
@@ -26,4 +17,30 @@ describe Pikelet::RecordDefinition do
26
17
 
27
18
  it { is_expected.to eq "Hello world" }
28
19
  end
20
+
21
+ describe "#type_signature" do
22
+ let(:definition) { described_class.new(nil, base_definition: nil) }
23
+
24
+ subject { definition }
25
+
26
+ context "with no fields and no signature defined" do
27
+ its(:type_signature) { is_expected.to be_nil }
28
+ end
29
+
30
+ context "with signature defined" do
31
+ before do
32
+ definition.type_signature = :type
33
+ end
34
+
35
+ its(:type_signature) { is_expected.to eq :type }
36
+ end
37
+
38
+ context "with a field named :type_signature" do
39
+ before do
40
+ definition.field(:type_signature, 0...3)
41
+ end
42
+
43
+ its(:type_signature) { is_expected.to eq :type_signature }
44
+ end
45
+ end
29
46
  end
data/spec/pikelet_spec.rb CHANGED
@@ -210,27 +210,4 @@ describe Pikelet do
210
210
  end
211
211
  end
212
212
  end
213
-
214
- describe "#parse_hashes" do
215
- let(:definition) do
216
- Pikelet.define do
217
- name 0... 4
218
- number 4...13
219
- end
220
- end
221
-
222
- let(:data) do
223
- <<-FILE.split(/[\r\n]+/).map(&:lstrip)
224
- John012345678
225
- Sue 087654321
226
- FILE
227
- end
228
-
229
- let(:records) { definition.parse(data) }
230
- let(:hashes) { records.map(&:to_h) }
231
-
232
- subject { definition.parse_hashes(hashes).to_a }
233
-
234
- it { is_expected.to eq records.to_a }
235
- end
236
213
  end
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: 2.0.0.beta.2
4
+ version: 2.0.0.beta.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - John Carney
@@ -133,6 +133,7 @@ files:
133
133
  - lib/pikelet/version.rb
134
134
  - pikelet.gemspec
135
135
  - spec/pikelet/field_definition_spec.rb
136
+ - spec/pikelet/record_definer_spec.rb
136
137
  - spec/pikelet/record_definition_spec.rb
137
138
  - spec/pikelet_spec.rb
138
139
  - spec/spec_helper.rb
@@ -162,6 +163,7 @@ specification_version: 4
162
163
  summary: A simple flat-file database parser.
163
164
  test_files:
164
165
  - spec/pikelet/field_definition_spec.rb
166
+ - spec/pikelet/record_definer_spec.rb
165
167
  - spec/pikelet/record_definition_spec.rb
166
168
  - spec/pikelet_spec.rb
167
169
  - spec/spec_helper.rb