slither 0.99.4 → 0.99.5
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.rspec +3 -0
- data/.rubocop.yml +22 -0
- data/CHANGELOG.md +26 -0
- data/CODE_OF_CONDUCT.md +84 -0
- data/Gemfile +12 -0
- data/Gemfile.lock +63 -0
- data/LICENSE.txt +21 -0
- data/README.md +95 -0
- data/Rakefile +12 -37
- data/TODO +2 -1
- data/lib/slither/column.rb +96 -76
- data/lib/slither/definition.rb +28 -13
- data/lib/slither/generator.rb +46 -26
- data/lib/slither/parser.rb +118 -53
- data/lib/slither/section.rb +39 -21
- data/lib/slither/version.rb +5 -0
- data/lib/slither.rb +68 -7
- data/sig/slither.rbs +4 -0
- metadata +81 -82
- data/History.txt +0 -16
- data/README.rdoc +0 -100
- data/lib/slither/slither.rb +0 -49
- data/slither.gemspec +0 -0
- data/spec/column_spec.rb +0 -224
- data/spec/definition_spec.rb +0 -85
- data/spec/generator_spec.rb +0 -42
- data/spec/parser_spec.rb +0 -74
- data/spec/section_spec.rb +0 -146
- data/spec/slither_spec.rb +0 -84
- data/spec/spec_helper.rb +0 -4
data/README.rdoc
DELETED
@@ -1,100 +0,0 @@
|
|
1
|
-
== slither
|
2
|
-
by Ryan Wood
|
3
|
-
http://ryanwood.com
|
4
|
-
|
5
|
-
== DESCRIPTION:
|
6
|
-
|
7
|
-
A simple, clean DSL for describing, writing, and parsing fixed-width text files.
|
8
|
-
|
9
|
-
== FEATURES:
|
10
|
-
|
11
|
-
* Easy DSL syntax
|
12
|
-
* Can parse and format fixed width files
|
13
|
-
* Templated sections for reuse
|
14
|
-
|
15
|
-
== SYNOPSIS:
|
16
|
-
|
17
|
-
# Create a Slither::Defintion to describe a file format
|
18
|
-
Slither.define :simple do |d|
|
19
|
-
|
20
|
-
# This is a template section that can be reused in other sections
|
21
|
-
d.template :boundary do |t|
|
22
|
-
t.column :record_type, 4
|
23
|
-
t.column :company_id, 12
|
24
|
-
end
|
25
|
-
|
26
|
-
# Create a header section
|
27
|
-
d.header, :align => :left do |header|
|
28
|
-
# The trap tells Slither which lines should fall into this section
|
29
|
-
header.trap { |line| line[0,4] == 'HEAD' }
|
30
|
-
# Use the boundary template for the columns
|
31
|
-
header.template :boundary
|
32
|
-
end
|
33
|
-
|
34
|
-
d.body do |body|
|
35
|
-
body.trap { |line| line[0,4] =~ /[^(HEAD|FOOT)]/ }
|
36
|
-
body.column :id, 10, :type => :integer
|
37
|
-
body.column :name, 10, :align => :left
|
38
|
-
body.spacer 3
|
39
|
-
body.column :state, 2
|
40
|
-
end
|
41
|
-
|
42
|
-
d.footer do |footer|
|
43
|
-
footer.trap { |line| line[0,4] == 'FOOT' }
|
44
|
-
footer.template :boundary
|
45
|
-
footer.column :record_count, 10
|
46
|
-
end
|
47
|
-
end
|
48
|
-
|
49
|
-
Supported types are: string, integer, date, float, money, and money_with_implied_decimal.
|
50
|
-
|
51
|
-
Then either feed it a nested struct with data values to create the file in the defined format:
|
52
|
-
|
53
|
-
test_data = {
|
54
|
-
:body => [
|
55
|
-
{ :id => 12, :name => "Ryan", :state => 'SC' },
|
56
|
-
{ :id => 23, :name => "Joe", :state => 'VA' },
|
57
|
-
{ :id => 42, :name => "Tommy", :state => 'FL' },
|
58
|
-
],
|
59
|
-
:header => { :record_type => 'HEAD', :company_id => 'ABC' },
|
60
|
-
:footer => { :record_type => 'FOOT', :company_id => 'ABC' }
|
61
|
-
}
|
62
|
-
|
63
|
-
# Generates the file as a string
|
64
|
-
puts Slither.generate(:simple, test_data)
|
65
|
-
|
66
|
-
# Writes the file
|
67
|
-
Slither.write('outfile.txt', :simple, test_data)
|
68
|
-
|
69
|
-
or parse files already in that format into a nested hash:
|
70
|
-
|
71
|
-
parsed_data = Slither.parse('infile.txt', :test).inspect
|
72
|
-
|
73
|
-
== INSTALL:
|
74
|
-
|
75
|
-
sudo gem install slither
|
76
|
-
|
77
|
-
== LICENSE:
|
78
|
-
|
79
|
-
(The MIT License)
|
80
|
-
|
81
|
-
Copyright (c) 2008
|
82
|
-
|
83
|
-
Permission is hereby granted, free of charge, to any person obtaining
|
84
|
-
a copy of this software and associated documentation files (the
|
85
|
-
'Software'), to deal in the Software without restriction, including
|
86
|
-
without limitation the rights to use, copy, modify, merge, publish,
|
87
|
-
distribute, sublicense, and/or sell copies of the Software, and to
|
88
|
-
permit persons to whom the Software is furnished to do so, subject to
|
89
|
-
the following conditions:
|
90
|
-
|
91
|
-
The above copyright notice and this permission notice shall be
|
92
|
-
included in all copies or substantial portions of the Software.
|
93
|
-
|
94
|
-
THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
|
95
|
-
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
96
|
-
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
97
|
-
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
98
|
-
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
|
99
|
-
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
100
|
-
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/lib/slither/slither.rb
DELETED
@@ -1,49 +0,0 @@
|
|
1
|
-
class Slither
|
2
|
-
|
3
|
-
VERSION = '0.99.0'
|
4
|
-
|
5
|
-
class DuplicateColumnNameError < StandardError; end
|
6
|
-
class RequiredSectionNotFoundError < StandardError; end
|
7
|
-
class RequiredSectionEmptyError < StandardError; end
|
8
|
-
class FormattedStringExceedsLengthError < StandardError; end
|
9
|
-
class ColumnMismatchError < StandardError; end
|
10
|
-
|
11
|
-
|
12
|
-
def self.define(name, options = {}, &block)
|
13
|
-
definition = Definition.new(options)
|
14
|
-
yield(definition)
|
15
|
-
definitions[name] = definition
|
16
|
-
definition
|
17
|
-
end
|
18
|
-
|
19
|
-
def self.generate(definition_name, data)
|
20
|
-
definition = definition(definition_name)
|
21
|
-
raise ArgumentError, "Definition name '#{name}' was not found." unless definition
|
22
|
-
generator = Generator.new(definition)
|
23
|
-
generator.generate(data)
|
24
|
-
end
|
25
|
-
|
26
|
-
def self.write(filename, definition_name, data)
|
27
|
-
File.open(filename, 'w') do |f|
|
28
|
-
f.write generate(definition_name, data)
|
29
|
-
end
|
30
|
-
end
|
31
|
-
|
32
|
-
def self.parse(filename, definition_name)
|
33
|
-
raise ArgumentError, "File #{filename} does not exist." unless File.exists?(filename)
|
34
|
-
definition = definition(definition_name)
|
35
|
-
raise ArgumentError, "Definition name '#{definition_name}' was not found." unless definition
|
36
|
-
parser = Parser.new(definition, filename)
|
37
|
-
parser.parse
|
38
|
-
end
|
39
|
-
|
40
|
-
private
|
41
|
-
|
42
|
-
def self.definitions
|
43
|
-
@@definitions ||= {}
|
44
|
-
end
|
45
|
-
|
46
|
-
def self.definition(name)
|
47
|
-
definitions[name]
|
48
|
-
end
|
49
|
-
end
|
data/slither.gemspec
DELETED
Binary file
|
data/spec/column_spec.rb
DELETED
@@ -1,224 +0,0 @@
|
|
1
|
-
require File.join(File.dirname(__FILE__), 'spec_helper')
|
2
|
-
|
3
|
-
describe Slither::Column do
|
4
|
-
before(:each) do
|
5
|
-
@name = :id
|
6
|
-
@length = 5
|
7
|
-
@column = Slither::Column.new(@name, @length)
|
8
|
-
end
|
9
|
-
|
10
|
-
describe "when being created" do
|
11
|
-
it "should have a name" do
|
12
|
-
@column.name.should == @name
|
13
|
-
end
|
14
|
-
|
15
|
-
it "should have a length" do
|
16
|
-
@column.length.should == @length
|
17
|
-
end
|
18
|
-
|
19
|
-
it "should have a default padding" do
|
20
|
-
@column.padding.should == :space
|
21
|
-
end
|
22
|
-
|
23
|
-
it "should have a default alignment" do
|
24
|
-
@column.alignment.should == :right
|
25
|
-
end
|
26
|
-
|
27
|
-
it "should return a proper formatter" do
|
28
|
-
@column.send(:formatter).should == "%5s"
|
29
|
-
end
|
30
|
-
end
|
31
|
-
|
32
|
-
describe "when specifying an alignment" do
|
33
|
-
before(:each) do
|
34
|
-
@column = Slither::Column.new(@name, @length, :align => :left)
|
35
|
-
end
|
36
|
-
|
37
|
-
it "should only accept :right or :left for an alignment" do
|
38
|
-
lambda{ Slither::Column.new(@name, @length, :align => :bogus) }.should raise_error(ArgumentError, "Option :align only accepts :right (default) or :left")
|
39
|
-
end
|
40
|
-
|
41
|
-
it "should override the default alignment" do
|
42
|
-
@column.alignment.should == :left
|
43
|
-
end
|
44
|
-
end
|
45
|
-
|
46
|
-
describe "when specifying padding" do
|
47
|
-
before(:each) do
|
48
|
-
@column = Slither::Column.new(@name, @length, :padding => :zero)
|
49
|
-
end
|
50
|
-
|
51
|
-
it "should accept only :space or :zero" do
|
52
|
-
lambda{ Slither::Column.new(@name, @length, :padding => :bogus) }.should raise_error(ArgumentError, "Option :padding only accepts :space (default) or :zero")
|
53
|
-
end
|
54
|
-
|
55
|
-
it "should override the default padding" do
|
56
|
-
@column.padding.should == :zero
|
57
|
-
end
|
58
|
-
end
|
59
|
-
|
60
|
-
it "should return the proper unpack value for a string" do
|
61
|
-
@column.send(:unpacker).should == 'A5'
|
62
|
-
end
|
63
|
-
|
64
|
-
describe "when parsing a value from a file" do
|
65
|
-
it "should default to a string" do
|
66
|
-
@column.parse(' name ').should == 'name'
|
67
|
-
@column.parse(' 234').should == '234'
|
68
|
-
@column.parse('000000234').should == '000000234'
|
69
|
-
@column.parse('12.34').should == '12.34'
|
70
|
-
end
|
71
|
-
|
72
|
-
it "should support the integer type" do
|
73
|
-
@column = Slither::Column.new(:amount, 10, :type=> :integer)
|
74
|
-
@column.parse('234 ').should == 234
|
75
|
-
@column.parse(' 234').should == 234
|
76
|
-
@column.parse('00000234').should == 234
|
77
|
-
@column.parse('Ryan ').should == 0
|
78
|
-
@column.parse('00023.45').should == 23
|
79
|
-
end
|
80
|
-
|
81
|
-
it "should support the float type" do
|
82
|
-
@column = Slither::Column.new(:amount, 10, :type=> :float)
|
83
|
-
@column.parse(' 234.45').should == 234.45
|
84
|
-
@column.parse('234.5600').should == 234.56
|
85
|
-
@column.parse(' 234').should == 234.0
|
86
|
-
@column.parse('00000234').should == 234.0
|
87
|
-
@column.parse('Ryan ').should == 0
|
88
|
-
@column.parse('00023.45').should == 23.45
|
89
|
-
end
|
90
|
-
|
91
|
-
it "should support the money_with_implied_decimal type" do
|
92
|
-
@column = Slither::Column.new(:amount, 10, :type=> :money_with_implied_decimal)
|
93
|
-
@column.parse(' 23445').should == 234.45
|
94
|
-
end
|
95
|
-
|
96
|
-
it "should support the date type" do
|
97
|
-
@column = Slither::Column.new(:date, 10, :type => :date)
|
98
|
-
dt = @column.parse('2009-08-22')
|
99
|
-
dt.should be_a(Date)
|
100
|
-
dt.to_s.should == '2009-08-22'
|
101
|
-
end
|
102
|
-
|
103
|
-
it "should use the format option with date type if available" do
|
104
|
-
@column = Slither::Column.new(:date, 10, :type => :date, :format => "%m%d%Y")
|
105
|
-
dt = @column.parse('08222009')
|
106
|
-
dt.should be_a(Date)
|
107
|
-
dt.to_s.should == '2009-08-22'
|
108
|
-
end
|
109
|
-
end
|
110
|
-
|
111
|
-
describe "when applying formatting options" do
|
112
|
-
it "should return a proper formatter" do
|
113
|
-
@column = Slither::Column.new(@name, @length, :align => :left)
|
114
|
-
@column.send(:formatter).should == "%-5s"
|
115
|
-
end
|
116
|
-
|
117
|
-
it "should respect a right alignment" do
|
118
|
-
@column = Slither::Column.new(@name, @length, :align => :right)
|
119
|
-
@column.format(25).should == ' 25'
|
120
|
-
end
|
121
|
-
|
122
|
-
it "should respect a left alignment" do
|
123
|
-
@column = Slither::Column.new(@name, @length, :align => :left)
|
124
|
-
@column.format(25).should == '25 '
|
125
|
-
end
|
126
|
-
|
127
|
-
it "should respect padding with spaces" do
|
128
|
-
@column = Slither::Column.new(@name, @length, :padding => :space)
|
129
|
-
@column.format(25).should == ' 25'
|
130
|
-
end
|
131
|
-
|
132
|
-
it "should respect padding with zeros with integer types" do
|
133
|
-
@column = Slither::Column.new(@name, @length, :type => :integer, :padding => :zero)
|
134
|
-
@column.format(25).should == '00025'
|
135
|
-
end
|
136
|
-
|
137
|
-
describe "that is a float type" do
|
138
|
-
it "should respect padding with zeros aligned right" do
|
139
|
-
@column = Slither::Column.new(@name, @length, :type => :float, :padding => :zero, :align => :right)
|
140
|
-
@column.format(4.45).should == '04.45'
|
141
|
-
end
|
142
|
-
|
143
|
-
it "should respect padding with zeros aligned left" do
|
144
|
-
@column = Slither::Column.new(@name, @length, :type => :float, :padding => :zero, :align => :left)
|
145
|
-
@column.format(4.45).should == '4.450'
|
146
|
-
end
|
147
|
-
end
|
148
|
-
end
|
149
|
-
|
150
|
-
describe "when formatting values for a file" do
|
151
|
-
it "should default to a string" do
|
152
|
-
@column = Slither::Column.new(:name, 10)
|
153
|
-
@column.format('Bill').should == ' Bill'
|
154
|
-
end
|
155
|
-
|
156
|
-
describe "whose size is too long" do
|
157
|
-
it "should raise an error if truncate is false" do
|
158
|
-
@value = "XX" * @length
|
159
|
-
lambda { @column.format(@value) }.should raise_error(
|
160
|
-
Slither::FormattedStringExceedsLengthError,
|
161
|
-
"The formatted value '#{@value}' in column '#{@name}' exceeds the allowed length of #{@length} chararacters."
|
162
|
-
)
|
163
|
-
end
|
164
|
-
|
165
|
-
it "should truncate from the left if truncate is true and aligned left" do
|
166
|
-
@column = Slither::Column.new(@name, @length, :truncate => true, :align => :left)
|
167
|
-
@column.format("This is too long").should == "This "
|
168
|
-
end
|
169
|
-
|
170
|
-
it "should truncate from the right if truncate is true and aligned right" do
|
171
|
-
@column = Slither::Column.new(@name, @length, :truncate => true, :align => :right)
|
172
|
-
@column.format("This is too long").should == " long"
|
173
|
-
end
|
174
|
-
end
|
175
|
-
|
176
|
-
it "should support the integer type" do
|
177
|
-
@column = Slither::Column.new(:amount, 10, :type => :integer)
|
178
|
-
@column.format(234).should == ' 234'
|
179
|
-
@column.format('234').should == ' 234'
|
180
|
-
end
|
181
|
-
|
182
|
-
it "should support the float type" do
|
183
|
-
@column = Slither::Column.new(:amount, 10, :type => :float)
|
184
|
-
@column.format(234.45).should == ' 234.45'
|
185
|
-
@column.format('234.4500').should == ' 234.45'
|
186
|
-
@column.format('3').should == ' 3.0'
|
187
|
-
end
|
188
|
-
|
189
|
-
it "should support the float type with a format" do
|
190
|
-
@column = Slither::Column.new(:amount, 10, :type => :float, :format => "%.3f")
|
191
|
-
@column.format(234.45).should == ' 234.450'
|
192
|
-
@column.format('234.4500').should == ' 234.450'
|
193
|
-
@column.format('3').should == ' 3.000'
|
194
|
-
end
|
195
|
-
|
196
|
-
it "should support the float type with a format, alignment and padding" do
|
197
|
-
@column = Slither::Column.new(:amount, 10, :type => :float, :format => "%.2f", :align => :left, :padding => :zero)
|
198
|
-
@column.format(234.45).should == '234.450000'
|
199
|
-
@column = Slither::Column.new(:amount, 10, :type => :float, :format => "%.2f", :align => :right, :padding => :zero)
|
200
|
-
@column.format('234.400').should == '0000234.40'
|
201
|
-
@column = Slither::Column.new(:amount, 10, :type => :float, :format => "%.4f", :align => :left, :padding => :space)
|
202
|
-
@column.format('3').should == '3.0000 '
|
203
|
-
end
|
204
|
-
|
205
|
-
it "should support the money_with_implied_decimal type" do
|
206
|
-
@column = Slither::Column.new(:amount, 10, :type=> :money_with_implied_decimal)
|
207
|
-
@column.format(234.450).should == " 23445"
|
208
|
-
@column.format(12.34).should == " 1234"
|
209
|
-
end
|
210
|
-
|
211
|
-
it "should support the date type" do
|
212
|
-
dt = Date.new(2009, 8, 22)
|
213
|
-
@column = Slither::Column.new(:date, 10, :type => :date)
|
214
|
-
@column.format(dt).should == '2009-08-22'
|
215
|
-
end
|
216
|
-
|
217
|
-
it "should support the date type with a :format" do
|
218
|
-
dt = Date.new(2009, 8, 22)
|
219
|
-
@column = Slither::Column.new(:date, 8, :type => :date, :format => "%m%d%Y")
|
220
|
-
@column.format(dt).should == '08222009'
|
221
|
-
end
|
222
|
-
end
|
223
|
-
|
224
|
-
end
|
data/spec/definition_spec.rb
DELETED
@@ -1,85 +0,0 @@
|
|
1
|
-
require File.join(File.dirname(__FILE__), 'spec_helper')
|
2
|
-
|
3
|
-
describe Slither::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 = Slither::Definition.new :align => :right
|
10
|
-
d.options[:align].should == :right
|
11
|
-
end
|
12
|
-
|
13
|
-
it "should default to being right aligned" do
|
14
|
-
d = Slither::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
|
-
Slither::Section.should_receive(:new).with('name', {:align => :left}).and_return(section)
|
21
|
-
d = Slither::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 = Slither::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(Slither::Section)
|
39
|
-
@d.sections.first.should == yielded
|
40
|
-
end
|
41
|
-
|
42
|
-
it "should magically build a section from an unknown method" do
|
43
|
-
Slither::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(ArgumentError)
|
49
|
-
lambda { @d.section(:header) {} }.should raise_error(ArgumentError, "Reserved or duplicate section name: 'header'")
|
50
|
-
end
|
51
|
-
|
52
|
-
it "should throw an error if a reserved section name is used" do
|
53
|
-
lambda { @d.section(:spacer) {} }.should raise_error(ArgumentError, "Reserved or duplicate section name: 'spacer'")
|
54
|
-
end
|
55
|
-
end
|
56
|
-
|
57
|
-
describe "when creating a template" do
|
58
|
-
before(:each) do
|
59
|
-
@d = Slither::Definition.new
|
60
|
-
@section = mock('section', :null_object => true)
|
61
|
-
end
|
62
|
-
|
63
|
-
it "should create a new section" do
|
64
|
-
Slither::Section.should_receive(:new).with(:row, anything()).and_return(@section)
|
65
|
-
@d.template(:row) {}
|
66
|
-
end
|
67
|
-
|
68
|
-
it "should yield the new section" do
|
69
|
-
Slither::Section.should_receive(:new).with(:row, anything()).and_return(@section)
|
70
|
-
yielded = nil
|
71
|
-
@d.template :row do |section|
|
72
|
-
yielded = section
|
73
|
-
end
|
74
|
-
yielded.should == @section
|
75
|
-
end
|
76
|
-
|
77
|
-
it "add a section to the templates collection" do
|
78
|
-
@d.should have(0).templates
|
79
|
-
@d.template :row do |t|
|
80
|
-
t.column :id, 3
|
81
|
-
end
|
82
|
-
@d.should have(1).templates
|
83
|
-
end
|
84
|
-
end
|
85
|
-
end
|
data/spec/generator_spec.rb
DELETED
@@ -1,42 +0,0 @@
|
|
1
|
-
require File.join(File.dirname(__FILE__), 'spec_helper')
|
2
|
-
|
3
|
-
describe Slither::Generator do
|
4
|
-
before(:each) do
|
5
|
-
@definition = Slither.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 = Slither::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(Slither::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
|
-
end
|
data/spec/parser_spec.rb
DELETED
@@ -1,74 +0,0 @@
|
|
1
|
-
require File.join(File.dirname(__FILE__), 'spec_helper')
|
2
|
-
|
3
|
-
describe Slither::Parser do
|
4
|
-
before(:each) do
|
5
|
-
@definition = mock('definition', :sections => [])
|
6
|
-
@file = mock("file", :gets => nil)
|
7
|
-
@file_name = 'test.txt'
|
8
|
-
@parser = Slither::Parser.new(@definition, @file_name)
|
9
|
-
end
|
10
|
-
|
11
|
-
it "should open and yield the source file" do
|
12
|
-
File.should_receive(:open).with(@file_name, 'r').and_yield(@file)
|
13
|
-
@parser.parse
|
14
|
-
end
|
15
|
-
|
16
|
-
describe "when parsing sections" do
|
17
|
-
before(:each) do
|
18
|
-
@definition = Slither.define :test do |d|
|
19
|
-
d.header do |h|
|
20
|
-
h.trap { |line| line[0,4] == 'HEAD' }
|
21
|
-
h.column :type, 4
|
22
|
-
h.column :file_id, 10
|
23
|
-
end
|
24
|
-
d.body do |b|
|
25
|
-
b.trap { |line| line[0,4] =~ /[^(HEAD|FOOT)]/ }
|
26
|
-
b.column :first, 10
|
27
|
-
b.column :last, 10
|
28
|
-
end
|
29
|
-
d.footer do |f|
|
30
|
-
f.trap { |line| line[0,4] == 'FOOT' }
|
31
|
-
f.column :type, 4
|
32
|
-
f.column :file_id, 10
|
33
|
-
end
|
34
|
-
end
|
35
|
-
File.should_receive(:open).with(@file_name, 'r').and_yield(@file)
|
36
|
-
@parser = Slither::Parser.new(@definition, @file_name)
|
37
|
-
end
|
38
|
-
|
39
|
-
it "should add lines to the proper sections" do
|
40
|
-
@file.should_receive(:gets).exactly(4).times.and_return(
|
41
|
-
'HEAD 1',
|
42
|
-
' Paul Hewson',
|
43
|
-
' Dave Evans',
|
44
|
-
'FOOT 1',
|
45
|
-
nil
|
46
|
-
)
|
47
|
-
expected = {
|
48
|
-
:header => [ {:type => "HEAD", :file_id => "1" }],
|
49
|
-
:body => [
|
50
|
-
{:first => "Paul", :last => "Hewson" },
|
51
|
-
{:first => "Dave", :last => "Evans" }
|
52
|
-
],
|
53
|
-
:footer => [ {:type => "FOOT", :file_id => "1" }]
|
54
|
-
}
|
55
|
-
result = @parser.parse
|
56
|
-
result.should == expected
|
57
|
-
end
|
58
|
-
|
59
|
-
it "should allow optional sections to be skipped" do
|
60
|
-
@definition.sections[0].optional = true
|
61
|
-
@definition.sections[2].optional = true
|
62
|
-
@file.should_receive(:gets).twice.and_return(' Paul Hewson', nil)
|
63
|
-
expected = { :body => [ {:first => "Paul", :last => "Hewson" } ] }
|
64
|
-
@parser.parse.should == expected
|
65
|
-
end
|
66
|
-
|
67
|
-
it "should raise an error if a required section is not found" do
|
68
|
-
@file.should_receive(:gets).twice.and_return(' Ryan Wood', nil)
|
69
|
-
lambda { @parser.parse }.should raise_error(Slither::RequiredSectionNotFoundError, "Required section 'header' was not found.")
|
70
|
-
end
|
71
|
-
|
72
|
-
# it "raise an error if a section limit is over run"
|
73
|
-
end
|
74
|
-
end
|