tabular 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 Scott Willson
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README ADDED
@@ -0,0 +1,46 @@
1
+ Tabular is a Ruby library for reading, writing, and manipulating CSV, tab-delimited and Excel data.
2
+
3
+ I extracted it from production code. Still extracting it, actually. I need to read structured data and manipulate it via a common interface before persisting it with ActiveRecord.
4
+
5
+
6
+ Dependencies
7
+ ------------
8
+ For tab-delimited data: Ruby standard lib
9
+ For CSV: FasterCSV
10
+ For Excel: Spreadsheet gem
11
+
12
+
13
+ Examples
14
+ --------
15
+ >> table = Table.read("test/fixtures/sample.csv")
16
+ >> table.rows.size
17
+ => 4
18
+
19
+ Access Table Rows by index:
20
+ >> table[0]
21
+
22
+ And Row cells as a Hash:
23
+ >> table[0][:last_name]
24
+ => "Willson"
25
+
26
+
27
+ Usage
28
+ -----
29
+ Table.read assumes that .txt files are tab-delimited, .csv files are comma-delimited, and .xls files are Excel. It assumes that the first row is the header row, and normalizes the header to lower-case with underscores. E.g., "Last Name" becomes "last_name".
30
+
31
+ Table.new accepts an Array of Arrays.
32
+
33
+ Table.new also accepts an options hash. Currently, :columns is the only option. Examples:
34
+ :city_state => :location -- Maps :city_state column to :location. A column with a "City State" header would be accessed as row[:location]
35
+ :flyer_approved => { :column_type => :boolean } -- Coerce :flyer_approved column cells to booleans.
36
+
37
+
38
+ Tests
39
+ -----
40
+ There's basic test coverage. More comprehensive test coverage needs to be extracted from original projects. Run 'rake test'.
41
+
42
+
43
+ Copyright
44
+ ---------
45
+
46
+ Copyright (c) 2009 Scott Willson. See LICENSE for details.
@@ -0,0 +1,38 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+ begin
5
+ require 'jeweler'
6
+ Jeweler::Tasks.new do |gemspec|
7
+ gemspec.name = "tabular"
8
+ gemspec.summary = "Read, write, and manipulate CSV, tab-delimited and Excel data"
9
+ gemspec.description = "Tabular is a Ruby library for reading, writing, and manipulating CSV, tab-delimited and Excel data."
10
+ gemspec.email = "scott.willson@gmail.cpm"
11
+ gemspec.homepage = "http://github.com/scottwillson/tabular"
12
+ gemspec.authors = ["Scott Willson"]
13
+ end
14
+ Jeweler::GemcutterTasks.new
15
+ rescue LoadError
16
+ puts "Jeweler not available. Install it with: sudo gem install jeweler"
17
+ end
18
+
19
+ require 'rake/testtask'
20
+ Rake::TestTask.new(:test) do |test|
21
+ test.libs << 'lib' << 'test'
22
+ test.pattern = 'test/**/*_test.rb'
23
+ test.verbose = true
24
+ end
25
+
26
+ task :test => :check_dependencies
27
+
28
+ task :default => :test
29
+
30
+ require 'rake/rdoctask'
31
+ Rake::RDocTask.new do |rdoc|
32
+ version = File.exist?('VERSION') ? File.read('VERSION') : ""
33
+
34
+ rdoc.rdoc_dir = 'rdoc'
35
+ rdoc.title = "tabular #{version}"
36
+ rdoc.rdoc_files.include('README*')
37
+ rdoc.rdoc_files.include('lib/**/*.rb')
38
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.0.1
@@ -0,0 +1,10 @@
1
+ require "rubygems"
2
+
3
+ $LOAD_PATH.unshift("#{File.dirname(__FILE__)}/../lib")
4
+
5
+ require "tabular/column.rb"
6
+ require "tabular/columns.rb"
7
+ require "tabular/row.rb"
8
+ require "tabular/table.rb"
9
+
10
+ require "tabular/support/object"
@@ -0,0 +1,50 @@
1
+ module Tabular
2
+ class Column
3
+ attr_reader :key, :column_type
4
+
5
+ def initialize(key = nil, columns_map = {})
6
+ key = symbolize(key)
7
+ columns_map = columns_map || {}
8
+ map_for_key = columns_map[key]
9
+
10
+ @column_type = :string
11
+ case map_for_key
12
+ when nil
13
+ @key = key
14
+ @column_type = :date if key == :date
15
+ when Symbol
16
+ @key = map_for_key
17
+ @column_type = :date if key == :date
18
+ when Hash
19
+ @key = key
20
+ @column_type = map_for_key[:column_type]
21
+ else
22
+ raise "Expected Symbol or Hash, but was #{map_for_key.class}"
23
+ end
24
+ end
25
+
26
+ def symbolize(key)
27
+ return nil if key.blank?
28
+
29
+ begin
30
+ key.to_s.strip.gsub(/::/, '/').
31
+ gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
32
+ gsub(/([a-z\d])([A-Z])/,'\1_\2').
33
+ tr("-", "_").
34
+ gsub(/ +/, "_").
35
+ downcase.
36
+ to_sym
37
+ rescue
38
+ nil
39
+ end
40
+ end
41
+
42
+ def inspect
43
+ "#<Tabular::Column #{key} #{column_type}>"
44
+ end
45
+
46
+ def to_s
47
+ key
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,55 @@
1
+ module Tabular
2
+ # The Table's header: a list of Columns.
3
+ class Columns
4
+ # +data+ -- array of header names
5
+ # +columns_map+ -- see Table. Maps column names and type conversion.
6
+ def initialize(data, columns_map = {})
7
+ @columns_map = columns_map
8
+ @column_indexes = {}
9
+ @columns_by_key = {}
10
+ index = 0
11
+ @columns = nil
12
+ @columns = data.map do |column|
13
+ new_column = Tabular::Column.new(column, columns_map)
14
+ unless new_column.key.blank?
15
+ @column_indexes[new_column.key] = index
16
+ @columns_by_key[new_column.key] = new_column
17
+ end
18
+ index = index + 1
19
+ new_column
20
+ end
21
+ end
22
+
23
+ # Is the a Column with this key? Keys are lower-case, underscore symbols.
24
+ # Example: :postal_code
25
+ def has_key?(key)
26
+ @columns.any? { |column| column.key == key }
27
+ end
28
+
29
+ # Column for +key+
30
+ def [](key)
31
+ @columns_by_key[key]
32
+ end
33
+
34
+ # Zero-based index of Column for +key+
35
+ def index(key)
36
+ @column_indexes[key]
37
+ end
38
+
39
+ # Call +block+ for each Column
40
+ def each(&block)
41
+ @columns.each(&block)
42
+ end
43
+
44
+ # Add a new Column with +key+
45
+ def <<(key)
46
+ column = Column.new(key, @columns_map)
47
+ unless column.key.blank?
48
+ @column_indexes[column.key] = @columns.size
49
+ @column_indexes[@columns.size] = column
50
+ @columns_by_key[column.key] = column
51
+ end
52
+ @columns << column
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,80 @@
1
+ module Tabular
2
+ # Associate list of cells. Each Table has a list of Rows. Access Row cells via symbols. Ex: row[:city]
3
+ class Row
4
+ include Enumerable
5
+
6
+ # +columns+ -- array of string
7
+ # +cell+ -- array (not neccessarily Strings)
8
+ def initialize(columns, cells = [])
9
+ @columns = columns
10
+ @array = cells
11
+ @hash = nil
12
+ end
13
+
14
+ # Cell value by symbol. E.g., row[:phone_number]
15
+ def [](key)
16
+ hash[key]
17
+ end
18
+
19
+ # Set cell value. Adds cell to end of Row and adds new Column if there is no Column fo +key_
20
+ def []=(key, value)
21
+ if @columns.has_key?(key)
22
+ @array[@columns.index(key)] = value
23
+ else
24
+ @array << value
25
+ @columns << key
26
+ end
27
+ hash[key] = value
28
+ end
29
+
30
+ # Call +block+ for each cell
31
+ def each(&block)
32
+ @array.each(&block)
33
+ end
34
+
35
+ # For pretty-printing cell values
36
+ def join(sep = nil)
37
+ @array.join(sep)
38
+ end
39
+
40
+ def to_hash
41
+ hash.dup
42
+ end
43
+
44
+ def inspect
45
+ hash.inspect
46
+ end
47
+
48
+ def to_s
49
+ @array.join(", ").to_s
50
+ end
51
+
52
+
53
+ protected
54
+
55
+
56
+ def hash #:nodoc:
57
+ unless @hash
58
+ @hash = Hash.new
59
+ @columns.each do |column|
60
+ index = @columns.index(column.key)
61
+ if index
62
+ case column.column_type
63
+ when :boolean
64
+ @hash[column.key] = [1, "1", true, "true"].include?(@array[index])
65
+ when :date
66
+ if @array[index].is_a?(Date) || @array[index].is_a?(DateTime) || @array[index].is_a?(Time)
67
+ @hash[column.key] = @array[index]
68
+ else
69
+ @hash[column.key] = Date.parse(@array[index], true)
70
+ end
71
+ else
72
+ @hash[column.key] = @array[index]
73
+ end
74
+ end
75
+ end
76
+ end
77
+ @hash
78
+ end
79
+ end
80
+ end
@@ -0,0 +1,59 @@
1
+ # Copied from Rails' ActiveSupport
2
+ class Object
3
+ # An object is blank if it's false, empty, or a whitespace string.
4
+ # For example, "", " ", +nil+, [], and {} are blank.
5
+ #
6
+ # This simplifies
7
+ #
8
+ # if !address.nil? && !address.empty?
9
+ #
10
+ # to
11
+ #
12
+ # if !address.blank?
13
+ def blank?
14
+ respond_to?(:empty?) ? empty? : !self
15
+ end
16
+
17
+ # An object is present if it's not blank.
18
+ def present?
19
+ !blank?
20
+ end
21
+ end
22
+
23
+ class NilClass #:nodoc:
24
+ def blank?
25
+ true
26
+ end
27
+ end
28
+
29
+ class FalseClass #:nodoc:
30
+ def blank?
31
+ true
32
+ end
33
+ end
34
+
35
+ class TrueClass #:nodoc:
36
+ def blank?
37
+ false
38
+ end
39
+ end
40
+
41
+ class Array #:nodoc:
42
+ alias_method :blank?, :empty?
43
+ end
44
+
45
+ class Hash #:nodoc:
46
+ alias_method :blank?, :empty?
47
+ end
48
+
49
+ class String #:nodoc:
50
+ def blank?
51
+ self !~ /\S/
52
+ end
53
+ end
54
+
55
+ class Numeric #:nodoc:
56
+ def blank?
57
+ false
58
+ end
59
+ end
@@ -0,0 +1,65 @@
1
+ module Tabular
2
+ # Simple Enumerable list of Hashes. Use Table.read(file_path) to read file.
3
+ class Table
4
+ attr_reader :columns, :rows
5
+
6
+ # Assumes .txt = tab-delimited, .csv = CSV, .xls = Excel. Assumes first row is the header.
7
+ # Normalizes column names to lower-case with underscores.
8
+ def self.read(file_path, *options)
9
+ raise "Could not find '#{file_path}'" unless File.exists?(file_path)
10
+
11
+ case File.extname(file_path)
12
+ when ".xls", ".xlsx"
13
+ require "spreadsheet"
14
+ # Row#to_a coerces Excel data to Strings, but we want Dates and Numbers
15
+ data = []
16
+ Spreadsheet.open(file_path).worksheets.first.each do |excel_row|
17
+ data << excel_row.inject([]) { |row, cell| row << cell; row }
18
+ end
19
+ when ".txt"
20
+ require "csv"
21
+ data = ::CSV.open(file_path, "r","\t").collect { |row| row }
22
+ when ".csv"
23
+ require "fastercsv"
24
+ data = FasterCSV.read(file_path)
25
+ end
26
+
27
+ Table.new data, options
28
+ end
29
+
30
+ # Pass data in as +rows+. Expects rows to be an Enumerable of Enumerables.
31
+ # Maps rows to Hash-like Tabular::Rows.
32
+ #
33
+ # Options:
34
+ # :column => { :original_name => :preferred_name, :column_name => { :column_type => :boolean } }
35
+ def initialize(rows = [], *options)
36
+ if options
37
+ options = options.flatten.first || {}
38
+ else
39
+ options = {}
40
+ end
41
+
42
+ rows.each do |row|
43
+ if columns
44
+ @rows << Tabular::Row.new(columns, row)
45
+ else
46
+ @columns = Tabular::Columns.new(row, options[:columns])
47
+ @rows = []
48
+ end
49
+ end
50
+ end
51
+
52
+ # Return Row at zero-based index, or nil if Row is out of bounds
53
+ def [](index)
54
+ rows[index]
55
+ end
56
+
57
+ def inspect
58
+ rows.map { |row| row.join(",") }.join("\n")
59
+ end
60
+
61
+ def to_s
62
+ "#<#{self.class} #{rows.size}>"
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,63 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{tabular}
8
+ s.version = "0.0.1"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Scott Willson"]
12
+ s.date = %q{2009-12-15}
13
+ s.description = %q{Tabular is a Ruby library for reading, writing, and manipulating CSV, tab-delimited and Excel data.}
14
+ s.email = %q{scott.willson@gmail.cpm}
15
+ s.extra_rdoc_files = [
16
+ "LICENSE",
17
+ "README"
18
+ ]
19
+ s.files = [
20
+ "LICENSE",
21
+ "README",
22
+ "Rakefile",
23
+ "VERSION",
24
+ "lib/tabular.rb",
25
+ "lib/tabular/column.rb",
26
+ "lib/tabular/columns.rb",
27
+ "lib/tabular/row.rb",
28
+ "lib/tabular/support/object.rb",
29
+ "lib/tabular/table.rb",
30
+ "tabular.gemspec",
31
+ "test/column_test.rb",
32
+ "test/columns_test.rb",
33
+ "test/fixtures/blank.txt",
34
+ "test/fixtures/excel.xls",
35
+ "test/fixtures/sample.csv",
36
+ "test/helper.rb",
37
+ "test/row_test.rb",
38
+ "test/table_test.rb"
39
+ ]
40
+ s.homepage = %q{http://github.com/scottwillson/tabular}
41
+ s.rdoc_options = ["--charset=UTF-8"]
42
+ s.require_paths = ["lib"]
43
+ s.rubygems_version = %q{1.3.5}
44
+ s.summary = %q{Read, write, and manipulate CSV, tab-delimited and Excel data}
45
+ s.test_files = [
46
+ "test/column_test.rb",
47
+ "test/columns_test.rb",
48
+ "test/helper.rb",
49
+ "test/row_test.rb",
50
+ "test/table_test.rb"
51
+ ]
52
+
53
+ if s.respond_to? :specification_version then
54
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
55
+ s.specification_version = 3
56
+
57
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
58
+ else
59
+ end
60
+ else
61
+ end
62
+ end
63
+
@@ -0,0 +1,39 @@
1
+ require "helper"
2
+
3
+ module Tabular
4
+ class ColumnTest < Test::Unit::TestCase
5
+ def test_new_nil
6
+ column = Column.new
7
+ assert_equal nil, column.to_s, "blank column to_s"
8
+ assert_equal nil, column.key, "blank column key"
9
+ end
10
+
11
+ def test_new
12
+ assert_equal :date, Column.new("date").key, "column key"
13
+ assert_equal :date, Column.new(:date).key, "column key"
14
+ assert_equal :date, Column.new("Date").key, "column key"
15
+ assert_equal :date, Column.new(" Date ").key, "column key"
16
+ assert_equal :date, Column.new("DATE").key, "column key"
17
+ assert_equal :start_date, Column.new("StartDate").key, "column key"
18
+ assert_equal :start_date, Column.new("Start Date").key, "column key"
19
+ end
20
+
21
+ def test_mapping
22
+ assert_equal :city, Column.new(:location, :location => :city).key, "column key"
23
+ end
24
+
25
+ def test_type
26
+ column = Column.new("name")
27
+ assert_equal :name, column.key, "key"
28
+ assert_equal :string, column.column_type, "column_type"
29
+
30
+ column = Column.new("date")
31
+ assert_equal :date, column.key, "key"
32
+ assert_equal :date, column.column_type, "column_type"
33
+
34
+ column = Column.new("phone", :phone => { :column_type => :integer })
35
+ assert_equal :phone, column.key, "key"
36
+ assert_equal :integer, column.column_type, "column_type"
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,64 @@
1
+ require "helper"
2
+
3
+ module Tabular
4
+ class ColumnsTest < Test::Unit::TestCase
5
+ def test_new_blank
6
+ columns = Columns.new([])
7
+ assert_equal false, columns.has_key?(:name), "has_key? :name"
8
+ assert_equal nil, columns[:name], "[:name]"
9
+ assert_equal nil, columns.index(nil), "index"
10
+ assert_equal nil, columns.index(""), "index"
11
+ assert_equal nil, columns.index(:name), "index"
12
+ columns.each { |c| c.nil? }
13
+ end
14
+
15
+ def test_new
16
+ columns = Columns.new(["date", "first name", "LastName"])
17
+ assert_equal false, columns.has_key?(:location), "has_key? :location"
18
+ assert_equal true, columns.has_key?(:date), "has_key? :date"
19
+ assert_equal true, columns.has_key?(:first_name), "has_key? :first_name"
20
+ assert_equal true, columns.has_key?(:last_name), "has_key? :last_name"
21
+ assert_equal false, columns.has_key?("first name"), "has_key? 'first name'"
22
+
23
+ column = columns[:first_name]
24
+ assert_equal :first_name, column.key, "column[:first_name] Column key"
25
+
26
+ assert_equal 1, columns.index(:first_name), "index of :first_name"
27
+ end
28
+
29
+ def test_columns_map
30
+ columns = Columns.new(["date"], :start_date => :date)
31
+ assert_equal true, columns.has_key?(:date), "has_key? :date"
32
+ assert_equal false, columns.has_key?(:start_date), "has_key? :start_date"
33
+ end
34
+
35
+ def test_each
36
+ columns = Columns.new(["date", "first name", "LastName"])
37
+ columns_from_each = []
38
+ columns.each { |c| columns_from_each << c.key }
39
+ assert_equal [ :date, :first_name, :last_name ], columns_from_each, "column keys from #each"
40
+ end
41
+
42
+ def test_push_onto_blank
43
+ columns = Columns.new([])
44
+ columns << "city state"
45
+ assert_equal true, columns.has_key?(:city_state), "has_key? :city_state"
46
+ assert_equal 0, columns.index(:city_state), "index of new column"
47
+
48
+ column = columns[:city_state]
49
+ assert_equal :city_state, column.key, "column[:city_state] Column key"
50
+ end
51
+
52
+ def test_push
53
+ columns = Columns.new(["first", "second"])
54
+ columns << "third"
55
+ assert_equal true, columns.has_key?(:third), "has_key? :third"
56
+ assert_equal 0, columns.index(:first), "index of existing column"
57
+ assert_equal 1, columns.index(:second), "index of existing column"
58
+ assert_equal 2, columns.index(:third), "index of new column"
59
+
60
+ column = columns[:third]
61
+ assert_equal :third, column.key, "column[:third] Column key"
62
+ end
63
+ end
64
+ end
File without changes
Binary file
@@ -0,0 +1,5 @@
1
+ "Place ","Number","Last Name","First Name","Team","Category Raced"
2
+ "1","189","Willson","Scott","Gentle Lover","Senior Men 1/2/3","11",,"11"
3
+ "2","190","Phinney","Harry","CCCP","Senior Men 1/2/3","9",,
4
+ "3","10a","Holland","Steve","Huntair","Senior Men 1/2/3",,"3",
5
+ "dnf","100","Bourcier","Paul","Hutch's","Senior Men 1/2/3",,,"1"
@@ -0,0 +1,9 @@
1
+ require 'rubygems'
2
+ require 'test/unit'
3
+
4
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
5
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
6
+ require 'tabular'
7
+
8
+ class Test::Unit::TestCase
9
+ end
@@ -0,0 +1,57 @@
1
+ require "helper"
2
+
3
+ module Tabular
4
+ class RowTest < Test::Unit::TestCase
5
+ def test_new
6
+ row = Row.new([])
7
+ assert_equal nil, row[:city], "[]"
8
+
9
+ assert_equal "", row.join, "join"
10
+ assert_equal({}, row.to_hash, "to_hash")
11
+ assert_equal "{}", row.inspect, "inspect"
12
+ assert_equal "", row.to_s, "to_s"
13
+
14
+ # Test each
15
+ row.each { |c| c.nil? }
16
+ end
17
+
18
+ def test_set
19
+ columns = Columns.new([ "planet", "star" ])
20
+ row = Row.new(columns, [ "Mars", "Sun" ])
21
+
22
+ assert_equal "Sun", row[:star], "row[:star]"
23
+
24
+ row[:star] = "Solaris"
25
+ assert_equal "Solaris", row[:star], "row[:star]"
26
+
27
+ row[:astronaut] = "Buzz"
28
+ assert_equal "Buzz", row[:astronaut], "row[:astronaut]"
29
+ end
30
+
31
+ def test_join
32
+ columns = Columns.new([ "planet", "star" ])
33
+ row = Row.new(columns, [ "Mars", "Sun" ])
34
+ assert_equal "MarsSun", row.join, "join"
35
+ assert_equal "Mars-Sun", row.join("-"), "join '-'"
36
+ end
37
+
38
+ def test_to_hash
39
+ columns = Columns.new([ "planet", "star" ])
40
+ row = Row.new(columns, [ "Mars", "Sun" ])
41
+ assert_equal({ :planet => "Mars", :star => "Sun"}, row.to_hash, "to_hash")
42
+ end
43
+
44
+ def test_inspect
45
+ columns = Columns.new([ "planet", "star" ])
46
+ row = Row.new(columns, [ "Mars", "Sun" ])
47
+ assert_equal "{:planet=>\"Mars\", :star=>\"Sun\"}", row.inspect, "inspect"
48
+ end
49
+
50
+ def test_to_s
51
+ columns = Columns.new([ "planet", "star" ])
52
+ row = Row.new(columns, [ "Mars", "Sun" ])
53
+ assert_equal "Mars, Sun", row.to_s, "to_s"
54
+ end
55
+ end
56
+ end
57
+
@@ -0,0 +1,37 @@
1
+ require "helper"
2
+
3
+ module Tabular
4
+ class TableTest < Test::Unit::TestCase
5
+ def test_read_from_blank_txt_file
6
+ table = Table.read(File.expand_path(File.dirname(__FILE__) + "/fixtures/blank.txt"))
7
+ end
8
+
9
+ # "Place ","Number","Last Name","First Name","Team","Category Raced"
10
+ # "1","189","Willson","Scott","Gentle Lover","Senior Men 1/2/3","11",,"11"
11
+ # "2","190","Phinney","Harry","CCCP","Senior Men 1/2/3","9",,
12
+ # "3","10a","Holland","Steve","Huntair","Senior Men 1/2/3",,"3",
13
+ # "dnf","100","Bourcier","Paul","Hutch's","Senior Men 1/2/3",,,"1"
14
+ def test_read_from_csv
15
+ table = Table.read(File.expand_path(File.dirname(__FILE__) + "/fixtures/sample.csv"))
16
+ assert_equal 4, table.rows.size, "rows"
17
+
18
+ assert_equal "1", table[0][:place], "0.0"
19
+ assert_equal "189", table[0][:number], "0.1"
20
+ assert_equal "Willson", table[0][:last_name], "0.2"
21
+ assert_equal "Scott", table[0][:first_name], "0.3"
22
+ assert_equal "Gentle Lover", table[0][:team], "0.4"
23
+
24
+ assert_equal "dnf", table[3][:place], "3.0"
25
+ assert_equal "100", table[3][:number], "3.1"
26
+ assert_equal "Bourcier", table[3][:last_name], "3.2"
27
+ assert_equal "Paul", table[3][:first_name], "3.3"
28
+ assert_equal "Hutch's", table[3][:team], "3.4"
29
+ end
30
+
31
+ def test_read_from_excel
32
+ table = Table.read(File.expand_path(File.dirname(__FILE__) + "/fixtures/excel.xls"))
33
+ assert_equal Date.new(2006, 1, 20), table[0][:date], "0.0"
34
+ end
35
+ end
36
+ end
37
+
metadata ADDED
@@ -0,0 +1,78 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: tabular
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Scott Willson
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-12-15 00:00:00 -08:00
13
+ default_executable:
14
+ dependencies: []
15
+
16
+ description: Tabular is a Ruby library for reading, writing, and manipulating CSV, tab-delimited and Excel data.
17
+ email: scott.willson@gmail.cpm
18
+ executables: []
19
+
20
+ extensions: []
21
+
22
+ extra_rdoc_files:
23
+ - LICENSE
24
+ - README
25
+ files:
26
+ - LICENSE
27
+ - README
28
+ - Rakefile
29
+ - VERSION
30
+ - lib/tabular.rb
31
+ - lib/tabular/column.rb
32
+ - lib/tabular/columns.rb
33
+ - lib/tabular/row.rb
34
+ - lib/tabular/support/object.rb
35
+ - lib/tabular/table.rb
36
+ - tabular.gemspec
37
+ - test/column_test.rb
38
+ - test/columns_test.rb
39
+ - test/fixtures/blank.txt
40
+ - test/fixtures/excel.xls
41
+ - test/fixtures/sample.csv
42
+ - test/helper.rb
43
+ - test/row_test.rb
44
+ - test/table_test.rb
45
+ has_rdoc: true
46
+ homepage: http://github.com/scottwillson/tabular
47
+ licenses: []
48
+
49
+ post_install_message:
50
+ rdoc_options:
51
+ - --charset=UTF-8
52
+ require_paths:
53
+ - lib
54
+ required_ruby_version: !ruby/object:Gem::Requirement
55
+ requirements:
56
+ - - ">="
57
+ - !ruby/object:Gem::Version
58
+ version: "0"
59
+ version:
60
+ required_rubygems_version: !ruby/object:Gem::Requirement
61
+ requirements:
62
+ - - ">="
63
+ - !ruby/object:Gem::Version
64
+ version: "0"
65
+ version:
66
+ requirements: []
67
+
68
+ rubyforge_project:
69
+ rubygems_version: 1.3.5
70
+ signing_key:
71
+ specification_version: 3
72
+ summary: Read, write, and manipulate CSV, tab-delimited and Excel data
73
+ test_files:
74
+ - test/column_test.rb
75
+ - test/columns_test.rb
76
+ - test/helper.rb
77
+ - test/row_test.rb
78
+ - test/table_test.rb