fixed_width-multibyte 0.2.2
Sign up to get free protection for your applications and to get access to all the features.
- data/COPYING +10 -0
- data/HISTORY +17 -0
- data/README.markdown +149 -0
- data/Rakefile +49 -0
- data/TODO +7 -0
- data/VERSION +1 -0
- data/examples/readme_example.rb +62 -0
- data/fixed_width-multibyte.gemspec +69 -0
- data/fixed_width.gemspec +76 -0
- data/lib/fixed_width.rb +14 -0
- data/lib/fixed_width/column.rb +86 -0
- data/lib/fixed_width/core_ext/symbol.rb +17 -0
- data/lib/fixed_width/definition.rb +31 -0
- data/lib/fixed_width/fixed_width.rb +84 -0
- data/lib/fixed_width/generator.rb +20 -0
- data/lib/fixed_width/parser.rb +47 -0
- data/lib/fixed_width/section.rb +90 -0
- data/spec/column_spec.rb +205 -0
- data/spec/definition_spec.rb +81 -0
- data/spec/fixed_width_spec.rb +81 -0
- data/spec/generator_spec.rb +48 -0
- data/spec/parser_spec.rb +110 -0
- data/spec/section_spec.rb +188 -0
- data/spec/spec_helper.rb +4 -0
- metadata +98 -0
@@ -0,0 +1,81 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), 'spec_helper')
|
2
|
+
|
3
|
+
describe FixedWidth::Definition do
|
4
|
+
before(:each) do
|
5
|
+
end
|
6
|
+
|
7
|
+
describe "when specifying alignment" do
|
8
|
+
it "should have an alignment option" do
|
9
|
+
d = FixedWidth::Definition.new :align => :right
|
10
|
+
d.options[:align].should == :right
|
11
|
+
end
|
12
|
+
|
13
|
+
it "should default to being right aligned" do
|
14
|
+
d = FixedWidth::Definition.new
|
15
|
+
d.options[:align].should == :right
|
16
|
+
end
|
17
|
+
|
18
|
+
it "should override the default if :align is passed to the section" do
|
19
|
+
section = mock('section', :null_object => true)
|
20
|
+
FixedWidth::Section.should_receive(:new).with('name', {:align => :left}).and_return(section)
|
21
|
+
d = FixedWidth::Definition.new
|
22
|
+
d.options[:align].should == :right
|
23
|
+
d.section('name', :align => :left) {}
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
describe "when creating a section" do
|
28
|
+
before(:each) do
|
29
|
+
@d = FixedWidth::Definition.new
|
30
|
+
@section = mock('section', :null_object => true)
|
31
|
+
end
|
32
|
+
|
33
|
+
it "should create and yield a new section object" do
|
34
|
+
yielded = nil
|
35
|
+
@d.section :header do |section|
|
36
|
+
yielded = section
|
37
|
+
end
|
38
|
+
yielded.should be_a(FixedWidth::Section)
|
39
|
+
@d.sections.first.should == yielded
|
40
|
+
end
|
41
|
+
|
42
|
+
it "should magically build a section from an unknown method" do
|
43
|
+
FixedWidth::Section.should_receive(:new).with(:header, anything()).and_return(@section)
|
44
|
+
@d.header {}
|
45
|
+
end
|
46
|
+
|
47
|
+
it "should not create duplicate section names" do
|
48
|
+
lambda { @d.section(:header) {} }.should_not raise_error(FixedWidth::DuplicateSectionNameError)
|
49
|
+
lambda { @d.section(:header) {} }.should raise_error(FixedWidth::DuplicateSectionNameError, "Duplicate section name: 'header'")
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
describe "when creating a template" do
|
54
|
+
before(:each) do
|
55
|
+
@d = FixedWidth::Definition.new
|
56
|
+
@section = mock('section', :null_object => true)
|
57
|
+
end
|
58
|
+
|
59
|
+
it "should create a new section" do
|
60
|
+
FixedWidth::Section.should_receive(:new).with(:row, anything()).and_return(@section)
|
61
|
+
@d.template(:row) {}
|
62
|
+
end
|
63
|
+
|
64
|
+
it "should yield the new section" do
|
65
|
+
FixedWidth::Section.should_receive(:new).with(:row, anything()).and_return(@section)
|
66
|
+
yielded = nil
|
67
|
+
@d.template :row do |section|
|
68
|
+
yielded = section
|
69
|
+
end
|
70
|
+
yielded.should == @section
|
71
|
+
end
|
72
|
+
|
73
|
+
it "add a section to the templates collection" do
|
74
|
+
@d.should have(0).templates
|
75
|
+
@d.template :row do |t|
|
76
|
+
t.column :id, 3
|
77
|
+
end
|
78
|
+
@d.should have(1).templates
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
@@ -0,0 +1,81 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), 'spec_helper')
|
2
|
+
|
3
|
+
describe FixedWidth do
|
4
|
+
|
5
|
+
before(:each) do
|
6
|
+
@name = :doc
|
7
|
+
@options = { :align => :left }
|
8
|
+
end
|
9
|
+
|
10
|
+
describe "when defining a format" do
|
11
|
+
before(:each) do
|
12
|
+
@definition = mock('definition')
|
13
|
+
end
|
14
|
+
|
15
|
+
it "should create a new definition using the specified name and options" do
|
16
|
+
FixedWidth.should_receive(:define).with(@name, @options).and_return(@definition)
|
17
|
+
FixedWidth.define(@name , @options)
|
18
|
+
end
|
19
|
+
|
20
|
+
it "should pass the definition to the block" do
|
21
|
+
yielded = nil
|
22
|
+
FixedWidth.define(@name) do |y|
|
23
|
+
yielded = y
|
24
|
+
end
|
25
|
+
yielded.should be_a( FixedWidth::Definition )
|
26
|
+
end
|
27
|
+
|
28
|
+
it "should add to the internal definition count" do
|
29
|
+
FixedWidth.definitions.clear
|
30
|
+
FixedWidth.should have(0).definitions
|
31
|
+
FixedWidth.define(@name , @options) {}
|
32
|
+
FixedWidth.should have(1).definitions
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
describe "when creating file from data" do
|
37
|
+
it "should raise an error if the definition name is not found" do
|
38
|
+
lambda { FixedWidth.generate(:not_there, {}) }.should raise_error(ArgumentError)
|
39
|
+
end
|
40
|
+
|
41
|
+
it "should output a string" do
|
42
|
+
definition = mock('definition')
|
43
|
+
generator = mock('generator')
|
44
|
+
generator.should_receive(:generate).with({})
|
45
|
+
FixedWidth.should_receive(:definition).with(:test).and_return(definition)
|
46
|
+
FixedWidth::Generator.should_receive(:new).with(definition).and_return(generator)
|
47
|
+
FixedWidth.generate(:test, {})
|
48
|
+
end
|
49
|
+
|
50
|
+
it "should output a file" do
|
51
|
+
file = mock('file')
|
52
|
+
text = mock('string')
|
53
|
+
file.should_receive(:write).with(text)
|
54
|
+
FixedWidth.should_receive(:generate).with(:test, {}).and_return(text)
|
55
|
+
FixedWidth.write(file, :test, {})
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
describe "when parsing a file" do
|
60
|
+
before(:each) do
|
61
|
+
@file = mock('file')
|
62
|
+
end
|
63
|
+
|
64
|
+
it "should check the file exists" do
|
65
|
+
lambda { FixedWidth.parse(@file, :test, {}) }.should raise_error(ArgumentError)
|
66
|
+
end
|
67
|
+
|
68
|
+
it "should raise an error if the definition name is not found" do
|
69
|
+
FixedWidth.definitions.clear
|
70
|
+
lambda { FixedWidth.parse(@file, :test, {}) }.should raise_error(ArgumentError)
|
71
|
+
end
|
72
|
+
|
73
|
+
it "should create a parser and call parse" do
|
74
|
+
parser = mock("parser", :null_object => true)
|
75
|
+
definition = mock('definition')
|
76
|
+
FixedWidth.should_receive(:definition).with(:test).and_return(definition)
|
77
|
+
FixedWidth::Parser.should_receive(:new).with(definition, @file).and_return(parser)
|
78
|
+
FixedWidth.parse(@file, :test)
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), 'spec_helper')
|
2
|
+
|
3
|
+
describe FixedWidth::Generator do
|
4
|
+
before(:each) do
|
5
|
+
@definition = FixedWidth.define :test do |d|
|
6
|
+
d.header do |h|
|
7
|
+
h.trap { |line| line[0,4] == 'HEAD' }
|
8
|
+
h.column :type, 4
|
9
|
+
h.column :file_id, 10
|
10
|
+
end
|
11
|
+
d.body do |b|
|
12
|
+
b.trap { |line| line[0,4] =~ /[^(HEAD|FOOT)]/ }
|
13
|
+
b.column :first, 10
|
14
|
+
b.column :last, 10
|
15
|
+
end
|
16
|
+
d.footer do |f|
|
17
|
+
f.trap { |line| line[0,4] == 'FOOT' }
|
18
|
+
f.column :type, 4
|
19
|
+
f.column :file_id, 10
|
20
|
+
end
|
21
|
+
end
|
22
|
+
@data = {
|
23
|
+
:header => [ {:type => "HEAD", :file_id => "1" } ],
|
24
|
+
:body => [
|
25
|
+
{:first => "Paul", :last => "Hewson" },
|
26
|
+
{:first => "Dave", :last => "Evans" }
|
27
|
+
],
|
28
|
+
:footer => [ {:type => "FOOT", :file_id => "1" }]
|
29
|
+
}
|
30
|
+
@generator = FixedWidth::Generator.new(@definition)
|
31
|
+
end
|
32
|
+
|
33
|
+
it "should raise an error if there is no data for a required section" do
|
34
|
+
@data.delete :header
|
35
|
+
lambda { @generator.generate(@data) }.should raise_error(FixedWidth::RequiredSectionEmptyError, "Required section 'header' was empty.")
|
36
|
+
end
|
37
|
+
|
38
|
+
it "should generate a string" do
|
39
|
+
expected = "HEAD 1\n Paul Hewson\n Dave Evans\nFOOT 1"
|
40
|
+
@generator.generate(@data).should == expected
|
41
|
+
end
|
42
|
+
|
43
|
+
it "should handle lazy data declaration (no array around single record for a section)" do
|
44
|
+
expected = "HEAD 1\n Paul Hewson\n Dave Evans\nFOOT 1"
|
45
|
+
@data[:header] = @data[:header].first
|
46
|
+
@generator.generate(@data).should == expected
|
47
|
+
end
|
48
|
+
end
|
data/spec/parser_spec.rb
ADDED
@@ -0,0 +1,110 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), 'spec_helper')
|
2
|
+
|
3
|
+
describe FixedWidth::Parser do
|
4
|
+
before(:each) do
|
5
|
+
@definition = mock('definition', :sections => [])
|
6
|
+
@file = mock("file")
|
7
|
+
@parser = FixedWidth::Parser.new(@definition, @file)
|
8
|
+
end
|
9
|
+
|
10
|
+
it "should read in a source file" do
|
11
|
+
@file.should_receive(:readlines).and_return(["\n"])
|
12
|
+
@parser.parse
|
13
|
+
end
|
14
|
+
|
15
|
+
describe "when parsing sections" do
|
16
|
+
before(:each) do
|
17
|
+
@definition = FixedWidth.define :test do |d|
|
18
|
+
d.header do |h|
|
19
|
+
h.trap { |line| line[0,4] == 'HEAD' }
|
20
|
+
h.column :type, 4
|
21
|
+
h.column :file_id, 10
|
22
|
+
end
|
23
|
+
d.body do |b|
|
24
|
+
b.trap { |line| line[0,4] =~ /[^(HEAD|FOOT)]/ }
|
25
|
+
b.column :first, 10
|
26
|
+
b.column :last, 10
|
27
|
+
end
|
28
|
+
d.footer do |f|
|
29
|
+
f.trap { |line| line[0,4] == 'FOOT' }
|
30
|
+
f.column :type, 4
|
31
|
+
f.column :file_id, 10
|
32
|
+
end
|
33
|
+
end
|
34
|
+
@parser = FixedWidth::Parser.new(@definition, @file)
|
35
|
+
end
|
36
|
+
|
37
|
+
it "should add lines to the proper sections" do
|
38
|
+
@file.should_receive(:readlines).and_return([
|
39
|
+
"HEAD 1\n",
|
40
|
+
" Paul Hewson\n",
|
41
|
+
" Dave Evans\n",
|
42
|
+
"FOOT 1\n"
|
43
|
+
])
|
44
|
+
expected = {
|
45
|
+
:header => [ {:type => "HEAD", :file_id => "1" } ],
|
46
|
+
:body => [
|
47
|
+
{:first => "Paul", :last => "Hewson" },
|
48
|
+
{:first => "Dave", :last => "Evans" }
|
49
|
+
],
|
50
|
+
:footer => [ {:type => "FOOT", :file_id => "1" } ]
|
51
|
+
}
|
52
|
+
result = @parser.parse
|
53
|
+
result.should == expected
|
54
|
+
end
|
55
|
+
|
56
|
+
it "should treat singular sections properly" do
|
57
|
+
@definition = FixedWidth.define :test do |d|
|
58
|
+
d.header(:singular => true) do |h|
|
59
|
+
h.trap { |line| line[0,4] == 'HEAD' }
|
60
|
+
h.column :type, 4
|
61
|
+
h.column :file_id, 10
|
62
|
+
end
|
63
|
+
d.body do |b|
|
64
|
+
b.trap { |line| line[0,4] =~ /[^(HEAD|FOOT)]/ }
|
65
|
+
b.column :first, 10
|
66
|
+
b.column :last, 10
|
67
|
+
end
|
68
|
+
d.footer(:singular => true) do |f|
|
69
|
+
f.trap { |line| line[0,4] == 'FOOT' }
|
70
|
+
f.column :type, 4
|
71
|
+
f.column :file_id, 10
|
72
|
+
end
|
73
|
+
end
|
74
|
+
@parser = FixedWidth::Parser.new(@definition, @file)
|
75
|
+
@file.should_receive(:readlines).and_return([
|
76
|
+
"HEAD 1\n",
|
77
|
+
" Paul Hewson\n",
|
78
|
+
" Dave Evans\n",
|
79
|
+
"FOOT 1\n"
|
80
|
+
])
|
81
|
+
expected = {
|
82
|
+
:header => {:type => "HEAD", :file_id => "1" },
|
83
|
+
:body => [
|
84
|
+
{:first => "Paul", :last => "Hewson" },
|
85
|
+
{:first => "Dave", :last => "Evans" }
|
86
|
+
],
|
87
|
+
:footer => {:type => "FOOT", :file_id => "1" }
|
88
|
+
}
|
89
|
+
result = @parser.parse
|
90
|
+
result.should == expected
|
91
|
+
end
|
92
|
+
|
93
|
+
it "should allow optional sections to be skipped" do
|
94
|
+
@definition.sections[0].optional = true
|
95
|
+
@definition.sections[2].optional = true
|
96
|
+
@file.should_receive(:readlines).and_return([
|
97
|
+
" Paul Hewson\n"
|
98
|
+
])
|
99
|
+
expected = { :body => [ {:first => "Paul", :last => "Hewson" } ] }
|
100
|
+
@parser.parse.should == expected
|
101
|
+
end
|
102
|
+
|
103
|
+
it "should raise an error if a required section is not found" do
|
104
|
+
@file.should_receive(:readlines).and_return([
|
105
|
+
" Ryan Wood\n"
|
106
|
+
])
|
107
|
+
lambda { @parser.parse }.should raise_error(FixedWidth::RequiredSectionNotFoundError, "Required section 'header' was not found.")
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
@@ -0,0 +1,188 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require File.join(File.dirname(__FILE__), 'spec_helper')
|
3
|
+
|
4
|
+
describe FixedWidth::Section do
|
5
|
+
before(:each) do
|
6
|
+
@section = FixedWidth::Section.new(:body)
|
7
|
+
end
|
8
|
+
|
9
|
+
it "should have no columns after creation" do
|
10
|
+
@section.columns.should be_empty
|
11
|
+
end
|
12
|
+
|
13
|
+
describe "when adding columns" do
|
14
|
+
it "should build an ordered column list" do
|
15
|
+
@section.should have(0).columns
|
16
|
+
|
17
|
+
col1 = @section.column :id, 10
|
18
|
+
col2 = @section.column :name, 30
|
19
|
+
col3 = @section.column :state, 2
|
20
|
+
|
21
|
+
@section.should have(3).columns
|
22
|
+
@section.columns[0].should be(col1)
|
23
|
+
@section.columns[1].should be(col2)
|
24
|
+
@section.columns[2].should be(col3)
|
25
|
+
end
|
26
|
+
|
27
|
+
it "should create spacer columns" do
|
28
|
+
@section.should have(0).columns
|
29
|
+
@section.spacer(5)
|
30
|
+
@section.should have(1).columns
|
31
|
+
end
|
32
|
+
|
33
|
+
it "can should override the alignment of the definition" do
|
34
|
+
section = FixedWidth::Section.new('name', :align => :left)
|
35
|
+
section.options[:align].should == :left
|
36
|
+
end
|
37
|
+
|
38
|
+
it "should use a missing method to create a column" do
|
39
|
+
@section.should have(0).columns
|
40
|
+
@section.first_name 5
|
41
|
+
@section.should have(1).columns
|
42
|
+
end
|
43
|
+
|
44
|
+
it "should prevent duplicate column names without any groupings" do
|
45
|
+
@section.column :id, 10
|
46
|
+
lambda { @section.column(:id, 30) }.should raise_error(FixedWidth::DuplicateColumnNameError, /column named 'id'/)
|
47
|
+
end
|
48
|
+
|
49
|
+
it "should prevent column names that already exist as groups" do
|
50
|
+
@section.column :foo, 11, :group => :id
|
51
|
+
lambda { @section.column(:id, 30) }.should raise_error(FixedWidth::DuplicateGroupNameError, /group named 'id'/)
|
52
|
+
end
|
53
|
+
|
54
|
+
it "should prevent group names that already exist as columns" do
|
55
|
+
@section.column :foo, 11
|
56
|
+
lambda { @section.column(:id, 30, :group => :foo) }.should raise_error(FixedWidth::DuplicateGroupNameError, /column named 'foo'/)
|
57
|
+
end
|
58
|
+
|
59
|
+
it "should prevent duplicate column names within groups" do
|
60
|
+
@section.column :id, 10, :group => :foo
|
61
|
+
lambda { @section.column(:id, 30, :group => :foo) }.should raise_error(FixedWidth::DuplicateColumnNameError, /column named 'id' in the ':foo' group/)
|
62
|
+
end
|
63
|
+
|
64
|
+
it "should allow duplicate column names in different groups" do
|
65
|
+
@section.column :id, 10, :group => :foo
|
66
|
+
lambda { @section.column(:id, 30, :group => :bar) }.should_not raise_error(FixedWidth::DuplicateColumnNameError)
|
67
|
+
end
|
68
|
+
|
69
|
+
it "should allow duplicate column names that are reserved (i.e. spacer)" do
|
70
|
+
@section.spacer 10
|
71
|
+
lambda { @section.spacer 10 }.should_not raise_error(FixedWidth::DuplicateColumnNameError)
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
it "should accept and store the trap as a block" do
|
76
|
+
@section.trap { |v| v == 4 }
|
77
|
+
trap = @section.instance_variable_get(:@trap)
|
78
|
+
trap.should be_a(Proc)
|
79
|
+
trap.call(4).should == true
|
80
|
+
end
|
81
|
+
|
82
|
+
describe "when adding a template" do
|
83
|
+
before(:each) do
|
84
|
+
@template = mock('templated section', :columns => [1,2,3], :options => {})
|
85
|
+
@definition = mock("definition", :templates => { :test => @template } )
|
86
|
+
@section.definition = @definition
|
87
|
+
end
|
88
|
+
|
89
|
+
it "should ensure the template exists" do
|
90
|
+
@definition.stub! :templates => {}
|
91
|
+
lambda { @section.template(:none) }.should raise_error(ArgumentError)
|
92
|
+
end
|
93
|
+
|
94
|
+
it "should add the template columns to the current column list" do
|
95
|
+
@section.template :test
|
96
|
+
@section.should have(3).columns
|
97
|
+
end
|
98
|
+
|
99
|
+
it "should merge the template option" do
|
100
|
+
@section = FixedWidth::Section.new(:body, :align => :left)
|
101
|
+
@section.definition = @definition
|
102
|
+
@template.stub! :options => {:align => :right}
|
103
|
+
@section.template :test
|
104
|
+
@section.options.should == {:align => :left}
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
describe "when formatting a row" do
|
109
|
+
before(:each) do
|
110
|
+
@data = { :id => 3, :name => "Ryan" }
|
111
|
+
end
|
112
|
+
|
113
|
+
it "should default to string data aligned right" do
|
114
|
+
@section.column(:id, 5)
|
115
|
+
@section.column(:name, 10)
|
116
|
+
@section.format( @data ).should == " 3 Ryan"
|
117
|
+
end
|
118
|
+
|
119
|
+
it "should left align if asked" do
|
120
|
+
@section.column(:id, 5)
|
121
|
+
@section.column(:name, 10, :align => :left)
|
122
|
+
@section.format(@data).should == " 3Ryan "
|
123
|
+
end
|
124
|
+
|
125
|
+
it "should read from groups" do
|
126
|
+
@data = { :id => 3, :foo => { :name => "Ryan" } }
|
127
|
+
@section.column(:id, 5)
|
128
|
+
@section.column(:name, 10, :align => :left, :group => :foo)
|
129
|
+
@section.format(@data).should == " 3Ryan "
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
describe "when parsing a file" do
|
134
|
+
before(:each) do
|
135
|
+
@line = ' 45 Ryan WoódSC '
|
136
|
+
@section = FixedWidth::Section.new(:body)
|
137
|
+
@column_content = { :id => 5, :first => 10, :last => 10, :state => 2 }
|
138
|
+
end
|
139
|
+
|
140
|
+
it "should return a key for key column" do
|
141
|
+
@column_content.each { |k,v| @section.column(k, v) }
|
142
|
+
parsed = @section.parse(@line)
|
143
|
+
@column_content.each_key { |name| parsed.should have_key(name) }
|
144
|
+
end
|
145
|
+
|
146
|
+
it "should not return a key for reserved names" do
|
147
|
+
@column_content.each { |k,v| @section.column(k, v) }
|
148
|
+
@section.spacer 5
|
149
|
+
@section.should have(5).columns
|
150
|
+
parsed = @section.parse(@line)
|
151
|
+
parsed.should have(4).keys
|
152
|
+
end
|
153
|
+
|
154
|
+
it "should break columns into groups" do
|
155
|
+
@section.column(:id, 5)
|
156
|
+
@section.column(:first, 10, :group => :name)
|
157
|
+
@section.column(:last, 10, :group => :name)
|
158
|
+
@section.column(:state, 2, :group => :address)
|
159
|
+
@section.spacer 5
|
160
|
+
@section.should have(5).columns
|
161
|
+
parsed = @section.parse(@line)
|
162
|
+
parsed.should have(3).keys
|
163
|
+
parsed[:id].should == '45'
|
164
|
+
parsed[:name][:first].should == 'Ryan'
|
165
|
+
parsed[:name][:last].should == 'Woód'
|
166
|
+
parsed[:address][:state].should == 'SC'
|
167
|
+
end
|
168
|
+
|
169
|
+
it "should not die if a field is not in range" do
|
170
|
+
@section.column(:a, 5)
|
171
|
+
@section.column(:b, 5)
|
172
|
+
@section.column(:c, 5)
|
173
|
+
line = ' 45'
|
174
|
+
parsed = @section.parse(line)
|
175
|
+
parsed[:a].should == '45'
|
176
|
+
parsed[:b].should == ''
|
177
|
+
parsed[:c].should == ''
|
178
|
+
end
|
179
|
+
end
|
180
|
+
|
181
|
+
it "should try to match a line using the trap" do
|
182
|
+
@section.trap do |line|
|
183
|
+
line == 'hello'
|
184
|
+
end
|
185
|
+
@section.match('hello').should be_true
|
186
|
+
@section.match('goodbye').should be_false
|
187
|
+
end
|
188
|
+
end
|