csv_madness 0.0.3 → 0.0.4
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/CHANGELOG.markdown +17 -0
- data/Gemfile +3 -0
- data/README.rdoc +5 -3
- data/Rakefile +3 -1
- data/VERSION +1 -1
- data/lib/csv_madness/record.rb +13 -3
- data/lib/csv_madness/sheet.rb +83 -15
- data/lib/csv_madness.rb +4 -1
- data/test/helper.rb +82 -0
- data/test/test_csv_madness.rb +52 -22
- data/test/test_sheet.rb +24 -0
- metadata +21 -3
data/CHANGELOG.markdown
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
0.0.4
|
2
|
+
=====
|
3
|
+
|
4
|
+
* Fixed serious bug for default column names. record.middle_name instead of record.middlename
|
5
|
+
* Spreadsheet can be re-read from file by calling @sheet.reload_spreadsheet(opts)
|
6
|
+
|
7
|
+
|
8
|
+
0.0.3
|
9
|
+
=====
|
10
|
+
|
11
|
+
* Feature: can add and drop columns from spreadsheets
|
12
|
+
|
13
|
+
|
14
|
+
0.0.2
|
15
|
+
=====
|
16
|
+
|
17
|
+
* Aw, hell. I don't remember.
|
data/Gemfile
CHANGED
data/README.rdoc
CHANGED
@@ -121,9 +121,9 @@ sheet.write_to_file( "~/data/people.clean.csv", force_quotes: true ) # save the
|
|
121
121
|
You could do something similar to clean and standardize phone numbers, detect and delete/complete invalid emails, etc.
|
122
122
|
|
123
123
|
|
124
|
-
=== Adding and
|
124
|
+
=== Adding, removing, and renaming columns ===
|
125
125
|
|
126
|
-
# Add 72 years to the date born.
|
126
|
+
# Add 72 years to the date born.
|
127
127
|
sheet.set_column_type( :born, :date ) # replace date strings with Time objects
|
128
128
|
|
129
129
|
sheet.add_column( :expected_death_date ) do |date, record|
|
@@ -135,8 +135,10 @@ puts sheet[0].expected_death_date # should be in 2058
|
|
135
135
|
# But that's just morbid, so we drop the column
|
136
136
|
sheet.drop_column( :expected_death_date )
|
137
137
|
|
138
|
+
# Or, if you think you need the information, but need to be a bit more euphemistic about it
|
139
|
+
sheet.rename_column( :expected_death_date, :expiration_date )
|
138
140
|
|
139
|
-
=== Using columns
|
141
|
+
=== Using columns ===
|
140
142
|
|
141
143
|
sheet.set_column_type( :id, :integer )
|
142
144
|
|
data/Rakefile
CHANGED
@@ -33,9 +33,11 @@ Jeweler::Tasks.new do |gem|
|
|
33
33
|
"./VERSION",
|
34
34
|
"./README.rdoc",
|
35
35
|
"./Rakefile",
|
36
|
+
"./CHANGELOG.markdown",
|
36
37
|
"./test/csv/simple.csv",
|
37
38
|
"./test/helper.rb",
|
38
|
-
"./test/test_csv_madness.rb"
|
39
|
+
"./test/test_csv_madness.rb",
|
40
|
+
"./test/test_sheet.rb" ]
|
39
41
|
end
|
40
42
|
|
41
43
|
Jeweler::RubygemsDotOrgTasks.new
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.0.
|
1
|
+
0.0.4
|
data/lib/csv_madness/record.rb
CHANGED
@@ -13,11 +13,21 @@ module CsvMadness
|
|
13
13
|
end
|
14
14
|
|
15
15
|
def [] key
|
16
|
-
|
16
|
+
case key
|
17
|
+
when String, Integer
|
18
|
+
@csv_data[key]
|
19
|
+
when Symbol
|
20
|
+
@csv_data[key.to_s]
|
21
|
+
end
|
17
22
|
end
|
18
23
|
|
19
24
|
def []= key, val
|
20
|
-
|
25
|
+
case key
|
26
|
+
when String, Integer
|
27
|
+
@csv_data[key] = val
|
28
|
+
when Symbol
|
29
|
+
@csv_data[key.to_s] = val
|
30
|
+
end
|
21
31
|
end
|
22
32
|
|
23
33
|
def columns
|
@@ -37,7 +47,7 @@ module CsvMadness
|
|
37
47
|
end
|
38
48
|
|
39
49
|
def blank?( col )
|
40
|
-
(self.send( col ).to_s || "").strip.length == 0
|
50
|
+
(self.send( col.to_sym ).to_s || "").strip.length == 0
|
41
51
|
end
|
42
52
|
end
|
43
53
|
end
|
data/lib/csv_madness/sheet.rb
CHANGED
@@ -30,7 +30,8 @@ module CsvMadness
|
|
30
30
|
# Used to make getter/setter names out of the original header strings.
|
31
31
|
# " hello;: world! " => :hello_world
|
32
32
|
def self.getter_name( name )
|
33
|
-
name = name.strip.gsub(/\s+/,"_").gsub(/(\W|_)+/, "" ).downcase
|
33
|
+
name = name.strip.gsub( /\s+/, "_" ).gsub( /(\W|_)+/, "_" ).downcase
|
34
|
+
name = name.gsub( /_+$/, "" )
|
34
35
|
if name.match( /^\d/ )
|
35
36
|
name = "_#{name}"
|
36
37
|
end
|
@@ -43,9 +44,17 @@ module CsvMadness
|
|
43
44
|
def self.add_search_path( path )
|
44
45
|
@search_paths ||= []
|
45
46
|
path = Pathname.new( path ).expand_path
|
47
|
+
unless path.directory?
|
48
|
+
raise "The given path does not exist"
|
49
|
+
end
|
50
|
+
|
46
51
|
@search_paths << path unless @search_paths.include?( path )
|
47
52
|
end
|
48
53
|
|
54
|
+
def self.search_paths
|
55
|
+
@search_paths
|
56
|
+
end
|
57
|
+
|
49
58
|
def self.from( csv_file, opts = {} )
|
50
59
|
if f = find_spreadsheet_in_filesystem( csv_file )
|
51
60
|
Sheet.new( f, opts )
|
@@ -83,7 +92,7 @@ module CsvMadness
|
|
83
92
|
end
|
84
93
|
|
85
94
|
def self.write_to_file( spreadsheet, file, opts = {} )
|
86
|
-
file =
|
95
|
+
file = file.fwf_filepath.expand_path
|
87
96
|
File.open( file, "w" ) do |f|
|
88
97
|
f << spreadsheet.to_csv( opts )
|
89
98
|
end
|
@@ -99,7 +108,7 @@ module CsvMadness
|
|
99
108
|
end
|
100
109
|
end
|
101
110
|
|
102
|
-
attr_reader :columns, :records, :spreadsheet_file, :record_class
|
111
|
+
attr_reader :columns, :index_columns, :records, :spreadsheet_file, :record_class
|
103
112
|
# opts:
|
104
113
|
# index: ( [:id, :id2 ] )
|
105
114
|
# columns you want mapped for quick
|
@@ -115,28 +124,37 @@ module CsvMadness
|
|
115
124
|
# header: false
|
116
125
|
# anything else, we assume the csv file has a header row
|
117
126
|
def initialize( spreadsheet, opts = {} )
|
118
|
-
|
127
|
+
if spreadsheet.is_a?(Array)
|
128
|
+
@spreadsheet_file = nil
|
129
|
+
|
130
|
+
else
|
131
|
+
@spreadsheet_file = self.class.find_spreadsheet_in_filesystem( spreadsheet )
|
132
|
+
end
|
119
133
|
@opts = opts
|
120
134
|
@opts[:header] = (@opts[:header] == false ? false : true) # true unless already explicitly set to false
|
121
135
|
|
136
|
+
reload_spreadsheet
|
137
|
+
end
|
138
|
+
|
139
|
+
def reload_spreadsheet( opts = @opts )
|
122
140
|
load_csv
|
123
|
-
|
124
|
-
set_initial_columns( @opts[:columns] )
|
125
|
-
|
126
|
-
|
141
|
+
set_initial_columns( opts[:columns] )
|
127
142
|
create_record_class
|
128
143
|
package
|
129
144
|
|
130
|
-
|
145
|
+
set_index_columns( opts[:index] )
|
146
|
+
reindex
|
147
|
+
end
|
148
|
+
|
149
|
+
def set_index_columns( index_columns )
|
150
|
+
@index_columns = case index_columns
|
131
151
|
when NilClass
|
132
152
|
[]
|
133
153
|
when Symbol
|
134
|
-
[
|
154
|
+
[ index_columns ]
|
135
155
|
when Array
|
136
|
-
|
156
|
+
index_columns
|
137
157
|
end
|
138
|
-
|
139
|
-
reindex
|
140
158
|
end
|
141
159
|
|
142
160
|
def [] offset
|
@@ -196,8 +214,9 @@ module CsvMadness
|
|
196
214
|
end
|
197
215
|
end
|
198
216
|
|
199
|
-
# if column doesn't exist, silently fails. Proper behavior? Dunno.
|
200
217
|
def alter_column( column, blank = :undefined, &block )
|
218
|
+
raise "Column does not exist: #{column}" unless @columns.include?( column )
|
219
|
+
|
201
220
|
if cindex = @columns.index( column )
|
202
221
|
for record in @records
|
203
222
|
if record.blank?(column) && blank != :undefined
|
@@ -209,8 +228,9 @@ module CsvMadness
|
|
209
228
|
end
|
210
229
|
end
|
211
230
|
|
231
|
+
# If no block given, adds an empty column
|
212
232
|
def add_column( column, &block )
|
213
|
-
raise "Column already exists" if @columns.include?( column )
|
233
|
+
raise "Column already exists: #{column}" if @columns.include?( column )
|
214
234
|
@columns << column
|
215
235
|
|
216
236
|
# add empty column to each row
|
@@ -241,10 +261,45 @@ module CsvMadness
|
|
241
261
|
update_data_accessor_module
|
242
262
|
end
|
243
263
|
|
264
|
+
def rename_column( column, new_name )
|
265
|
+
@columns[@columns.index(column)] = new_name
|
266
|
+
rename_index_column( column, new_name ) if @index_columns.include?( column )
|
267
|
+
update_data_accessor_module
|
268
|
+
end
|
269
|
+
|
244
270
|
def set_column_type( column, type, blank = :undefined )
|
245
271
|
alter_column( column, blank, &COLUMN_TYPES[type] )
|
246
272
|
end
|
247
273
|
|
274
|
+
|
275
|
+
# If :reverse_merge is true, then the dest column is only overwritten for records where :dest is blank
|
276
|
+
def merge_columns( source, dest, opts = {} )
|
277
|
+
opts = { :drop_source => true, :reverse_merge => false, :default => "" }.merge( opts )
|
278
|
+
column_must_exist( source, dest )
|
279
|
+
|
280
|
+
self.records.each do |record|
|
281
|
+
if opts[:reverse_merge] == false || record.blank?( dest )
|
282
|
+
record[dest] = record.blank?(source) ? opts[:default] : record[source]
|
283
|
+
end
|
284
|
+
end
|
285
|
+
|
286
|
+
self.drop_column( source ) if opts[:drop_source]
|
287
|
+
end
|
288
|
+
|
289
|
+
# By default, the
|
290
|
+
def concat_columns( col1, col2, opts = {} )
|
291
|
+
opts = {:separator => '', :out => col1}.merge( opts )
|
292
|
+
|
293
|
+
column_must_exist( col1, col2 )
|
294
|
+
self.add_column( opts[:out] ) unless self.columns.include?( opts[:out] )
|
295
|
+
|
296
|
+
for record in self.records
|
297
|
+
record[ opts[:out] ] = "#{record[col1]}#{opts[:separator]}#{record[col2]}"
|
298
|
+
end
|
299
|
+
end
|
300
|
+
|
301
|
+
alias :concatenate :concat_columns
|
302
|
+
|
248
303
|
# Note: If a block is given, the mod arg will be ignored.
|
249
304
|
def add_record_methods( mod = nil, &block )
|
250
305
|
if block_given?
|
@@ -285,6 +340,13 @@ module CsvMadness
|
|
285
340
|
end
|
286
341
|
end
|
287
342
|
|
343
|
+
# shouldn't require reindex
|
344
|
+
def rename_index_column( column, new_name )
|
345
|
+
@index_columns[ @index_columns.index( column ) ] = new_name
|
346
|
+
@indexes[new_name] = @indexes[column]
|
347
|
+
@indexes.delete(column)
|
348
|
+
end
|
349
|
+
|
288
350
|
# Each spreadsheet has its own anonymous record class, and each CSV row instantiates
|
289
351
|
# a record of this class. This is where the getters and setters come from.
|
290
352
|
def create_record_class
|
@@ -374,5 +436,11 @@ module CsvMadness
|
|
374
436
|
def update_data_accessor_module
|
375
437
|
@module.remap_accessors( columns_to_mapping )
|
376
438
|
end
|
439
|
+
|
440
|
+
def column_must_exist( *cols )
|
441
|
+
for col in cols
|
442
|
+
raise ArgumentError.new( "#{caller[0]}: column :#{col} does not exist.") unless self.columns.include?(col)
|
443
|
+
end
|
444
|
+
end
|
377
445
|
end
|
378
446
|
end
|
data/lib/csv_madness.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
require 'csv'
|
2
|
-
require '
|
2
|
+
require 'fun_with_files'
|
3
3
|
require 'time' # to use Time.parse to parse cells to get the date
|
4
4
|
require 'debugger'
|
5
5
|
|
@@ -7,6 +7,9 @@ require_relative 'csv_madness/data_accessor_module'
|
|
7
7
|
require_relative 'csv_madness/sheet'
|
8
8
|
require_relative 'csv_madness/record'
|
9
9
|
|
10
|
+
|
11
|
+
FunWith::Files::RootPath.rootify( CsvMadness, __FILE__.fwf_filepath.dirname.up )
|
12
|
+
|
10
13
|
CsvMadness.class_eval do
|
11
14
|
def self.load( csv, opts = {} )
|
12
15
|
CsvMadness::Sheet.from( csv, opts )
|
data/test/helper.rb
CHANGED
@@ -19,3 +19,85 @@ require 'csv_madness'
|
|
19
19
|
|
20
20
|
class Test::Unit::TestCase
|
21
21
|
end
|
22
|
+
|
23
|
+
class MadTestCase < Test::Unit::TestCase
|
24
|
+
MARY_ID = "1"
|
25
|
+
BILL_ID = "2"
|
26
|
+
DARWIN_ID = "3"
|
27
|
+
CHUCK_ID = "4"
|
28
|
+
|
29
|
+
def load_mary
|
30
|
+
id = @simple.index_columns.first
|
31
|
+
@mary = @simple.fetch( id, MARY_ID )
|
32
|
+
end
|
33
|
+
|
34
|
+
def load_bill
|
35
|
+
id = @simple.index_columns.first
|
36
|
+
@bill = @simple.fetch( id, BILL_ID )
|
37
|
+
end
|
38
|
+
|
39
|
+
def load_darwin
|
40
|
+
id = @simple.index_columns.first
|
41
|
+
@darwin = @simple.fetch( id, DARWIN_ID )
|
42
|
+
end
|
43
|
+
|
44
|
+
def load_chuck
|
45
|
+
id = @simple.index_columns.first
|
46
|
+
@chuck = @simple.fetch( id, CHUCK_ID )
|
47
|
+
end
|
48
|
+
|
49
|
+
def set_person_records
|
50
|
+
load_mary
|
51
|
+
load_darwin
|
52
|
+
load_bill
|
53
|
+
load_chuck
|
54
|
+
end
|
55
|
+
|
56
|
+
def muck_up_spreadsheet
|
57
|
+
@simple.add_column(:scrambled_name) do |val, record|
|
58
|
+
record.fname.chars.map(&:to_s).zip( record.lname.chars.map(&:to_s) ).flatten.compact.join
|
59
|
+
end
|
60
|
+
|
61
|
+
@simple.alter_column(:id) do |val|
|
62
|
+
(val.to_i << 8) % 27
|
63
|
+
end
|
64
|
+
|
65
|
+
@simple.set_column_type(:id, :float)
|
66
|
+
@simple.set_column_type(:born, :date)
|
67
|
+
|
68
|
+
@simple.alter_column(:born) do |val|
|
69
|
+
if val.is_a?(String)
|
70
|
+
-1.0
|
71
|
+
else
|
72
|
+
(Time.now - val).to_f
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
@simple.drop_column(:fname)
|
77
|
+
@simple.drop_column(:lname)
|
78
|
+
end
|
79
|
+
|
80
|
+
def set_spreadsheet_paths
|
81
|
+
@csv_search_path = Pathname.new( __FILE__ ).dirname.join("csv")
|
82
|
+
@csv_output_path = @csv_search_path.join("out")
|
83
|
+
CsvMadness::Sheet.add_search_path( @csv_search_path )
|
84
|
+
CsvMadness::Sheet.add_search_path( @csv_output_path )
|
85
|
+
end
|
86
|
+
|
87
|
+
def load_simple_spreadsheet
|
88
|
+
@simple = CsvMadness.load( "simple.csv", index: [:id] )
|
89
|
+
end
|
90
|
+
|
91
|
+
def unload_simple_spreadsheet
|
92
|
+
@simple = nil
|
93
|
+
end
|
94
|
+
|
95
|
+
def empty_output_folder
|
96
|
+
if defined?(FileUtils)
|
97
|
+
FileUtils.rm_rf( Dir.glob( @csv_output_path.join("**","*") ) )
|
98
|
+
else
|
99
|
+
puts "fileutils not defined"
|
100
|
+
`rm -rf #{@csv_output_path.join('*')}`
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
data/test/test_csv_madness.rb
CHANGED
@@ -1,26 +1,21 @@
|
|
1
1
|
require 'helper'
|
2
2
|
|
3
|
-
class TestCsvMadness <
|
3
|
+
class TestCsvMadness < MadTestCase
|
4
4
|
context "all:" do
|
5
5
|
setup do
|
6
|
-
|
7
|
-
|
8
|
-
CsvMadness::Sheet.add_search_path( @csv_search_path )
|
6
|
+
set_spreadsheet_paths
|
7
|
+
load_simple_spreadsheet
|
9
8
|
end
|
10
9
|
|
11
10
|
teardown do
|
12
|
-
|
13
|
-
FileUtils.rm_rf( Dir.glob( @csv_output_path.join("**","*") ) )
|
14
|
-
else
|
15
|
-
puts "fileutils not defined"
|
16
|
-
`rm -rf #{@csv_output_path.join('*')}`
|
17
|
-
end
|
11
|
+
empty_output_folder
|
18
12
|
end
|
19
13
|
|
20
14
|
context "testing sheet basics" do
|
21
15
|
should "not accept duplicate search paths" do
|
16
|
+
@path_count = CsvMadness::Sheet.search_paths.length
|
22
17
|
CsvMadness::Sheet.add_search_path( Pathname.new( __FILE__ ).dirname.join("csv") )
|
23
|
-
assert_equal
|
18
|
+
assert_equal @path_count, CsvMadness::Sheet.search_paths.length
|
24
19
|
end
|
25
20
|
|
26
21
|
should "load a simple spreadsheet" do
|
@@ -49,11 +44,11 @@ class TestCsvMadness < Test::Unit::TestCase
|
|
49
44
|
context "testing transformations" do
|
50
45
|
context "with a simple spreadsheet loaded" do
|
51
46
|
setup do
|
52
|
-
|
47
|
+
load_simple_spreadsheet
|
53
48
|
end
|
54
49
|
|
55
50
|
teardown do
|
56
|
-
|
51
|
+
unload_simple_spreadsheet
|
57
52
|
end
|
58
53
|
|
59
54
|
should "transform every cell" do
|
@@ -154,6 +149,49 @@ class TestCsvMadness < Test::Unit::TestCase
|
|
154
149
|
assert_equal records.length, records.compact.length
|
155
150
|
assert_equal 2, records.length
|
156
151
|
assert_equal "1", records.first.id
|
152
|
+
end
|
153
|
+
|
154
|
+
should "rename columns" do
|
155
|
+
load_mary
|
156
|
+
|
157
|
+
assert_equal "Mary", @mary.fname
|
158
|
+
assert_equal "Moore", @mary.lname
|
159
|
+
assert_equal "Mary", @mary[1]
|
160
|
+
assert_equal "Moore", @mary[2]
|
161
|
+
|
162
|
+
@simple.rename_column( :fname, :first_name )
|
163
|
+
@simple.rename_column( :lname, :last_name )
|
164
|
+
|
165
|
+
assert_equal "Mary", @mary.first_name
|
166
|
+
assert_equal "Moore", @mary.last_name
|
167
|
+
assert_equal "Mary", @mary[1]
|
168
|
+
assert_equal "Moore", @mary[2]
|
169
|
+
end
|
170
|
+
|
171
|
+
should "rename an index column" do
|
172
|
+
@simple.rename_column( :id, :identifier )
|
173
|
+
@mary = @simple.fetch( :identifier, "1" )
|
174
|
+
assert_equal "1", @mary.identifier
|
175
|
+
end
|
176
|
+
|
177
|
+
should "rename an index column and ensure that the outputted spreadsheet has the new column name" do
|
178
|
+
@simple.rename_column( :id, :identifier )
|
179
|
+
@outfile = @csv_output_path.join("output.csv")
|
180
|
+
@simple.write_to_file( @outfile, force_quotes: true )
|
181
|
+
|
182
|
+
@simple = CsvMadness.load( @outfile, index: [:identifier] )
|
183
|
+
|
184
|
+
load_mary
|
185
|
+
assert_equal "Mary", @mary.fname
|
186
|
+
end
|
187
|
+
|
188
|
+
should "filter! records" do
|
189
|
+
@simple.filter! do |record|
|
190
|
+
record.id == BILL_ID || record.id == CHUCK_ID
|
191
|
+
end
|
192
|
+
|
193
|
+
assert_equal 2, @simple.records.length
|
194
|
+
|
157
195
|
end
|
158
196
|
end
|
159
197
|
end
|
@@ -194,7 +232,7 @@ class TestCsvMadness < Test::Unit::TestCase
|
|
194
232
|
context "testing add/remove column transformations" do
|
195
233
|
context "with simple spreadsheet loaded" do
|
196
234
|
setup do
|
197
|
-
|
235
|
+
load_simple_spreadsheet
|
198
236
|
end
|
199
237
|
|
200
238
|
should "add column" do
|
@@ -221,12 +259,4 @@ class TestCsvMadness < Test::Unit::TestCase
|
|
221
259
|
end
|
222
260
|
end
|
223
261
|
end
|
224
|
-
|
225
|
-
def load_simple
|
226
|
-
@simple = CsvMadness.load( "simple.csv", index: [:id] )
|
227
|
-
end
|
228
|
-
|
229
|
-
def load_mary
|
230
|
-
@mary = @simple.fetch( :id, "1" )
|
231
|
-
end
|
232
262
|
end
|
data/test/test_sheet.rb
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
class TestCsvMadness < MadTestCase
|
4
|
+
context "testing getter_name()" do
|
5
|
+
should "return proper function names" do
|
6
|
+
assert_equal :hello_world, CsvMadness::Sheet.getter_name( " heLLo __ world " )
|
7
|
+
assert_equal :_0_hello_world, CsvMadness::Sheet.getter_name( "0 heLLo __ worlD!!! " )
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
context "testing default spreadsheet paths" do
|
12
|
+
should "only load existing paths" do
|
13
|
+
assert_raise(RuntimeError) do
|
14
|
+
CsvMadness::Sheet.add_search_path( CsvMadness.root.join("rocaganthor") )
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
should "check a search path for files to load" do
|
19
|
+
CsvMadness::Sheet.add_search_path( CsvMadness.root.join("test", "csv") )
|
20
|
+
sheet = CsvMadness.load( "with_nils.csv" )
|
21
|
+
assert sheet.is_a?(CsvMadness::Sheet)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: csv_madness
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.4
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,8 +9,24 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-
|
12
|
+
date: 2013-11-07 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: fun_with_files
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ! '>='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '0'
|
14
30
|
- !ruby/object:Gem::Dependency
|
15
31
|
name: shoulda
|
16
32
|
requirement: !ruby/object:Gem::Requirement
|
@@ -100,6 +116,7 @@ extra_rdoc_files:
|
|
100
116
|
- LICENSE.txt
|
101
117
|
- README.rdoc
|
102
118
|
files:
|
119
|
+
- ./CHANGELOG.markdown
|
103
120
|
- ./Gemfile
|
104
121
|
- ./README.rdoc
|
105
122
|
- ./Rakefile
|
@@ -111,6 +128,7 @@ files:
|
|
111
128
|
- ./test/csv/simple.csv
|
112
129
|
- ./test/helper.rb
|
113
130
|
- ./test/test_csv_madness.rb
|
131
|
+
- ./test/test_sheet.rb
|
114
132
|
- LICENSE.txt
|
115
133
|
- README.rdoc
|
116
134
|
homepage: http://github.com/darthschmoo/csv_madness
|
@@ -128,7 +146,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
128
146
|
version: '0'
|
129
147
|
segments:
|
130
148
|
- 0
|
131
|
-
hash:
|
149
|
+
hash: 1185350757253474800
|
132
150
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
133
151
|
none: false
|
134
152
|
requirements:
|