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

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.
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