pikelet 2.0.0.beta.5 → 2.0.0.beta.6

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: f1dcc5a3b20d8e3277715f1841f88ea4dc22839c
4
- data.tar.gz: a7526777b26bc21e7966fc7e1386083fe3630aac
3
+ metadata.gz: 3087089478a24e533544d4338a8960fe279cf967
4
+ data.tar.gz: 359ba4f4e47ceb3e5398384aadd8cceea288f005
5
5
  SHA512:
6
- metadata.gz: 8f7957af9756008020b857e9ad2eb7e5e6c3474315900c55536babe8c685f6c596d2d798c1af2c597f5c30d34172b267aa4f68649dfed21c2b928f73805fc281
7
- data.tar.gz: 275f4b314132e74d5cd74a73c32f78264d34f13cad6f286dc7a929d299f55fac5affeb040103d796ae98dde138e7d56672889203787fd88e52db8fb592f31d4d
6
+ metadata.gz: 4f77a62b628790a4a39bc4a5a35d33530fef9095d39490b4fb0d4991fae9764e8b298c68d2e78924f572004a809f3d4e6beaa11e35cd567d60dadb9ec8b89687
7
+ data.tar.gz: 9c14bfce0aea5c1fab0bd6259cf6d434fd816399c917a7d98b08b47ff8a3a325951d9ffcb3434df5ae7f15a60391c3b9d95c43ea984b4d2424c42d88d11bd031
@@ -10,6 +10,11 @@ module Pikelet
10
10
  @formatter = format || :to_s
11
11
  @padding = pad && pad.to_s || " "
12
12
  @alignment = align || :left
13
+ if alignment == :right
14
+ @align_method = :rjust
15
+ else
16
+ @align_method = :ljust
17
+ end
13
18
  end
14
19
 
15
20
  def parse(record)
@@ -19,7 +24,7 @@ module Pikelet
19
24
  end
20
25
 
21
26
  def format(value)
22
- pad(truncate(formatter.to_proc.call(value)))
27
+ align(formatter.to_proc.call(value))[0...width]
23
28
  end
24
29
 
25
30
  def insert(value, record)
@@ -29,20 +34,10 @@ module Pikelet
29
34
 
30
35
  private
31
36
 
32
- def blank
33
- @blank ||= padding * width
34
- end
37
+ attr_reader :align_method
35
38
 
36
- def truncate(value)
37
- value[0...width]
38
- end
39
-
40
- def pad(value)
41
- if alignment == :left
42
- value + blank[value.size...width]
43
- else
44
- blank[-width..-(1+value.size)] + value
45
- end
39
+ def align(value)
40
+ value.send(align_method, width, padding)
46
41
  end
47
42
  end
48
43
  end
@@ -4,13 +4,13 @@ module Pikelet
4
4
 
5
5
  def initialize(signature_field: nil, record_class: nil, &block)
6
6
  @signature_field = signature_field
7
- definer = RecordDefiner.new(self, record_class: record_class)
8
- @base = definer.define(&block)
7
+ if block_given?
8
+ @base = define_record(nil, record_class: record_class, base: nil, &block)
9
+ end
9
10
  end
10
11
 
11
- def record(signature, record_class: nil, base: nil, &block)
12
- definer = RecordDefiner.new(self, record_class: record_class, base: base || self.base)
13
- record_definitions[signature] = definer.define(&block)
12
+ def define_record(signature, record_class:, base:, &block)
13
+ record_definitions[signature] = RecordDefiner.define(self, record_class: record_class, base: base, &block)
14
14
  end
15
15
 
16
16
  def record_definitions
@@ -31,29 +31,13 @@ module Pikelet
31
31
 
32
32
  private
33
33
 
34
- def all_record_definitions
35
- [ base, *record_definitions.values ]
36
- end
37
-
38
- def records_with_type_signatures
39
- all_record_definitions.select(&:type_signature)
40
- end
41
-
42
- def type_signatures
43
- records_with_type_signatures.map(&:type_signature).uniq
44
- end
45
-
46
- def best_definition(signatures)
47
- signatures.map { |sig| record_definitions[sig] }.detect { |d| d } || base
48
- end
49
-
50
34
  def record_signature(record)
51
- field = signature_field || (all_record_definitions.detect(&:signature_field) && :type_signature)
52
- record.send(field) if record.respond_to?(field)
35
+ field = signature_field || (record_definitions.values.detect(&:signature_field) && :type_signature)
36
+ record.send(field) if field && record.respond_to?(field)
53
37
  end
54
38
 
55
39
  def format_record(record, width:)
56
- definition = record_definitions[record_signature(record)] || base
40
+ definition = record_definitions[record_signature(record)]
57
41
  definition.format(record, width: width)
58
42
  end
59
43
 
@@ -66,12 +50,12 @@ module Pikelet
66
50
  end
67
51
 
68
52
  def signature_fields
69
- all_record_definitions.map(&:signature_field).compact.uniq
53
+ record_definitions.values.map(&:signature_field).compact.uniq
70
54
  end
71
55
 
72
56
  def parse_record(data)
73
- signatures = signature_fields.lazy.map { |field| field.parse(data) }
74
- definition = signatures.map { |sig| record_definitions[sig] }.detect { |defn| defn } || base
57
+ signatures = signature_fields.lazy.map { |field| field.parse(data) }.reject(&:nil?)
58
+ definition = signatures.map { |sig| record_definitions[sig] }.reject(&:nil?).first || base
75
59
  definition.parse(data)
76
60
  end
77
61
  end
@@ -2,19 +2,9 @@ module Pikelet
2
2
  class RecordDefiner
3
3
  attr_reader :file_definition, :definition
4
4
 
5
- def initialize(file_definition, record_class: nil, base: nil)
5
+ def initialize(file_definition, record_class:, base:)
6
6
  @file_definition = file_definition
7
- @definition = RecordDefinition.new(file_definition,
8
- record_class: record_class,
9
- base: base
10
- )
11
- end
12
-
13
- def define(&block)
14
- if block_given?
15
- instance_eval(&block)
16
- end
17
- definition
7
+ @definition = RecordDefinition.new(file_definition, record_class: record_class, base: base)
18
8
  end
19
9
 
20
10
  def field(name, index, **options, &block)
@@ -22,11 +12,17 @@ module Pikelet
22
12
  end
23
13
 
24
14
  def record(signature, record_class: nil, &block)
25
- file_definition.record(signature, record_class: record_class, base: definition, &block)
15
+ file_definition.define_record(signature, record_class: record_class, base: definition, &block)
26
16
  end
27
17
 
28
18
  def method_missing(method, *args, **options, &block)
29
19
  field(method, *args, **options, &block)
30
20
  end
21
+
22
+ def self.define(file_definition, record_class: nil, base: nil, &block)
23
+ definer = self.new(file_definition, record_class: record_class, base: base)
24
+ definer.instance_eval(&block) if block_given?
25
+ definer.definition
26
+ end
31
27
  end
32
28
  end
@@ -1,3 +1,3 @@
1
1
  module Pikelet
2
- VERSION = "2.0.0.beta.5"
2
+ VERSION = "2.0.0.beta.6"
3
3
  end
@@ -174,7 +174,7 @@ describe Pikelet::FieldDefinition do
174
174
  let(:index) { 3...7 }
175
175
 
176
176
  context "given a value that fits the field exactly" do
177
- let(:value) { "1234" }
177
+ let(:value) { "1234" }
178
178
 
179
179
  it "does not pad the field" do
180
180
  expect(formatted).to eq value
@@ -199,7 +199,7 @@ describe Pikelet::FieldDefinition do
199
199
  let(:padding) { { pad: '<->' } }
200
200
 
201
201
  it "pads the field on the right" do
202
- expect(formatted).to eq "12><"
202
+ expect(formatted).to eq "12<-"
203
203
  end
204
204
  end
205
205
  end
@@ -219,7 +219,7 @@ describe Pikelet::FieldDefinition do
219
219
  let(:padding) { { pad: '<->' } }
220
220
 
221
221
  it "pads the field on the left" do
222
- expect(formatted).to eq "><12"
222
+ expect(formatted).to eq "<-12"
223
223
  end
224
224
  end
225
225
  end
@@ -1,8 +1,89 @@
1
1
  require "spec_helper"
2
2
  require "pikelet"
3
3
 
4
- describe Pikelet::RecordDefiner do
5
- let(:definer) { described_class.new(nil) }
6
- let(:definition) { definer.definition }
4
+ RSpec::Matchers.define :have_field_definition do |name|
5
+ match do |record_definition|
6
+ definition = record_definition.field_definitions[name]
7
+ definition && (!@index || definition.index == @index) && (!@alignment || definition.alignment == @alignment)
8
+ end
9
+
10
+ chain :with_index do |index|
11
+ @index = index
12
+ end
13
+
14
+ chain :with_alignment do |alignment|
15
+ @alignment = alignment
16
+ end
17
+
18
+ description do
19
+ message = "have field definition #{name.inspect}"
20
+ message += " with index #{@index.inspect}" if @index
21
+ message += " with #{@alignment.inspect} alignment" if @alignment
22
+ message
23
+ end
7
24
  end
8
25
 
26
+ describe Pikelet::RecordDefiner do
27
+ let(:file_definition) { Pikelet::FileDefinition.new }
28
+ let(:definer) { described_class.new(file_definition, record_class: nil, base: nil) }
29
+ let(:record_definition) { definer.definition }
30
+
31
+ describe "#field" do
32
+ let(:parser) { ->(v) { v.to_i } }
33
+
34
+ subject(:field) { definer.field(:thing, 0...4, pad: "0", &parser) }
35
+
36
+ its(:index) { is_expected.to eq 0...4 }
37
+ its(:padding) { is_expected.to eq "0" }
38
+ its(:parser) { is_expected.to eq parser }
39
+
40
+ it "adds the field to the record definition" do
41
+ field
42
+ expect(record_definition.field_definitions[:thing]).to be field
43
+ end
44
+ end
45
+
46
+ describe "#record" do
47
+ let(:definition_block) { proc { field(:thing, 1..4) } }
48
+
49
+ subject(:record) { definer.record("NAME", record_class: OpenStruct, &definition_block) }
50
+
51
+ its(:record_class) { is_expected.to be OpenStruct }
52
+
53
+ it "adds the record to the file definition" do
54
+ record
55
+ expect(file_definition.record_definitions["NAME"]).to be record
56
+ end
57
+
58
+ it "evaluates the definition block" do
59
+ expect(record.field_definitions[:thing]).to_not be_nil
60
+ end
61
+ end
62
+
63
+ describe "shorthand field definition" do
64
+ let(:parser) { ->(v) { v.upcase } }
65
+
66
+ subject(:field) { definer.thing(10...20, pad: "-", &parser) }
67
+
68
+ its(:index) { is_expected.to eq 10...20 }
69
+ its(:padding) { is_expected.to eq "-" }
70
+ its(:parser) { is_expected.to eq parser }
71
+
72
+ it "adds the field to the record definition" do
73
+ field
74
+ expect(record_definition.field_definitions[:thing]).to be field
75
+ end
76
+ end
77
+
78
+ describe ".define" do
79
+ subject(:definition) do
80
+ described_class.define(file_definition, record_class: OpenStruct, base: nil) do
81
+ field :thing, 20...30, align: :right
82
+ end
83
+ end
84
+
85
+ its(:record_class) { is_expected.to be OpenStruct }
86
+
87
+ it { is_expected.to have_field_definition(:thing).with_index(20...30).with_alignment(:right) }
88
+ end
89
+ end
@@ -2,12 +2,14 @@ require "spec_helper"
2
2
  require "pikelet"
3
3
 
4
4
  describe Pikelet::RecordDefinition do
5
- let(:definer) { Pikelet::RecordDefiner.new(nil, base: nil) }
5
+ def define_record(&block)
6
+ Pikelet::RecordDefiner.define(nil, base: nil, &block)
7
+ end
6
8
 
7
- let(:data) { "Hello world" }
9
+ let(:data) { "Hello world" }
8
10
 
9
11
  let(:definition) do
10
- definer.define do
12
+ define_record do
11
13
  hello 0... 5
12
14
  world 6...11
13
15
  end
@@ -26,7 +28,7 @@ describe Pikelet::RecordDefinition do
26
28
 
27
29
  context "with contiguous fields" do
28
30
  let(:definition) do
29
- definer.define do
31
+ define_record do
30
32
  hello 0... 5
31
33
  world 6...11
32
34
  end
@@ -39,7 +41,7 @@ describe Pikelet::RecordDefinition do
39
41
 
40
42
  context "with overlapping fields" do
41
43
  let(:definition) do
42
- definer.define do
44
+ define_record do
43
45
  hello 0..6
44
46
  world 4..9
45
47
  end
@@ -52,7 +54,7 @@ describe Pikelet::RecordDefinition do
52
54
 
53
55
  context "with discontinuous fields" do
54
56
  let(:definition) do
55
- definer.define do
57
+ define_record do
56
58
  hello 4... 7
57
59
  world 9...16
58
60
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pikelet
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.0.beta.5
4
+ version: 2.0.0.beta.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - John Carney
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-02-20 00:00:00.000000000 Z
11
+ date: 2015-02-24 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler