ryanwood-slither 0.99.1 → 0.99.2

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.
data/History.txt CHANGED
@@ -1,6 +1,8 @@
1
- == 0.99.0 / 2009-04-14
1
+
2
+ == 0.99.2 / 2009-04-28
2
3
 
3
- * Initial Release
4
+ * Added better support for float formatting
5
+ * Added the money_with_implied_decimal type
4
6
 
5
7
  == 0.99.1 / 2009-04-22
6
8
 
@@ -8,3 +10,7 @@
8
10
  * Prevent duplicate column names
9
11
  * Better error messages
10
12
  * Implement custom padding (spaces (default), zero)
13
+
14
+ == 0.99.0 / 2009-04-14
15
+
16
+ * Initial Release
data/README.rdoc CHANGED
@@ -46,6 +46,8 @@ A simple, clean DSL for describing, writing, and parsing fixed-width text files.
46
46
  end
47
47
  end
48
48
 
49
+ Supported types are: string, integer, date, float, money, and money_with_implied_decimal.
50
+
49
51
  Then either feed it a nested struct with data values to create the file in the defined format:
50
52
 
51
53
  test_data = {
data/Rakefile CHANGED
@@ -24,7 +24,7 @@ PROJ.name = 'slither'
24
24
  PROJ.authors = 'Ryan Wood'
25
25
  PROJ.email = 'ryan.wood@gmail.com'
26
26
  PROJ.url = 'http://github.com/ryanwood/slither'
27
- PROJ.version = '0.99.0'
27
+ PROJ.version = '0.99.2'
28
28
  PROJ.exclude = %w(\.git .gitignore ^tasks \.eprj ^pkg)
29
29
  PROJ.readme_file = 'README.rdoc'
30
30
 
@@ -20,13 +20,15 @@ class Slither
20
20
  "A#{@length}"
21
21
  end
22
22
 
23
- def to_type(value)
23
+ def parse(value)
24
24
  case @type
25
25
  when :integer: value.to_i
26
- when :float: value.to_f
26
+ when :float, :money: value.to_f
27
+ when :money_with_implied_decimal:
28
+ value.to_f / 100
27
29
  when :date:
28
- if @options[:date_format]
29
- Date.strptime(value, @options[:date_format])
30
+ if @options[:format]
31
+ Date.strptime(value, @options[:format])
30
32
  else
31
33
  Date.strptime(value)
32
34
  end
@@ -35,13 +37,15 @@ class Slither
35
37
  end
36
38
 
37
39
  def format(value)
38
- pad(formatter % format_as_string(value))
40
+ pad(formatter % to_s(value))
41
+ rescue
42
+ puts "Could not format column '#{@name}' as a '#{@type}' with formatter '#{formatter}' and value of '#{value}' (formatted: '#{to_s(value)}'). #{$!}"
39
43
  end
40
44
 
41
45
  private
42
46
 
43
47
  def formatter
44
- "%#{aligner}#{sizer}#{typer}"
48
+ "%#{aligner}#{sizer}s"
45
49
  end
46
50
 
47
51
  def aligner
@@ -52,14 +56,6 @@ class Slither
52
56
  (@type == :float && @precision) ? @precision : @length
53
57
  end
54
58
 
55
- def typer
56
- case @type
57
- when :integer: 'd'
58
- when :float: 's'
59
- else 's'
60
- end
61
- end
62
-
63
59
  # Manually apply padding. sprintf only allows padding on numeric fields.
64
60
  def pad(value)
65
61
  return value unless @padding == :zero
@@ -69,19 +65,34 @@ class Slither
69
65
  value.gsub(space[0], '0' * space[0].size)
70
66
  end
71
67
 
72
- def format_as_string(value)
68
+ def to_s(value)
73
69
  result = case @type
74
- when :date:
75
- if @options[:date_format]
76
- value.strftime(@options[:date_format])
70
+ when :date:
71
+ # If it's a DBI::Timestamp object, see if we can convert it to a Time object
72
+ unless value.respond_to?(:strftime)
73
+ value = value.to_time if value.respond_to?(:to_time)
74
+ end
75
+ if value.respond_to?(:strftime)
76
+ if @options[:format]
77
+ value.strftime(@options[:format])
78
+ else
79
+ value.strftime
80
+ end
77
81
  else
78
- value.strftime
82
+ value.to_s
79
83
  end
80
- else value.to_s
84
+ when :float:
85
+ @options[:format] ? @options[:format] % value.to_f : value.to_f.to_s
86
+ when :money:
87
+ "%.2f" % value.to_f
88
+ when :money_with_implied_decimal:
89
+ "%d" % (value.to_f * 100)
90
+ else
91
+ value.to_s
81
92
  end
82
93
  raise(
83
94
  Slither::FormattedStringExceedsLengthError,
84
- "The formatted value '#{result}' exceeds #{@length} chararacters, the allowable length of the '#{@name}' column."
95
+ "The formatted value '#{result}' in column '#{@name}' exceeds the allowed length of #{@length} chararacters."
85
96
  ) if result.length > @length
86
97
  result
87
98
  end
@@ -39,7 +39,10 @@ class Slither
39
39
  end
40
40
 
41
41
  def format(data)
42
- row = ''
42
+ # raise( ColumnMismatchError,
43
+ # "The '#{@name}' section has #{@columns.size} column(s) defined, but there are #{data.size} column(s) provided in the data."
44
+ # ) unless @columns.size == data.size
45
+ row = ''
43
46
  @columns.each do |column|
44
47
  row += column.format(data[column.name])
45
48
  end
@@ -50,7 +53,7 @@ class Slither
50
53
  line_data = line.unpack(unpacker)
51
54
  row = {}
52
55
  @columns.each_with_index do |c, i|
53
- row[c.name] = c.to_type(line_data[i]) unless RESERVED_NAMES.include?(c.name)
56
+ row[c.name] = c.parse(line_data[i]) unless RESERVED_NAMES.include?(c.name)
54
57
  end
55
58
  row
56
59
  end
@@ -6,6 +6,7 @@ class Slither
6
6
  class RequiredSectionNotFoundError < StandardError; end
7
7
  class RequiredSectionEmptyError < StandardError; end
8
8
  class FormattedStringExceedsLengthError < StandardError; end
9
+ class ColumnMismatchError < StandardError; end
9
10
 
10
11
 
11
12
  def self.define(name, options = {}, &block)
data/slither.gemspec CHANGED
Binary file
data/spec/column_spec.rb CHANGED
@@ -60,73 +60,55 @@ describe Slither::Column do
60
60
  it "should return the proper unpack value for a string" do
61
61
  @column.send(:unpacker).should == 'A5'
62
62
  end
63
-
64
- describe "when typing the value" do
63
+
64
+ describe "when parsing a value from a file" do
65
65
  it "should default to a string" do
66
- @column.to_type('name').should == 'name'
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'
67
70
  end
68
-
69
- it "should support the :integer type" do
70
- @column = Slither::Column.new(@name, @length, :type => :integer)
71
- @column.to_type('234').should == 234
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
72
79
  end
73
80
 
74
- it "should support the :float type" do
75
- @column = Slither::Column.new(@name, @length, :type => :float)
76
- @column.to_type('234.45').should == 234.45
77
- end
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
78
95
 
79
- it "should support the :date type" do
80
- @column = Slither::Column.new(@name, @length, :type => :date)
81
- dt = @column.to_type('2009-08-22')
96
+ it "should support the date type" do
97
+ @column = Slither::Column.new(:date, 10, :type => :date)
98
+ dt = @column.parse('2009-08-22')
82
99
  dt.should be_a(Date)
83
100
  dt.to_s.should == '2009-08-22'
84
101
  end
85
102
 
86
- it "should use the :date_format option with :date type if available" do
87
- @column = Slither::Column.new(@name, @length, :type => :date, :date_format => "%m%d%Y")
88
- dt = @column.to_type('08222009')
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')
89
106
  dt.should be_a(Date)
90
107
  dt.to_s.should == '2009-08-22'
91
108
  end
92
109
  end
93
110
 
94
- describe "when getting the column's the value as a string" do
95
- it "should default to a string" do
96
- @column.send(:format_as_string, 'name').should == 'name'
97
- end
98
-
99
- it "should raise an error if the value is longer than the length" do
100
- lambda { @column.send(:format_as_string, 'This string is too long') }.should raise_error(
101
- Slither::FormattedStringExceedsLengthError,
102
- "The formatted value 'This string is too long' exceeds #{@length} chararacters, the allowable length of the '#{@name}' column."
103
- )
104
- end
105
-
106
- it "should support the :integer type" do
107
- @column = Slither::Column.new(@name, @length, :type => :integer)
108
- @column.send(:format_as_string, 234).should == '234'
109
- end
110
-
111
- it "should support the :float type" do
112
- @column = Slither::Column.new(:amount, 6, :type => :float)
113
- @column.send(:format_as_string, 234.45).should == '234.45'
114
- end
115
-
116
- it "should support the :date type" do
117
- dt = Date.new(2009, 8, 22)
118
- @column = Slither::Column.new(:date, 10, :type => :date)
119
- @column.send(:format_as_string, dt).should == '2009-08-22'
120
- end
121
-
122
- it "should use the :date_format option with :date type if available" do
123
- dt = Date.new(2009, 8, 22)
124
- @column = Slither::Column.new(:date, 8, :type => :date, :date_format => "%m%d%Y")
125
- @column.send(:format_as_string, dt).should == '08222009'
126
- end
127
- end
128
-
129
- describe "when formatting a column" do
111
+ describe "when applying formatting options" do
130
112
  it "should return a proper formatter" do
131
113
  @column = Slither::Column.new(@name, @length, :align => :left)
132
114
  @column.send(:formatter).should == "%-5s"
@@ -162,6 +144,68 @@ describe Slither::Column do
162
144
  @column = Slither::Column.new(@name, @length, :type => :float, :padding => :zero, :align => :left)
163
145
  @column.format(4.45).should == '4.450'
164
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
+ it "should raise an error if the value is longer than the length" do
157
+ @value = "XX" * @length
158
+ lambda { @column.format(@value) }.should raise_error(
159
+ Slither::FormattedStringExceedsLengthError,
160
+ "The formatted value '#{@value}' in column '#{@name}' exceeds the allowed length of #{@length} chararacters."
161
+ )
162
+ end
163
+
164
+ it "should support the integer type" do
165
+ @column = Slither::Column.new(:amount, 10, :type => :integer)
166
+ @column.format(234).should == ' 234'
167
+ @column.format('234').should == ' 234'
165
168
  end
169
+
170
+ it "should support the float type" do
171
+ @column = Slither::Column.new(:amount, 10, :type => :float)
172
+ @column.format(234.45).should == ' 234.45'
173
+ @column.format('234.4500').should == ' 234.45'
174
+ @column.format('3').should == ' 3.0'
175
+ end
176
+
177
+ it "should support the float type with a format" do
178
+ @column = Slither::Column.new(:amount, 10, :type => :float, :format => "%.3f")
179
+ @column.format(234.45).should == ' 234.450'
180
+ @column.format('234.4500').should == ' 234.450'
181
+ @column.format('3').should == ' 3.000'
182
+ end
183
+
184
+ it "should support the float type with a format, alignment and padding" do
185
+ @column = Slither::Column.new(:amount, 10, :type => :float, :format => "%.2f", :align => :left, :padding => :zero)
186
+ @column.format(234.45).should == '234.450000'
187
+ @column = Slither::Column.new(:amount, 10, :type => :float, :format => "%.2f", :align => :right, :padding => :zero)
188
+ @column.format('234.400').should == '0000234.40'
189
+ @column = Slither::Column.new(:amount, 10, :type => :float, :format => "%.4f", :align => :left, :padding => :space)
190
+ @column.format('3').should == '3.0000 '
191
+ end
192
+
193
+ it "should support the money_with_implied_decimal type" do
194
+ @column = Slither::Column.new(:amount, 10, :type=> :money_with_implied_decimal)
195
+ @column.format(234.450).should == " 23445"
196
+ @column.format(12.34).should == " 1234"
197
+ end
198
+
199
+ it "should support the date type" do
200
+ dt = Date.new(2009, 8, 22)
201
+ @column = Slither::Column.new(:date, 10, :type => :date)
202
+ @column.format(dt).should == '2009-08-22'
203
+ end
204
+
205
+ it "should support the date type with a :format" do
206
+ dt = Date.new(2009, 8, 22)
207
+ @column = Slither::Column.new(:date, 8, :type => :date, :format => "%m%d%Y")
208
+ @column.format(dt).should == '08222009'
209
+ end
166
210
  end
167
211
  end
data/spec/parser_spec.rb CHANGED
@@ -69,15 +69,6 @@ describe Slither::Parser do
69
69
  lambda { @parser.parse }.should raise_error(Slither::RequiredSectionNotFoundError, "Required section 'header' was not found.")
70
70
  end
71
71
 
72
- it "raise an error if a section limit is over run"
72
+ # it "raise an error if a section limit is over run"
73
73
  end
74
-
75
-
76
-
77
- describe "when in linear mode" do
78
-
79
- end
80
-
81
-
82
-
83
74
  end
data/spec/section_spec.rb CHANGED
@@ -104,6 +104,14 @@ describe Slither::Section do
104
104
  @section.column(:name, 10, :align => :left)
105
105
  @section.format(@data).should == " 3Ryan "
106
106
  end
107
+
108
+ # it "should raise an error if the data and column definitions aren't the same size" do
109
+ # @section.column(:id, 5)
110
+ # lambda { @section.format(@data) }.should raise_error(
111
+ # Slither::ColumnMismatchError,
112
+ # "The 'body' section has 1 column(s) defined, but there are 2 column(s) provided in the data."
113
+ # )
114
+ # end
107
115
  end
108
116
 
109
117
  describe "when parsing a file" do
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ryanwood-slither
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.99.1
4
+ version: 0.99.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ryan Wood
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-04-17 00:00:00 -07:00
12
+ date: 2009-04-28 00:00:00 -07:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -36,7 +36,6 @@ files:
36
36
  - README.rdoc
37
37
  - Rakefile
38
38
  - TODO
39
- - VERSION.yml
40
39
  - lib/slither.rb
41
40
  - lib/slither/column.rb
42
41
  - lib/slither/definition.rb
data/VERSION.yml DELETED
@@ -1,4 +0,0 @@
1
- ---
2
- :minor: 0
3
- :patch: 99
4
- :major: 0