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 +4 -4
- data/lib/pikelet/field_definition.rb +9 -14
- data/lib/pikelet/file_definition.rb +11 -27
- data/lib/pikelet/record_definer.rb +9 -13
- data/lib/pikelet/version.rb +1 -1
- data/spec/pikelet/field_definition_spec.rb +3 -3
- data/spec/pikelet/record_definer_spec.rb +84 -3
- data/spec/pikelet/record_definition_spec.rb +8 -6
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 3087089478a24e533544d4338a8960fe279cf967
|
4
|
+
data.tar.gz: 359ba4f4e47ceb3e5398384aadd8cceea288f005
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
-
|
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
|
-
|
33
|
-
@blank ||= padding * width
|
34
|
-
end
|
37
|
+
attr_reader :align_method
|
35
38
|
|
36
|
-
def
|
37
|
-
value
|
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
|
-
|
8
|
-
|
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
|
12
|
-
|
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 || (
|
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)]
|
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
|
-
|
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] }.
|
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
|
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.
|
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
|
data/lib/pikelet/version.rb
CHANGED
@@ -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)
|
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 "
|
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
|
-
|
5
|
-
|
6
|
-
|
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
|
-
|
5
|
+
def define_record(&block)
|
6
|
+
Pikelet::RecordDefiner.define(nil, base: nil, &block)
|
7
|
+
end
|
6
8
|
|
7
|
-
let(:data)
|
9
|
+
let(:data) { "Hello world" }
|
8
10
|
|
9
11
|
let(:definition) do
|
10
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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.
|
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-
|
11
|
+
date: 2015-02-24 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|