pikelet 2.0.0.beta.3 → 2.0.0.beta.4

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: 68d81342d91b044e20a05a3b6f1529c4ecf92341
4
- data.tar.gz: f15c6928d585b0d1a8e65674d5193c69a0a47efc
3
+ metadata.gz: 70a0fcf61a81ceefc60f5553225d9e9c8aef3038
4
+ data.tar.gz: fb8276527757550144e73f69b939bdeb6038a430
5
5
  SHA512:
6
- metadata.gz: e1bc4ca7eda495fa16b92a000e41e62c017e4d1b043729e3e544f0b679dbc084b7b4ffebe7d03c1b1fdcb354f9a0d3d8aee37583730e2af552baf3aa53de90ea
7
- data.tar.gz: 21aad39051235f6bb604f7151c3912bec8ac37c93ca084a07c83aa8863360522cfd4a1f796ad1c7f0ebadbd48209fd37e11fa75c5ab5ee0d4a630f82aacdca3a
6
+ metadata.gz: 3532873fe18e685b72fe211270f08d55b343e4e5cf87d094d0ec191b21c255e57c1e5eec609f2d5d789791ecfea7b9d00652ef23c6cdf034a256866ed4631c48
7
+ data.tar.gz: e274f942d76718d17a135affafff8152299edb84a06a66aaa70d9be561fd4e2d6f7087503fe11f9c3395990c3cf5b7ebf2ea8f2084e10656117bfe136dff8a26
@@ -2,13 +2,14 @@ module Pikelet
2
2
  class FileDefinition
3
3
  attr_reader :base_record_definition
4
4
 
5
- def initialize(&block)
6
- @base_record_definition = RecordDefiner.new(self).define(&block)
5
+ def initialize(record_class: nil, &block)
6
+ @base_record_definition = RecordDefiner.new(self, record_class: record_class).define(&block)
7
7
  end
8
8
 
9
- def record(type_signature, base_definition: nil, &block)
9
+ def record(type_signature, record_class: nil, base_definition: nil, &block)
10
10
  base_definition ||= base_record_definition
11
- record_definitions[type_signature] = RecordDefiner.new(self, base_definition: base_definition).define(&block)
11
+ definer = RecordDefiner.new(self, record_class: record_class, base_definition: base_definition)
12
+ record_definitions[type_signature] = definer.define(&block)
12
13
  end
13
14
 
14
15
  def record_definitions
@@ -2,9 +2,9 @@ module Pikelet
2
2
  class RecordDefiner
3
3
  attr_reader :file_definition, :definition
4
4
 
5
- def initialize(file_definition, base_definition: nil)
5
+ def initialize(file_definition, record_class: nil, base_definition: nil)
6
6
  @file_definition = file_definition
7
- @definition = RecordDefinition.new(file_definition, base_definition: base_definition)
7
+ @definition = RecordDefinition.new(file_definition, record_class: record_class, base_definition: base_definition)
8
8
  end
9
9
 
10
10
  def define(&block)
@@ -27,8 +27,8 @@ module Pikelet
27
27
  end
28
28
  end
29
29
 
30
- def record(type_signature, &block)
31
- file_definition.record(type_signature, base_definition: definition, &block)
30
+ def record(type_signature, record_class: nil, &block)
31
+ file_definition.record(type_signature, record_class: record_class, base_definition: definition, &block)
32
32
  end
33
33
 
34
34
  def method_missing(method, *args, **options, &block)
@@ -5,13 +5,13 @@ module Pikelet
5
5
  attr_reader :file_definition, :field_definitions
6
6
  attr_writer :type_signature
7
7
 
8
- def initialize(file_definition, base_definition:)
8
+ def initialize(file_definition, record_class: nil, base_definition:)
9
9
  @file_definition = file_definition
10
10
  @field_definitions = base_definition && base_definition.field_definitions.dup || {}
11
+ @record_class = record_class
11
12
  end
12
13
 
13
14
  def field(name, index, **options, &block)
14
- @record_class = nil
15
15
  field_definitions[name] = Pikelet::FieldDefinition.new(index, **options, &block)
16
16
  end
17
17
 
@@ -27,7 +27,7 @@ module Pikelet
27
27
  end
28
28
 
29
29
  def parse(data)
30
- record_class.new(*field_definitions.values.map { |field| field.parse(data) })
30
+ record_class.new(parse_fields(data))
31
31
  end
32
32
 
33
33
  def format(record, width: nil)
@@ -38,11 +38,32 @@ module Pikelet
38
38
  end
39
39
 
40
40
  def record_class
41
- @record_class ||= Struct.new(*field_definitions.keys.map(&:to_sym))
41
+ @record_class ||= default_record_class
42
+ end
43
+
44
+ def default_record_class
45
+ Struct.new(*field_names) do
46
+ def initialize(**attributes)
47
+ # FIXME: Do we need to worry about missing attributes?
48
+ super(*attributes.values_at(*self.class.members))
49
+ end
50
+ end
42
51
  end
43
52
 
44
53
  def width
45
- field_definitions.values.map(&:width).inject(&:+)
54
+ field_definitions.values.map { |d| d.index.max }.max + 1
55
+ end
56
+
57
+ private
58
+
59
+ def field_names
60
+ field_definitions.keys.map(&:to_sym)
61
+ end
62
+
63
+ def parse_fields(data)
64
+ field_definitions.each_with_object({}) do |(field, definition), result|
65
+ result[field.to_sym] = definition.parse(data)
66
+ end
46
67
  end
47
68
  end
48
69
  end
@@ -1,3 +1,3 @@
1
1
  module Pikelet
2
- VERSION = "2.0.0.beta.3"
2
+ VERSION = "2.0.0.beta.4"
3
3
  end
data/lib/pikelet.rb CHANGED
@@ -4,7 +4,7 @@ require "pikelet/record_definition"
4
4
  require "pikelet/field_definition"
5
5
 
6
6
  module Pikelet
7
- def self.define(&block)
8
- Pikelet::FileDefinition.new(&block)
7
+ def self.define(record_class: nil, &block)
8
+ Pikelet::FileDefinition.new(record_class: record_class, &block)
9
9
  end
10
10
  end
@@ -2,9 +2,12 @@ require "spec_helper"
2
2
  require "pikelet"
3
3
 
4
4
  describe Pikelet::RecordDefinition do
5
- let(:data) { "Hello world" }
5
+ let(:definer) { Pikelet::RecordDefiner.new(nil, base_definition: nil) }
6
+
7
+ let(:data) { "Hello world" }
8
+
6
9
  let(:definition) do
7
- Pikelet::RecordDefiner.new(nil, base_definition: nil).define do
10
+ definer.define do
8
11
  hello 0... 5
9
12
  world 6...11
10
13
  end
@@ -43,4 +46,47 @@ describe Pikelet::RecordDefinition do
43
46
  its(:type_signature) { is_expected.to eq :type_signature }
44
47
  end
45
48
  end
49
+
50
+ describe "#width" do
51
+ subject(:width) { definition.width }
52
+
53
+ context "with contiguous fields" do
54
+ let(:definition) do
55
+ definer.define do
56
+ hello 0... 5
57
+ world 6...11
58
+ end
59
+ end
60
+
61
+ it "returns the width of the record" do
62
+ expect(width).to eq 11
63
+ end
64
+ end
65
+
66
+ context "with overlapping fields" do
67
+ let(:definition) do
68
+ definer.define do
69
+ hello 0..6
70
+ world 4..9
71
+ end
72
+ end
73
+
74
+ it "returns the width of the record" do
75
+ expect(width).to eq 10
76
+ end
77
+ end
78
+
79
+ context "with discontinuous fields" do
80
+ let(:definition) do
81
+ definer.define do
82
+ hello 4... 7
83
+ world 9...16
84
+ end
85
+ end
86
+
87
+ it "returns the width of the record" do
88
+ expect(width).to eq 16
89
+ end
90
+ end
91
+ end
46
92
  end
data/spec/pikelet_spec.rb CHANGED
@@ -9,6 +9,36 @@ describe Pikelet do
9
9
  end
10
10
  end
11
11
 
12
+ describe "custom record classes" do
13
+ let(:custom_class) do
14
+ Class.new do
15
+ attr_reader :first_name, :last_name
16
+
17
+ def initialize(**attrs)
18
+ @first_name = attrs[:first_name]
19
+ @last_name = attrs[:last_name]
20
+ end
21
+ end
22
+ end
23
+
24
+ let(:definition) do
25
+ Pikelet.define record_class: custom_class do
26
+ first_name 0...10
27
+ last_name 10...20
28
+ end
29
+ end
30
+
31
+ let(:data) { [ "Nicolaus Copernicus" ] }
32
+ subject(:record) { definition.parse(data).to_a.first }
33
+
34
+ it "uses the supplied record class" do
35
+ expect(record).to be_a custom_class
36
+ end
37
+
38
+ its(:first_name) { is_expected.to eq "Nicolaus" }
39
+ its(:last_name) { is_expected.to eq "Copernicus" }
40
+ end
41
+
12
42
  describe "#format" do
13
43
  let(:definition) do
14
44
  Pikelet.define do
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.3
4
+ version: 2.0.0.beta.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - John Carney