sheets 0.9.0

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/.gitignore ADDED
@@ -0,0 +1,6 @@
1
+ .DS_Store
2
+ *.gem
3
+ .bundle
4
+ Gemfile.lock
5
+ pkg/*
6
+ doc/*
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in sheets.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,19 @@
1
+ Copyright (c) 2011 Bradley J. Spaulding
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ of this software and associated documentation files (the "Software"), to deal
5
+ in the Software without restriction, including without limitation the rights
6
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ copies of the Software, and to permit persons to whom the Software is
8
+ furnished to do so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in
11
+ all copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,92 @@
1
+ Sheets
2
+ ==========
3
+
4
+ Sheets is a Facade on top of many spreadsheet formats, presenting them as simple, unified, native ruby arrays. It is intended to allow applications to easily import data from a wide variety of spreadsheet formats.
5
+
6
+ With Sheets, all cell values are strings representing the final, evaluated value of the cell.
7
+
8
+ This does mean that, in some cases, you will be casting data back into its native format.
9
+
10
+ However, this eliminates the need to deal with multiple spreadsheet formats and normalize data types in your application logic.
11
+
12
+ Your application only needs to care about the layout of the spreadsheet, and the format *you* want the data in.
13
+
14
+ Usage
15
+ ----------
16
+
17
+ To retrieve a list of parseable spreadsheet formats at runtime:
18
+
19
+ Sheets::Base.parseable_formats # => ["csv", "xls", "xlsx", "ods"]
20
+
21
+ To open a spreadsheet, pass initialize Sheets::Base.new either a file path:
22
+
23
+ Sheets::Base.new( '/path/to/a/spreadsheet.(format)' )
24
+
25
+ or a file handle:
26
+
27
+ Sheets::Base.new( File.open('/path/to/a/spreadsheet.(format)') )
28
+
29
+ By default, Sheets will use the basename of the file to detect the spreadsheet type. You can override this by passing in the :format option:
30
+
31
+ *This is necessary if you pass Sheets an IO object, like StringIO, that doesn't have metadata like a filename/path.*
32
+
33
+ Sheets::Base.new( an_io_object_with_spreadsheet_data, :format => :xls )
34
+
35
+ Once you have imported a sheet, you can either grab the array:
36
+
37
+ sheet = Sheets::Base.new( # ... )
38
+ sheet.to_array
39
+
40
+ or utilize any of the Enumerable functions on the sheet:
41
+
42
+ sheet = Sheets::Base.new( # ... )
43
+ sheet.collect {|row| puts row }
44
+
45
+ Additionally, you may output the sheet in any of the renderable formats:
46
+
47
+ Sheets::Base.renderable_formats # => ['csv', 'xls']
48
+ sheet = Sheets::Base.new( file )
49
+ sheet.to_csv
50
+ sheet.to_xls
51
+
52
+ Sheets::Base will skip the parsing phase if initialized with an array, allowing you to render arrays to a native spreadsheet format:
53
+
54
+ my_awesome_data = [ ["Date", "Spent", "Earned"], ["2011-04-11", "$0.00", "$5,000.00"] ]
55
+ sheet = Sheets::Base.new( my_awesome_data )
56
+ sheet.to_csv
57
+ sheet.to_xls
58
+
59
+ Adding Parsers
60
+ ------------
61
+
62
+ Parsers subclass Sheets::Parsers::Base, live in the Sheets::Parsers namespace and should respond to two methods:
63
+
64
+ * formats: returns an array of string format names (file extensions) that this parser class supports
65
+ * to_array: returns a simple array representation of the spreadsheet.
66
+
67
+ Parsers have access to @data and @format in order to do their parsing. See lib/sheets/parsers/* for examples.
68
+
69
+ Adding Renderers
70
+ ------------
71
+
72
+ Renderers subclass Sheets::Renderers::Base, live in the Sheets::Renderers namespace and should respond to:
73
+
74
+ * formats: returns an array of string format names that this parser class supports
75
+ * to\_#{format}: For each format that a renderer supports, it should respond to "to\_#{format}", returning the file data of that format.
76
+
77
+ Renderers are given access to the results of Sheets::Base#to_array as @data. See lib/sheets/renderers/* for examples.
78
+
79
+ License
80
+ ----------
81
+
82
+ Sheets is licensed under the [MIT License](http://www.opensource.org/licenses/mit-license.php).
83
+
84
+ Please note that Sheets is dependent upon the Spreadsheet gem, which is licensed under the [GPLv3](http://www.opensource.org/licenses/gpl-3.0.html).
85
+
86
+ Credits
87
+ ----------
88
+
89
+ Sheets takes full advantage of the great work done in these gems:
90
+
91
+ * [Spreadsheet](http://spreadsheet.rubyforge.org/) - mhatakeyama@ywesee.com, zdavatz@ywesee.com
92
+ * [Roo](http://roo.rubyforge.org/) - [Thomas Preymesser](mailto:thopre@gmail.com)
data/Rakefile ADDED
@@ -0,0 +1,7 @@
1
+ require 'bundler'
2
+ Bundler::GemHelper.install_tasks
3
+
4
+ task :test do
5
+ require File.join(File.expand_path(File.dirname(__FILE__)), 'test', 'test_helper.rb')
6
+ Dir[ File.join(File.expand_path(File.dirname(__FILE__)), 'test', '**', '*_test.rb') ].each {|file| require file }
7
+ end
data/lib/sheets.rb ADDED
@@ -0,0 +1,21 @@
1
+ module Sheets
2
+ module Parsers; end
3
+ module Renderers; end
4
+
5
+ class UnsupportedSpreadsheetFormatError < StandardError; end
6
+ end
7
+
8
+ lib_path = File.expand_path(File.dirname(__FILE__))
9
+
10
+ # Load Parsers
11
+ require File.join lib_path, 'sheets', 'parseable.rb'
12
+ require File.join lib_path, 'sheets', 'parsers', 'base.rb'
13
+ Dir[ File.join lib_path, 'sheets', 'parsers', '*_parser.rb' ].each {|file| require file }
14
+
15
+ # Load Renderers
16
+ require File.join lib_path, 'sheets', 'renderable.rb'
17
+ require File.join lib_path, 'sheets', 'renderers', 'base.rb'
18
+ Dir[ File.join lib_path, 'sheets', 'renderers', '*_renderer.rb' ].each {|file| require file }
19
+
20
+ # Load Sheets::Base
21
+ require File.join lib_path, 'sheets', 'base.rb'
@@ -0,0 +1,28 @@
1
+ module Sheets
2
+ class Base
3
+ include Parseable
4
+ include Renderable
5
+
6
+ def initialize(file, options = {})
7
+ if file.is_a?(Array)
8
+ @data = file
9
+ @extension = options[:format].to_s
10
+ return
11
+ end
12
+
13
+ file = File.open(file.to_s) unless file.respond_to? :read
14
+ options[:format] ||= File.basename(file.path || "").split('.')[-1]
15
+
16
+ @data = file.read
17
+ @extension = options[:format].to_s
18
+ @file_path = File.expand_path(file.path || "")
19
+
20
+ raise UnsupportedSpreadsheetFormatError, "Couldn't find a parser for the '#{@extension}' format." if parser.nil?
21
+ end
22
+
23
+ alias_method :default_to_array, :to_array
24
+ def to_array
25
+ @data.is_a?(Array) ? @data : default_to_array
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,39 @@
1
+ module Sheets
2
+ module Parseable
3
+ include Enumerable
4
+
5
+ def self.included(base)
6
+ base.extend(ClassMethods)
7
+ end
8
+
9
+ module ClassMethods
10
+ def parseable_formats
11
+ Sheets::Parsers.constants.collect {|constant_name| Sheets::Parsers.const_get(constant_name) }.map(&:formats).flatten.uniq
12
+ end
13
+ end
14
+
15
+ def each
16
+ to_array.each {|row| yield row }
17
+ end
18
+
19
+ def to_array
20
+ parser.send(:to_array)
21
+ end
22
+
23
+ private
24
+ def parser_class
25
+ classes = Sheets::Parsers.constants.map do |constant_name|
26
+ constant = Sheets::Parsers.const_get(constant_name)
27
+ constant if constant && constant.respond_to?(:formats) && constant.formats.map(&:to_s).include?(@extension)
28
+ end
29
+
30
+ classes.delete(nil)
31
+
32
+ classes.first
33
+ end
34
+
35
+ def parser
36
+ @parser ||= parser_class.new(@data, @extension, @file_path) unless parser_class.nil?
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,23 @@
1
+ class Sheets::Parsers::Base
2
+ def initialize(data, format, file_path)
3
+ @data = data
4
+ @format = format
5
+ @file_path = file_path
6
+ end
7
+
8
+ def io
9
+ StringIO.new(@data)
10
+ end
11
+
12
+ def self.parses(*args)
13
+ self.formats = args.map(&:to_s)
14
+ end
15
+
16
+ def self.formats
17
+ @formats ||= []
18
+ end
19
+
20
+ def self.formats=(new_formats)
21
+ @formats = new_formats
22
+ end
23
+ end
@@ -0,0 +1,9 @@
1
+ require 'csv'
2
+
3
+ class Sheets::Parsers::CSVParser < Sheets::Parsers::Base
4
+ parses :csv
5
+
6
+ def to_array
7
+ CSV.parse( @data )
8
+ end
9
+ end
@@ -0,0 +1,28 @@
1
+ require 'roo'
2
+
3
+ class Sheets::Parsers::RooParser < Sheets::Parsers::Base
4
+ parses :xls, :xlsx, :ods
5
+
6
+ ROO_CLASS = {
7
+ :xls => Excel,
8
+ :xlsx => Excelx,
9
+ :ods => Openoffice
10
+ }
11
+
12
+ def to_array
13
+ array = []
14
+ (spreadsheet.first_row..spreadsheet.last_row).each do |row_num|
15
+ row = []
16
+ (spreadsheet.first_column..spreadsheet.last_column).each do |column_num|
17
+ row << spreadsheet.cell(row_num, column_num).to_s
18
+ end
19
+ array << row
20
+ end
21
+ array
22
+ end
23
+
24
+ private
25
+ def spreadsheet
26
+ ROO_CLASS[@format.to_sym].new(@file_path)
27
+ end
28
+ end
@@ -0,0 +1,36 @@
1
+ module Sheets
2
+ module Renderable
3
+ def self.included(base)
4
+ base.extend(ClassMethods)
5
+ end
6
+
7
+ module ClassMethods
8
+ def renderable_formats
9
+ Sheets::Renderers.constants.collect {|constant_name| Sheets::Renderers.const_get(constant_name) }.map(&:formats).flatten.uniq
10
+ end
11
+ end
12
+
13
+ def method_missing(method_name, *args, &block)
14
+ match = method_name.to_s.match(/\Ato_(.*)/i)
15
+ format = match[1] unless match.nil?
16
+
17
+ format.nil? || !self.class.renderable_formats.include?(format) ? super(method_name, args, block) : renderer(format).send(method_name)
18
+ end
19
+
20
+ private
21
+ def renderer_class(format)
22
+ classes = Sheets::Renderers.constants.map do |constant_name|
23
+ constant = Sheets::Renderers.const_get(constant_name)
24
+ constant if constant && constant.respond_to?(:formats) && constant.formats.map(&:to_s).include?(format)
25
+ end
26
+
27
+ classes.delete(nil)
28
+
29
+ classes.first
30
+ end
31
+
32
+ def renderer(format = @extension)
33
+ @renderer ||= renderer_class(format).new(to_array, format) unless renderer_class(format).nil?
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,18 @@
1
+ class Sheets::Renderers::Base
2
+ def initialize(data, format)
3
+ @data = data
4
+ @format = format
5
+ end
6
+
7
+ def self.renders(*args)
8
+ self.formats = args.map(&:to_s)
9
+ end
10
+
11
+ def self.formats
12
+ @formats ||= []
13
+ end
14
+
15
+ def self.formats=(new_formats)
16
+ @formats = new_formats
17
+ end
18
+ end
@@ -0,0 +1,7 @@
1
+ class Sheets::Renderers::CSVRenderer < Sheets::Renderers::Base
2
+ renders :csv
3
+
4
+ def to_csv
5
+ @data.collect {|row| row.join(',') }.join("\n")
6
+ end
7
+ end
@@ -0,0 +1,22 @@
1
+ class Sheets::Renderers::ExcelRenderer < Sheets::Renderers::Base
2
+ renders :xls
3
+
4
+ def to_xls
5
+ workbook = Spreadsheet::Excel::Workbook.new
6
+ worksheet = Spreadsheet::Excel::Worksheet.new
7
+ workbook.add_worksheet(worksheet)
8
+
9
+ @data.each_with_index do |row, row_index|
10
+ row.each_with_index do |cell, col_index|
11
+ worksheet[row_index, col_index] = cell
12
+ end
13
+ end
14
+
15
+ # Tried to use StringIO here, but ran into encoding issues with Ruby 1.8.7.
16
+ file_path = "tmp_excel_render_#{Time.now.to_i}"
17
+ File.open(file_path, 'w+') {|file| workbook.write(file) }
18
+ File.read(file_path)
19
+ ensure
20
+ File.delete( file_path ) if File.exists?( file_path )
21
+ end
22
+ end
@@ -0,0 +1,3 @@
1
+ module Sheets
2
+ VERSION = "0.9.0"
3
+ end
data/sheets.gemspec ADDED
@@ -0,0 +1,23 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "sheets/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "sheets"
7
+ s.version = Sheets::VERSION
8
+ s.platform = Gem::Platform::RUBY
9
+ s.authors = ["Bradley J. Spaulding"]
10
+ s.email = ["brad.spaulding@gmail.com"]
11
+ s.homepage = "https://github.com/bspaulding/Sheets"
12
+ s.summary = %q{Sheets provides a Facade for importing spreadsheets that gives the application control. Any Spreadsheet can be represented as either (1) a two dimensional array, or (2) an array of hashes. Sheets' goal is to convert any spreadsheet format to one of these native Ruby data structures.}
13
+ s.description = %q{Work with spreadsheets easily in a native ruby format.}
14
+
15
+ s.rubyforge_project = "sheets"
16
+
17
+ s.add_dependency('roo', '>= 1.9.3')
18
+
19
+ s.files = `git ls-files`.split("\n")
20
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
21
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
22
+ s.require_paths = ["lib"]
23
+ end
data/test/base_test.rb ADDED
@@ -0,0 +1,19 @@
1
+ class TestBase < Test::Unit::TestCase
2
+ EXAMPLE_DATA = [
3
+ ["Date", "Impressions", "Clicks", "Actions"],
4
+ ["2011-01-01", "10", "10", "10"],
5
+ ["2011-01-02", "10", "10", "10"],
6
+ ["2011-01-03", "10", "10", "10"],
7
+ ["2011-01-04", "10", "10", "10"],
8
+ ["2011-01-05", "10", "10", "10"],
9
+ ["2011-01-06", "10", "10", "10"],
10
+ ["2011-01-07", "10", "10", "10"],
11
+ ["2011-01-08", "10", "10", "10"],
12
+ ["2011-01-09", "10", "10", "10"],
13
+ ["2011-01-10", "10", "10", "10"]
14
+ ]
15
+
16
+ def test_initialize_with_array
17
+ assert_equal EXAMPLE_DATA, Sheets::Base.new( EXAMPLE_DATA ).to_array
18
+ end
19
+ end
@@ -0,0 +1,11 @@
1
+ Date,Impressions,Clicks,Actions
2
+ 2011-01-01,10,10,10
3
+ 2011-01-02,10,10,10
4
+ 2011-01-03,10,10,10
5
+ 2011-01-04,10,10,10
6
+ 2011-01-05,10,10,10
7
+ 2011-01-06,10,10,10
8
+ 2011-01-07,10,10,10
9
+ 2011-01-08,10,10,10
10
+ 2011-01-09,10,10,10
11
+ 2011-01-10,10,10,10
Binary file
Binary file
Binary file
@@ -0,0 +1,7 @@
1
+ def test_classes_for_collection(collection, &block)
2
+ collection.each do |object|
3
+ test_class = Class.new(Test::Unit::TestCase)
4
+ Object.const_set("Test#{object.to_s.split(':')[-1]}Interface", test_class)
5
+ test_class.instance_exec(object, &block)
6
+ end
7
+ end
@@ -0,0 +1,9 @@
1
+ class TestParseable < Test::Unit::TestCase
2
+ Sheets::Base.parseable_formats.each do |format|
3
+ define_method "test_sheet_parses_#{format}" do
4
+ assert_nothing_raised do
5
+ Sheets::Base.new( File.join('test', 'data', "simple.#{format}") ).to_array
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,18 @@
1
+ parser_classes = (Sheets::Parsers.constants - ["Base"]).map {|constant_name| Sheets::Parsers.const_get(constant_name) }
2
+
3
+ test_classes_for_collection parser_classes do |parser_class|
4
+ define_method :test_provides_formats do
5
+ assert parser_class.respond_to? :formats, "#{parser_class} doesn't respond_to formats."
6
+ end
7
+
8
+ define_method :test_formats_not_empty do
9
+ assert !parser_class.formats.empty?, "#{parser_class} doesn't render any formats."
10
+ end
11
+
12
+ parser_class.formats.each do |format|
13
+ define_method "test_#{format}_to_array" do
14
+ parser = parser_class.new([], format, nil)
15
+ assert parser.respond_to?("to_array"), "#{parser.inspect} doesn't respond to to_array"
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,37 @@
1
+ class TestCSVParser < Test::Unit::TestCase
2
+
3
+ def test_to_array
4
+ file_path = generate_test_spreadsheet
5
+ assert_equal Sheets::Base.new( file_path ).to_array, example_spreadsheet_data
6
+ ensure
7
+ File.delete( file_path ) if File.exists?( file_path )
8
+ end
9
+
10
+ private
11
+ def example_spreadsheet_data
12
+ [
13
+ ["Date", "Impressions", "Clicks", "Actions"],
14
+ ["2011-01-01", "10", "10", "10"],
15
+ ["2011-01-02", "10", "10", "10"],
16
+ ["2011-01-03", "10", "10", "10"],
17
+ ["2011-01-04", "10", "10", "10"],
18
+ ["2011-01-05", "10", "10", "10"],
19
+ ["2011-01-06", "10", "10", "10"],
20
+ ["2011-01-07", "10", "10", "10"],
21
+ ["2011-01-08", "10", "10", "10"],
22
+ ["2011-01-09", "10", "10", "10"],
23
+ ["2011-01-10", "10", "10", "10"]
24
+ ]
25
+ end
26
+
27
+ def generate_test_spreadsheet
28
+ filename = "test_simple_#{Time.new.to_i}.csv"
29
+ file_path = File.join('.', filename)
30
+
31
+ File.open( file_path, 'w+' ) do |file|
32
+ file.write( example_spreadsheet_data.collect {|row| row.join(',') }.join("\n") )
33
+ end
34
+
35
+ file_path
36
+ end
37
+ end
@@ -0,0 +1,8 @@
1
+ class TestRenderable < Test::Unit::TestCase
2
+ Sheets::Base.renderable_formats.each do |renderable_format|
3
+ define_method "test_sheet_responds_to_#{renderable_format}" do
4
+ sheet = Sheets::Base.new( File.join('test', 'data', 'simple.csv') )
5
+ assert_nothing_raised { sheet.send("to_#{renderable_format}") }
6
+ end
7
+ end
8
+ end
@@ -0,0 +1,18 @@
1
+ renderer_classes = (Sheets::Renderers.constants - ["Base"]).map {|constant_name| Sheets::Renderers.const_get(constant_name) }
2
+
3
+ test_classes_for_collection renderer_classes do |renderer_class|
4
+ define_method :test_provides_formats do
5
+ assert renderer_class.respond_to? :formats, "#{renderer_class} doesn't respond_to formats."
6
+ end
7
+
8
+ define_method :test_formats_not_empty do
9
+ assert !renderer_class.formats.empty?, "#{renderer_class} doesn't render any formats."
10
+ end
11
+
12
+ renderer_class.formats.each do |format|
13
+ define_method "test_to_#{format}" do
14
+ renderer = renderer_class.new([], format)
15
+ assert renderer.respond_to?("to_#{format}"), "#{renderer.inspect} doesn't respond to to_#{format}"
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,25 @@
1
+ class TestCSVRenderer < Test::Unit::TestCase
2
+
3
+ def test_to_csv
4
+ renderer = Sheets::Renderers::CSVRenderer.new(example_spreadsheet_data, :csv)
5
+
6
+ assert_equal renderer.to_csv, example_spreadsheet_data.collect {|row| row.join(',') }.join("\n")
7
+ end
8
+
9
+ private
10
+ def example_spreadsheet_data
11
+ [
12
+ ["Date", "Impressions", "Clicks", "Actions"],
13
+ ["2011-01-01", "10", "10", "10"],
14
+ ["2011-01-02", "10", "10", "10"],
15
+ ["2011-01-03", "10", "10", "10"],
16
+ ["2011-01-04", "10", "10", "10"],
17
+ ["2011-01-05", "10", "10", "10"],
18
+ ["2011-01-06", "10", "10", "10"],
19
+ ["2011-01-07", "10", "10", "10"],
20
+ ["2011-01-08", "10", "10", "10"],
21
+ ["2011-01-09", "10", "10", "10"],
22
+ ["2011-01-10", "10", "10", "10"]
23
+ ]
24
+ end
25
+ end
@@ -0,0 +1,42 @@
1
+ class TestExcelRenderer < Test::Unit::TestCase
2
+
3
+ EXAMPLE_DATA = [
4
+ ["Date", "Impressions", "Clicks", "Actions"],
5
+ ["2011-01-01", "10", "10", "10"],
6
+ ["2011-01-02", "10", "10", "10"],
7
+ ["2011-01-03", "10", "10", "10"],
8
+ ["2011-01-04", "10", "10", "10"],
9
+ ["2011-01-05", "10", "10", "10"],
10
+ ["2011-01-06", "10", "10", "10"],
11
+ ["2011-01-07", "10", "10", "10"],
12
+ ["2011-01-08", "10", "10", "10"],
13
+ ["2011-01-09", "10", "10", "10"],
14
+ ["2011-01-10", "10", "10", "10"]
15
+ ]
16
+
17
+ def test_to_xls
18
+ renderer = Sheets::Renderers::ExcelRenderer.new(EXAMPLE_DATA, :xls)
19
+
20
+ file_path = File.expand_path( File.join('test', 'data', "excel_render_test_#{Time.now.to_i}.xls") )
21
+ File.open(file_path, 'w+') {|file| file.write(renderer.to_xls) }
22
+
23
+ assert_equal EXAMPLE_DATA, Sheets::Base.new( file_path ).to_array
24
+ ensure
25
+ File.delete( file_path ) if File.exists?( file_path )
26
+ end
27
+
28
+ Sheets::Base.parseable_formats.each do |parseable_format|
29
+ define_method "test_#{parseable_format}_to_xls" do
30
+ begin
31
+ sheet = Sheets::Base.new( File.join('test', 'data', "simple.#{parseable_format}") )
32
+
33
+ file_path = File.expand_path( File.join('test', 'data', "excel_render_test_#{Time.now.to_i}.xls") )
34
+ File.open(file_path, 'w+') {|file| file.write(sheet.to_xls) }
35
+
36
+ assert_equal sheet.to_array, Sheets::Base.new( file_path ).to_array
37
+ ensure
38
+ File.delete( file_path ) if File.exists?( file_path )
39
+ end
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,6 @@
1
+ require 'test/unit'
2
+
3
+ puts 'Loading Test Generators'
4
+ Dir[ File.join(File.expand_path(File.dirname(__FILE__)), 'generators', '*.rb') ].each {|file| puts "- #{file}"; require file }
5
+
6
+ require File.join(File.expand_path(File.dirname(__FILE__)), '..', 'lib', 'sheets.rb')
metadata ADDED
@@ -0,0 +1,126 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: sheets
3
+ version: !ruby/object:Gem::Version
4
+ hash: 59
5
+ prerelease:
6
+ segments:
7
+ - 0
8
+ - 9
9
+ - 0
10
+ version: 0.9.0
11
+ platform: ruby
12
+ authors:
13
+ - Bradley J. Spaulding
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2011-04-11 00:00:00 -04:00
19
+ default_executable:
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
22
+ name: roo
23
+ prerelease: false
24
+ requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ hash: 53
30
+ segments:
31
+ - 1
32
+ - 9
33
+ - 3
34
+ version: 1.9.3
35
+ type: :runtime
36
+ version_requirements: *id001
37
+ description: Work with spreadsheets easily in a native ruby format.
38
+ email:
39
+ - brad.spaulding@gmail.com
40
+ executables: []
41
+
42
+ extensions: []
43
+
44
+ extra_rdoc_files: []
45
+
46
+ files:
47
+ - .gitignore
48
+ - Gemfile
49
+ - LICENSE.txt
50
+ - README.md
51
+ - Rakefile
52
+ - lib/sheets.rb
53
+ - lib/sheets/base.rb
54
+ - lib/sheets/parseable.rb
55
+ - lib/sheets/parsers/base.rb
56
+ - lib/sheets/parsers/csv_parser.rb
57
+ - lib/sheets/parsers/roo_parser.rb
58
+ - lib/sheets/renderable.rb
59
+ - lib/sheets/renderers/base.rb
60
+ - lib/sheets/renderers/csv_renderer.rb
61
+ - lib/sheets/renderers/excel_renderer.rb
62
+ - lib/sheets/version.rb
63
+ - sheets.gemspec
64
+ - test/base_test.rb
65
+ - test/data/simple.csv
66
+ - test/data/simple.ods
67
+ - test/data/simple.xls
68
+ - test/data/simple.xlsx
69
+ - test/generators/test_classes.rb
70
+ - test/parseable_test.rb
71
+ - test/parsers/basic_parsers_test.rb
72
+ - test/parsers/csv_parser_test.rb
73
+ - test/renderable_test.rb
74
+ - test/renderers/basic_renderers_test.rb
75
+ - test/renderers/csv_renderer_test.rb
76
+ - test/renderers/excel_renderer_test.rb
77
+ - test/test_helper.rb
78
+ has_rdoc: true
79
+ homepage: https://github.com/bspaulding/Sheets
80
+ licenses: []
81
+
82
+ post_install_message:
83
+ rdoc_options: []
84
+
85
+ require_paths:
86
+ - lib
87
+ required_ruby_version: !ruby/object:Gem::Requirement
88
+ none: false
89
+ requirements:
90
+ - - ">="
91
+ - !ruby/object:Gem::Version
92
+ hash: 3
93
+ segments:
94
+ - 0
95
+ version: "0"
96
+ required_rubygems_version: !ruby/object:Gem::Requirement
97
+ none: false
98
+ requirements:
99
+ - - ">="
100
+ - !ruby/object:Gem::Version
101
+ hash: 3
102
+ segments:
103
+ - 0
104
+ version: "0"
105
+ requirements: []
106
+
107
+ rubyforge_project: sheets
108
+ rubygems_version: 1.5.0
109
+ signing_key:
110
+ specification_version: 3
111
+ summary: Sheets provides a Facade for importing spreadsheets that gives the application control. Any Spreadsheet can be represented as either (1) a two dimensional array, or (2) an array of hashes. Sheets' goal is to convert any spreadsheet format to one of these native Ruby data structures.
112
+ test_files:
113
+ - test/base_test.rb
114
+ - test/data/simple.csv
115
+ - test/data/simple.ods
116
+ - test/data/simple.xls
117
+ - test/data/simple.xlsx
118
+ - test/generators/test_classes.rb
119
+ - test/parseable_test.rb
120
+ - test/parsers/basic_parsers_test.rb
121
+ - test/parsers/csv_parser_test.rb
122
+ - test/renderable_test.rb
123
+ - test/renderers/basic_renderers_test.rb
124
+ - test/renderers/csv_renderer_test.rb
125
+ - test/renderers/excel_renderer_test.rb
126
+ - test/test_helper.rb