tabular 0.0.7 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +5 -0
- data/Gemfile.lock +34 -0
- data/Rakefile +1 -3
- data/VERSION +1 -1
- data/lib/tabular.rb +8 -4
- data/lib/tabular/column.rb +35 -8
- data/lib/tabular/columns.rb +49 -19
- data/lib/tabular/keys.rb +14 -0
- data/lib/tabular/renderer.rb +11 -0
- data/lib/tabular/row.rb +53 -20
- data/lib/tabular/support/zero.rb +29 -0
- data/lib/tabular/table.rb +94 -24
- data/tabular.gemspec +46 -41
- data/test/column_test.rb +59 -18
- data/test/columns_test.rb +39 -14
- data/test/row_test.rb +72 -13
- data/test/table_test.rb +140 -6
- data/test/zero_test.rb +21 -0
- metadata +82 -47
- data/.gitignore +0 -2
data/test/row_test.rb
CHANGED
@@ -5,55 +5,98 @@ module Tabular
|
|
5
5
|
def test_new
|
6
6
|
row = Row.new(Table.new)
|
7
7
|
assert_equal nil, row[:city], "[]"
|
8
|
-
|
8
|
+
|
9
9
|
assert_equal "", row.join, "join"
|
10
10
|
assert_equal({}, row.to_hash, "to_hash")
|
11
11
|
assert_equal "{}", row.inspect, "inspect"
|
12
12
|
assert_equal "", row.to_s, "to_s"
|
13
|
-
|
13
|
+
|
14
|
+
# Test each
|
15
|
+
row.each { |c| c.nil? }
|
16
|
+
end
|
17
|
+
|
18
|
+
def test_new_from_hash
|
19
|
+
row = Row.new(Table.new, { :place => "1" })
|
20
|
+
assert_equal nil, row[:city], "[]"
|
21
|
+
|
22
|
+
assert_equal "1", row.join, "join"
|
23
|
+
assert_equal({ :place => "1" }, row.to_hash, "to_hash")
|
24
|
+
assert_equal "{:place=>\"1\"}", row.inspect, "inspect"
|
25
|
+
assert_equal "1", row.to_s, "to_s"
|
26
|
+
|
27
|
+
# Test each
|
28
|
+
row.each { |c| c.nil? }
|
29
|
+
end
|
30
|
+
|
31
|
+
def test_new_from_hash_with_string_keys
|
32
|
+
row = Row.new(Table.new, { "place" => "1" })
|
33
|
+
assert_equal nil, row[:city], "[]"
|
34
|
+
|
35
|
+
assert_equal "1", row.join, "join"
|
36
|
+
assert_equal({ :place => "1" }, row.to_hash, "to_hash")
|
37
|
+
assert_equal "{:place=>\"1\"}", row.inspect, "inspect"
|
38
|
+
assert_equal "1", row.to_s, "to_s"
|
39
|
+
|
14
40
|
# Test each
|
15
41
|
row.each { |c| c.nil? }
|
42
|
+
|
43
|
+
assert_equal({ "place" => "1" }, row.source, "source")
|
16
44
|
end
|
17
|
-
|
45
|
+
|
18
46
|
def test_set
|
19
47
|
table = Table.new([[ "planet", "star" ]])
|
20
48
|
row = Row.new(table, [ "Mars", "Sun" ])
|
21
|
-
|
49
|
+
|
22
50
|
assert_equal "Sun", row[:star], "row[:star]"
|
23
|
-
|
51
|
+
|
24
52
|
row[:star] = "Solaris"
|
25
53
|
assert_equal "Solaris", row[:star], "row[:star]"
|
26
|
-
|
54
|
+
|
27
55
|
row[:astronaut] = "Buzz"
|
28
56
|
assert_equal "Buzz", row[:astronaut], "row[:astronaut]"
|
29
57
|
end
|
30
|
-
|
58
|
+
|
31
59
|
def test_join
|
32
60
|
table = Table.new([[ "planet", "star" ]])
|
33
61
|
row = Row.new(table, [ "Mars", "Sun" ])
|
34
62
|
assert_equal "MarsSun", row.join, "join"
|
35
63
|
assert_equal "Mars-Sun", row.join("-"), "join '-'"
|
36
64
|
end
|
37
|
-
|
65
|
+
|
38
66
|
def test_to_hash
|
39
67
|
table = Table.new([[ "planet", "star" ]])
|
40
68
|
row = Row.new(table, [ "Mars", "Sun" ])
|
41
69
|
assert_equal({ :planet => "Mars", :star => "Sun"}, row.to_hash, "to_hash")
|
42
70
|
end
|
43
|
-
|
71
|
+
|
44
72
|
def test_inspect
|
45
73
|
table = Table.new([[ "planet", "star" ]])
|
46
74
|
row = Row.new(table, [ "Mars", "Sun" ])
|
47
75
|
assert_match %r{:planet=>"Mars"}, row.inspect, "inspect"
|
48
76
|
assert_match %r{:star=>"Sun"}, row.inspect, "inspect"
|
49
77
|
end
|
50
|
-
|
78
|
+
|
51
79
|
def test_to_s
|
52
80
|
table = Table.new([[ "planet", "star" ]])
|
53
81
|
row = Row.new(table, [ "Mars", "Sun" ])
|
54
82
|
assert_equal "Mars, Sun", row.to_s, "to_s"
|
55
83
|
end
|
56
|
-
|
84
|
+
|
85
|
+
def test_render
|
86
|
+
table = Table.new([[ "planet", "star" ]])
|
87
|
+
table.renderers[:planet] = StarRenderer
|
88
|
+
row = Row.new(table, [ "Mars", "Sun" ])
|
89
|
+
assert_equal "****", row.render("planet"), "render"
|
90
|
+
assert_equal "****", row.render(:planet), "render"
|
91
|
+
assert_equal "****", row.render(row.columns.first), "render"
|
92
|
+
end
|
93
|
+
|
94
|
+
def test_render_with_no_renderer
|
95
|
+
table = Table.new([[ "planet", "star" ]])
|
96
|
+
row = Row.new(table, [ "Mars", "Sun" ])
|
97
|
+
assert_equal "Mars", row.render("planet"), "render"
|
98
|
+
end
|
99
|
+
|
57
100
|
def test_previous
|
58
101
|
table = Table.new([[ "planet", "star" ]])
|
59
102
|
table << [ "Mars", "Sun" ]
|
@@ -61,7 +104,17 @@ module Tabular
|
|
61
104
|
assert_equal nil, table.rows.first.previous, "previous of first Row"
|
62
105
|
assert_equal "Mars", table.rows.last.previous[:planet], "previous"
|
63
106
|
end
|
64
|
-
|
107
|
+
|
108
|
+
def test_each_with_key
|
109
|
+
table = Table.new([[ "planet", "star" ]])
|
110
|
+
table << [ "Mars", "Sun" ]
|
111
|
+
results = []
|
112
|
+
table.rows.first.each_with_key do |key, value|
|
113
|
+
results << [ key, value ]
|
114
|
+
end
|
115
|
+
assert_equal [ [ :planet, "Mars" ], [ :star, "Sun" ] ], results
|
116
|
+
end
|
117
|
+
|
65
118
|
def test_invalid_date_raises_exception
|
66
119
|
table = Table.new([[ "launched" ]], :columns => { :launched => { :column_type => :date } })
|
67
120
|
row = Row.new(table, [ "99/z/99" ])
|
@@ -69,13 +122,19 @@ module Tabular
|
|
69
122
|
row[:launched]
|
70
123
|
end
|
71
124
|
end
|
72
|
-
|
125
|
+
|
73
126
|
def test_parse_compact_american_dates
|
74
127
|
table = Table.new([[ "launched" ]], :columns => { :launched => { :column_type => :date } })
|
75
128
|
assert_equal Date.new(1999, 1, 1), Row.new(table, [ "1/1/99" ])[:launched], "1/1/99"
|
76
129
|
assert_equal Date.new(2000, 8, 28), Row.new(table, [ "8/28/00" ])[:launched], "8/28/00"
|
77
130
|
assert_equal Date.new(2008, 12, 31), Row.new(table, [ "12/31/08" ])[:launched], "12/31/08"
|
78
131
|
end
|
132
|
+
|
133
|
+
class StarRenderer
|
134
|
+
def self.render(column, row)
|
135
|
+
row[column.key].gsub(/\w/, "*")
|
136
|
+
end
|
137
|
+
end
|
79
138
|
end
|
80
139
|
end
|
81
140
|
|
data/test/table_test.rb
CHANGED
@@ -5,11 +5,11 @@ module Tabular
|
|
5
5
|
def test_read_from_blank_txt_file
|
6
6
|
Table.read(File.expand_path(File.dirname(__FILE__) + "/fixtures/blank.txt"))
|
7
7
|
end
|
8
|
-
|
8
|
+
|
9
9
|
def test_read_quoted_txt_file
|
10
10
|
Table.read(File.expand_path(File.dirname(__FILE__) + "/fixtures/quoted.txt"))
|
11
11
|
end
|
12
|
-
|
12
|
+
|
13
13
|
# "Place ","Number","Last Name","First Name","Team","Category Raced"
|
14
14
|
# "1","189","Willson","Scott","Gentle Lover","Senior Men 1/2/3","11",,"11"
|
15
15
|
# "2","190","Phinney","Harry","CCCP","Senior Men 1/2/3","9",,
|
@@ -31,22 +31,22 @@ module Tabular
|
|
31
31
|
assert_equal "Paul", table[3][:first_name], "3.3"
|
32
32
|
assert_equal "Hutch's", table[3][:team], "3.4"
|
33
33
|
end
|
34
|
-
|
34
|
+
|
35
35
|
def test_read_from_excel
|
36
36
|
table = Table.read(File.expand_path(File.dirname(__FILE__) + "/fixtures/excel.xls"))
|
37
37
|
assert_equal Date.new(2006, 1, 20), table[0][:date], "0.0"
|
38
38
|
end
|
39
|
-
|
39
|
+
|
40
40
|
def test_read_from_excel_file
|
41
41
|
table = Table.read(File.new(File.expand_path(File.dirname(__FILE__) + "/fixtures/excel.xls")))
|
42
42
|
assert_equal Date.new(2006, 1, 20), table[0][:date], "0.0"
|
43
43
|
end
|
44
|
-
|
44
|
+
|
45
45
|
def test_read_as
|
46
46
|
table = Table.read(File.expand_path(File.dirname(__FILE__) + "/fixtures/sample.lif"), :as => :csv)
|
47
47
|
assert_equal 4, table.rows.size, "rows"
|
48
48
|
end
|
49
|
-
|
49
|
+
|
50
50
|
def test_column_map
|
51
51
|
data = [
|
52
52
|
[ "nom", "equipe", "homme" ],
|
@@ -57,5 +57,139 @@ module Tabular
|
|
57
57
|
assert_equal "Team Z", table.rows.first[:team], ":team"
|
58
58
|
assert_equal true, table.rows.first[:homme], "boolean"
|
59
59
|
end
|
60
|
+
|
61
|
+
def test_new_with_hashes
|
62
|
+
data = [
|
63
|
+
{ :place => "1", :name => "Bernard Hinault" },
|
64
|
+
{ :place => "2", :name => "Greg Lemond" }
|
65
|
+
]
|
66
|
+
table = Table.new(data)
|
67
|
+
assert_equal 2, table.rows.size, "size"
|
68
|
+
assert_equal data[0], table.rows[0].to_hash
|
69
|
+
assert_equal data[1], table.rows[1].to_hash
|
70
|
+
end
|
71
|
+
|
72
|
+
def test_row_mapper_class_method
|
73
|
+
data = [
|
74
|
+
[ :place, "1", :name, "Bernard Hinault" ],
|
75
|
+
]
|
76
|
+
|
77
|
+
table = Table.new
|
78
|
+
table.row_mapper = StatelessTestMapper
|
79
|
+
table.rows = data
|
80
|
+
|
81
|
+
assert_equal 1, table.rows.size, "size"
|
82
|
+
assert_equal({ :place => "1", :name => "Bernard Hinault" }, table.rows[0].to_hash)
|
83
|
+
end
|
84
|
+
|
85
|
+
def test_row_mapper
|
86
|
+
data = [
|
87
|
+
[ :place, "1", :name, "Bernard Hinault" ],
|
88
|
+
]
|
89
|
+
|
90
|
+
table = Table.new
|
91
|
+
table.row_mapper = TestMapper.new
|
92
|
+
table.rows = data
|
93
|
+
|
94
|
+
assert_equal 1, table.rows.size, "size"
|
95
|
+
assert_equal({ :place => "1", :name => "Bernard Hinault" }, table.rows[0].to_hash)
|
96
|
+
end
|
97
|
+
|
98
|
+
def test_delete_blank_columns
|
99
|
+
data = [
|
100
|
+
[ "nom", "equipe", "homme", "age" ],
|
101
|
+
[ "Hinault", "", "true", "0" ]
|
102
|
+
]
|
103
|
+
|
104
|
+
table = Table.new
|
105
|
+
table.rows = data
|
106
|
+
|
107
|
+
table.delete_blank_columns!
|
108
|
+
|
109
|
+
assert_equal 1, table.rows.size, "size"
|
110
|
+
assert_equal({ :nom => "Hinault", :homme => "true" }, table.rows[0].to_hash)
|
111
|
+
end
|
112
|
+
|
113
|
+
def test_delete_blank_columns_empty_table
|
114
|
+
Table.new.delete_blank_columns!
|
115
|
+
end
|
116
|
+
|
117
|
+
def test_delete_homogenous_columns
|
118
|
+
Table.new.delete_homogenous_columns!
|
119
|
+
|
120
|
+
data = [
|
121
|
+
[ "nom", "equipe", "homme", "age" ],
|
122
|
+
[ "Hinault", "", "true", "30" ],
|
123
|
+
[ "Lemond", "", "true", "20" ],
|
124
|
+
[ "Hinault", "", "true", "30" ]
|
125
|
+
]
|
126
|
+
|
127
|
+
table = Table.new
|
128
|
+
table.rows = data
|
129
|
+
|
130
|
+
table.delete_homogenous_columns!
|
131
|
+
|
132
|
+
assert_equal 3, table.rows.size, "size"
|
133
|
+
assert_equal({ :nom => "Hinault", :age => "30" }, table.rows[0].to_hash)
|
134
|
+
assert_equal({ :nom => "Lemond", :age => "20" }, table.rows[1].to_hash)
|
135
|
+
assert_equal({ :nom => "Hinault", :age => "30" }, table.rows[2].to_hash)
|
136
|
+
end
|
137
|
+
|
138
|
+
def test_delete_homogenous_columns_single_row
|
139
|
+
Table.new.delete_homogenous_columns!
|
140
|
+
|
141
|
+
data = [
|
142
|
+
[ "nom", "equipe", "homme", "age" ],
|
143
|
+
[ "Hinault", "", "true", "30" ],
|
144
|
+
]
|
145
|
+
|
146
|
+
table = Table.new
|
147
|
+
table.rows = data
|
148
|
+
|
149
|
+
table.delete_homogenous_columns!
|
150
|
+
|
151
|
+
assert_equal 1, table.rows.size, "size"
|
152
|
+
assert_equal({ :nom => "Hinault", :equipe => "", :homme => "true", :age => "30" }, table.rows[0].to_hash)
|
153
|
+
end
|
154
|
+
|
155
|
+
def test_delete_column
|
156
|
+
data = [
|
157
|
+
{ :place => "1", :name => "Bernard Hinault" },
|
158
|
+
{ :place => "2", :name => "Greg Lemond" }
|
159
|
+
]
|
160
|
+
table = Table.new(data)
|
161
|
+
|
162
|
+
table.delete_column :place
|
163
|
+
|
164
|
+
assert_equal 2, table.rows.size, "size"
|
165
|
+
assert_equal({ :name => "Bernard Hinault" }, table.rows[0].to_hash)
|
166
|
+
assert_equal({ :name => "Greg Lemond" }, table.rows[1].to_hash)
|
167
|
+
end
|
168
|
+
|
169
|
+
def test_strip
|
170
|
+
data = [
|
171
|
+
{ :name => " Bernard Hinault " }
|
172
|
+
]
|
173
|
+
table = Table.new(data)
|
174
|
+
|
175
|
+
assert_equal 1, table.rows.size, "size"
|
176
|
+
assert_equal({ :name => " Bernard Hinault " }, table.rows[0].to_hash)
|
177
|
+
|
178
|
+
table.strip!
|
179
|
+
|
180
|
+
assert_equal({ :name => "Bernard Hinault" }, table.rows[0].to_hash)
|
181
|
+
end
|
182
|
+
|
183
|
+
class StatelessTestMapper
|
184
|
+
def self.map(array)
|
185
|
+
Hash[*array]
|
186
|
+
end
|
187
|
+
end
|
188
|
+
|
189
|
+
class TestMapper
|
190
|
+
def map(array)
|
191
|
+
Hash[*array]
|
192
|
+
end
|
193
|
+
end
|
60
194
|
end
|
61
195
|
end
|
data/test/zero_test.rb
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
require "helper"
|
2
|
+
|
3
|
+
class ZeroTest < Test::Unit::TestCase
|
4
|
+
def test_zero
|
5
|
+
assert 0.zero?
|
6
|
+
assert (0.0).zero?
|
7
|
+
assert "0".zero?
|
8
|
+
assert "0.0".zero?
|
9
|
+
assert "00000.00000".zero?
|
10
|
+
|
11
|
+
assert !(1.zero?)
|
12
|
+
assert !(-1.zero?)
|
13
|
+
assert !((0.1).zero?)
|
14
|
+
assert !("1".zero?)
|
15
|
+
assert !("ABC".zero?)
|
16
|
+
assert !(nil.zero?)
|
17
|
+
assert !("".zero?)
|
18
|
+
assert !(false.zero?)
|
19
|
+
assert !(true.zero?)
|
20
|
+
end
|
21
|
+
end
|
metadata
CHANGED
@@ -1,34 +1,75 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: tabular
|
3
|
-
version: !ruby/object:Gem::Version
|
4
|
-
prerelease:
|
5
|
-
|
6
|
-
- 0
|
7
|
-
- 0
|
8
|
-
- 7
|
9
|
-
version: 0.0.7
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease:
|
5
|
+
version: 0.2.0
|
10
6
|
platform: ruby
|
11
|
-
authors:
|
7
|
+
authors:
|
12
8
|
- Scott Willson
|
13
9
|
autorequire:
|
14
10
|
bindir: bin
|
15
11
|
cert_chain: []
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
12
|
+
date: 2013-05-05 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: ruby-ole
|
16
|
+
prerelease: false
|
17
|
+
requirement: !ruby/object:Gem::Requirement
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
none: false
|
23
|
+
type: :runtime
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
requirements:
|
26
|
+
- - ! '>='
|
27
|
+
- !ruby/object:Gem::Version
|
28
|
+
version: '0'
|
29
|
+
none: false
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: spreadsheet
|
32
|
+
prerelease: false
|
33
|
+
requirement: !ruby/object:Gem::Requirement
|
34
|
+
requirements:
|
35
|
+
- - ! '>='
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '0'
|
38
|
+
none: false
|
39
|
+
type: :runtime
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
requirements:
|
42
|
+
- - ! '>='
|
43
|
+
- !ruby/object:Gem::Version
|
44
|
+
version: '0'
|
45
|
+
none: false
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: jeweler
|
48
|
+
prerelease: false
|
49
|
+
requirement: !ruby/object:Gem::Requirement
|
50
|
+
requirements:
|
51
|
+
- - ! '>='
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '0'
|
54
|
+
none: false
|
55
|
+
type: :runtime
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
requirements:
|
58
|
+
- - ! '>='
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
version: '0'
|
61
|
+
none: false
|
62
|
+
description: Tabular is a Ruby library for reading, writing, and manipulating CSV,
|
63
|
+
tab-delimited and Excel data.
|
22
64
|
email: scott.willson@gmail.cpm
|
23
65
|
executables: []
|
24
|
-
|
25
66
|
extensions: []
|
26
|
-
|
27
|
-
extra_rdoc_files:
|
67
|
+
extra_rdoc_files:
|
28
68
|
- LICENSE
|
29
69
|
- README
|
30
|
-
files:
|
31
|
-
-
|
70
|
+
files:
|
71
|
+
- Gemfile
|
72
|
+
- Gemfile.lock
|
32
73
|
- LICENSE
|
33
74
|
- README
|
34
75
|
- Rakefile
|
@@ -36,8 +77,11 @@ files:
|
|
36
77
|
- lib/tabular.rb
|
37
78
|
- lib/tabular/column.rb
|
38
79
|
- lib/tabular/columns.rb
|
80
|
+
- lib/tabular/keys.rb
|
81
|
+
- lib/tabular/renderer.rb
|
39
82
|
- lib/tabular/row.rb
|
40
83
|
- lib/tabular/support/object.rb
|
84
|
+
- lib/tabular/support/zero.rb
|
41
85
|
- lib/tabular/table.rb
|
42
86
|
- tabular.gemspec
|
43
87
|
- test/column_test.rb
|
@@ -50,41 +94,32 @@ files:
|
|
50
94
|
- test/helper.rb
|
51
95
|
- test/row_test.rb
|
52
96
|
- test/table_test.rb
|
53
|
-
|
97
|
+
- test/zero_test.rb
|
54
98
|
homepage: http://github.com/scottwillson/tabular
|
55
99
|
licenses: []
|
56
|
-
|
57
100
|
post_install_message:
|
58
|
-
rdoc_options:
|
59
|
-
|
60
|
-
require_paths:
|
101
|
+
rdoc_options: []
|
102
|
+
require_paths:
|
61
103
|
- lib
|
62
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
segments:
|
104
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
105
|
+
requirements:
|
106
|
+
- - ! '>='
|
107
|
+
- !ruby/object:Gem::Version
|
108
|
+
hash: -1721544850789134153
|
109
|
+
segments:
|
68
110
|
- 0
|
69
|
-
version:
|
70
|
-
|
111
|
+
version: '0'
|
112
|
+
none: false
|
113
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - ! '>='
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0'
|
71
118
|
none: false
|
72
|
-
requirements:
|
73
|
-
- - ">="
|
74
|
-
- !ruby/object:Gem::Version
|
75
|
-
segments:
|
76
|
-
- 0
|
77
|
-
version: "0"
|
78
119
|
requirements: []
|
79
|
-
|
80
120
|
rubyforge_project:
|
81
|
-
rubygems_version: 1.
|
121
|
+
rubygems_version: 1.8.25
|
82
122
|
signing_key:
|
83
123
|
specification_version: 3
|
84
124
|
summary: Read, write, and manipulate CSV, tab-delimited and Excel data
|
85
|
-
test_files:
|
86
|
-
- test/column_test.rb
|
87
|
-
- test/columns_test.rb
|
88
|
-
- test/helper.rb
|
89
|
-
- test/row_test.rb
|
90
|
-
- test/table_test.rb
|
125
|
+
test_files: []
|