csv_madness 0.0.9 → 0.0.10
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.
Potentially problematic release.
This version of csv_madness might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/.document +5 -0
- data/CHANGELOG.markdown +4 -0
- data/Gemfile +2 -7
- data/Rakefile +12 -78
- data/VERSION +1 -1
- data/lib/csv_madness/builder.rb +91 -9
- data/lib/csv_madness/column.rb +30 -0
- data/lib/csv_madness/column_methods/core_methods.rb +6 -0
- data/lib/csv_madness/column_methods/default_value_methods.rb +7 -0
- data/lib/csv_madness/column_methods/error_methods.rb +19 -0
- data/lib/csv_madness/column_methods/fetch_methods.rb +11 -0
- data/lib/csv_madness/column_methods/typing_methods.rb +24 -0
- data/lib/csv_madness/column_set.rb +5 -0
- data/lib/csv_madness/column_type.rb +74 -0
- data/lib/csv_madness/column_types/date.rb +14 -0
- data/lib/csv_madness/column_types/float.rb +25 -0
- data/lib/csv_madness/column_types/integer.rb +17 -0
- data/lib/csv_madness/column_types/string.rb +9 -0
- data/lib/csv_madness/data_accessor_module.rb +79 -79
- data/lib/csv_madness/gem_api.rb +11 -2
- data/lib/csv_madness/index_set.rb +36 -0
- data/lib/csv_madness/indexer.rb +105 -0
- data/lib/csv_madness/record.rb +68 -42
- data/lib/csv_madness/record_filter.rb +68 -0
- data/lib/csv_madness/record_methods/method_methods.rb +57 -0
- data/lib/csv_madness/sheet.rb +160 -76
- data/lib/csv_madness/sheet_methods/class_methods.rb +11 -4
- data/lib/csv_madness/sheet_methods/column_methods.rb +95 -107
- data/lib/csv_madness/sheet_methods/file_methods.rb +9 -6
- data/lib/csv_madness/sheet_methods/indexing.rb +104 -23
- data/lib/csv_madness/sheet_methods/record_methods.rb +123 -47
- data/lib/csv_madness/sheet_methods/sorting_methods.rb +10 -0
- data/lib/csv_madness/utils/const_proc.rb +19 -0
- data/lib/csv_madness/utils/counter.rb +24 -0
- data/lib/csv_madness/utils/counter_proc.rb +31 -0
- data/lib/csv_madness/utils/looker_upper.rb +36 -0
- data/lib/csv_madness.rb +1 -0
- data/test/csv/nil_headers.csv +5 -0
- data/test/csv/out/.gitkeep +0 -0
- data/test/csv/pokemon.csv +9 -0
- data/test/csv/test_column_types.csv +2 -2
- data/test/helper.rb +9 -6
- data/test/test_builder.rb +36 -0
- data/test/test_csv_madness.rb +28 -18
- data/test/test_index_set.rb +30 -0
- data/test/test_indexer.rb +50 -0
- data/test/test_reloading_spreadsheet.rb +4 -2
- data/test/test_sheet.rb +164 -27
- data/test/test_utils.rb +99 -0
- metadata +66 -38
|
@@ -1,25 +1,69 @@
|
|
|
1
1
|
module CsvMadness
|
|
2
2
|
module SheetMethods
|
|
3
3
|
module Indexing
|
|
4
|
+
attr_accessor :index_columns
|
|
5
|
+
|
|
4
6
|
def set_index_columns( index_columns )
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
7
|
+
cols = case index_columns
|
|
8
|
+
when NilClass
|
|
9
|
+
[]
|
|
10
|
+
when Symbol
|
|
11
|
+
[ index_columns ]
|
|
12
|
+
when Array
|
|
13
|
+
index_columns.map{|col| add_index_column( col ) }
|
|
14
|
+
end
|
|
15
|
+
for col in cols.map(&:to_sym)
|
|
16
|
+
remove_index_column( col ) if self.has_index_column?( col )
|
|
17
|
+
add_index_column( col )
|
|
12
18
|
end
|
|
13
19
|
end
|
|
14
20
|
|
|
15
|
-
def
|
|
16
|
-
(
|
|
21
|
+
def add_index_column( col )
|
|
22
|
+
raise_if_index_columns( col )
|
|
23
|
+
|
|
24
|
+
col = col.to_sym
|
|
25
|
+
|
|
26
|
+
@index_columns << col
|
|
27
|
+
@indexes[col] = {}
|
|
28
|
+
|
|
29
|
+
reindex( col )
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
# TODO: Suddenly seeing a huge problem with the indexes.
|
|
33
|
+
# What if the index values aren't unique?
|
|
34
|
+
# Add a single record to a single index. Index value calculated by caller.
|
|
35
|
+
def add_to_index( col, index_value, record )
|
|
36
|
+
raise_unless_index_columns( col )
|
|
37
|
+
|
|
38
|
+
remove_from_index( col, record ) # first remove in case it's been indexed previously with a different value... gah, this is getting ugly.
|
|
39
|
+
|
|
40
|
+
index_hash = (@indexes[col.to_sym] ||= {})
|
|
41
|
+
index_hash_records = (index_hash[index_value] ||= Set.new)
|
|
42
|
+
|
|
43
|
+
index_hash_records << record
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def unindex_record( record )
|
|
47
|
+
for index_col in @index_columns
|
|
48
|
+
remove_from_index( index_col, record )
|
|
49
|
+
end
|
|
17
50
|
end
|
|
51
|
+
|
|
52
|
+
def remove_from_index( col, record )
|
|
53
|
+
raise_unless_index_columns( col )
|
|
54
|
+
|
|
55
|
+
@indexes[col.to_sym].each do |index_value, indexed_records|
|
|
56
|
+
indexed_records.delete( record )
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
|
|
18
62
|
|
|
19
|
-
def
|
|
63
|
+
def index_records( records )
|
|
20
64
|
if records.is_a?( Array )
|
|
21
65
|
for record in records
|
|
22
|
-
|
|
66
|
+
index_records( record )
|
|
23
67
|
end
|
|
24
68
|
else
|
|
25
69
|
record = records
|
|
@@ -28,24 +72,61 @@ module CsvMadness
|
|
|
28
72
|
end
|
|
29
73
|
end
|
|
30
74
|
end
|
|
31
|
-
|
|
32
|
-
def
|
|
33
|
-
|
|
34
|
-
@indexes[col].delete( record.send(col) )
|
|
35
|
-
end
|
|
75
|
+
|
|
76
|
+
def has_index_column?( col )
|
|
77
|
+
@index_columns.include?( col.to_sym )
|
|
36
78
|
end
|
|
37
79
|
|
|
38
80
|
# Reindexes the record lookup tables.
|
|
39
|
-
def reindex
|
|
40
|
-
|
|
41
|
-
|
|
81
|
+
def reindex( *cols )
|
|
82
|
+
# for column in (columns )
|
|
83
|
+
#
|
|
84
|
+
# @indexes = {}
|
|
85
|
+
# index_records( @records )
|
|
42
86
|
end
|
|
87
|
+
|
|
88
|
+
def empty_indexes( *cols )
|
|
89
|
+
raise_unless_index_columns( cols )
|
|
90
|
+
|
|
91
|
+
icols = @index_columns if cols.fwf_blank?
|
|
92
|
+
|
|
93
|
+
for icol in icols
|
|
94
|
+
@indexes[icol.to_sym] = {}
|
|
95
|
+
end
|
|
96
|
+
end
|
|
43
97
|
|
|
44
98
|
# shouldn't require reindex
|
|
45
|
-
def rename_index_column(
|
|
46
|
-
@index_columns[ @index_columns.index(
|
|
47
|
-
@indexes[new_name] = @indexes
|
|
48
|
-
|
|
99
|
+
def rename_index_column( old_name, new_name )
|
|
100
|
+
@index_columns[ @index_columns.index( old_name ) ] = new_name
|
|
101
|
+
@indexes[new_name] = @indexes.delete( old_name )
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
def remove_index_column( column_name )
|
|
105
|
+
raise_unless_index_columns( column_name )
|
|
106
|
+
|
|
107
|
+
@indexes.delete( column_name.sym )
|
|
108
|
+
@index_columns.delete( column_name.sym )
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
protected
|
|
112
|
+
# def each_index_column( cols = @index_columns, &block )
|
|
113
|
+
# raise_unless_index_columns( cols )
|
|
114
|
+
#
|
|
115
|
+
# for col in cols
|
|
116
|
+
# yield col.to_sym
|
|
117
|
+
# end
|
|
118
|
+
# end
|
|
119
|
+
|
|
120
|
+
def raise_unless_index_columns( *cols )
|
|
121
|
+
absent_columns = cols.reject{ |col| self.has_index_column?( col ) }
|
|
122
|
+
|
|
123
|
+
raise MissingColumnError.new( "Not an index column(s): #{absent_columns.inspect}" ) unless absent_columns.fwf_blank?
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
def raise_if_index_columns( *cols )
|
|
127
|
+
present_columns = cols.detect{ |col| self.has_index_column?( col ) }
|
|
128
|
+
|
|
129
|
+
raise MissingColumnError.new( "Index column(s) already exist: #{present_columns.inspect}" ) unless present_columns.fwf_blank?
|
|
49
130
|
end
|
|
50
131
|
end
|
|
51
132
|
end
|
|
@@ -1,64 +1,101 @@
|
|
|
1
1
|
module CsvMadness
|
|
2
2
|
module SheetMethods
|
|
3
3
|
module RecordMethods
|
|
4
|
-
def add_record( record )
|
|
4
|
+
def add_record( record, &block )
|
|
5
5
|
case record
|
|
6
6
|
when Array
|
|
7
|
-
#
|
|
8
|
-
record = CSV::Row.new( self.columns, record )
|
|
7
|
+
# do nothing
|
|
9
8
|
when Hash
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
9
|
+
record = @column_mapping.inject( [] ) do |memo, col_and_index|
|
|
10
|
+
col, index = col_and_index
|
|
11
|
+
|
|
12
|
+
if record.has_key?( col )
|
|
13
|
+
val = record[col]
|
|
14
|
+
elsif record.has_key?( col.to_s )
|
|
15
|
+
val = record[col.to_s]
|
|
16
|
+
else
|
|
17
|
+
val = nil
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
if index >= memo.length
|
|
21
|
+
memo.insert( index, val )
|
|
22
|
+
else
|
|
23
|
+
memo[index] = val
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
memo
|
|
16
27
|
end
|
|
17
|
-
|
|
18
|
-
record = CSV::Row.new( header, fields )
|
|
19
28
|
when CSV::Row
|
|
20
|
-
|
|
29
|
+
record = record.to_a.map( &:last )
|
|
30
|
+
when CsvMadness::Record
|
|
31
|
+
# TODO: But what if the two records aren't from the same kinds of sheet
|
|
32
|
+
# IOW, different columns or columns in different orders, etc.
|
|
33
|
+
record = record.data
|
|
21
34
|
else
|
|
22
35
|
raise "sheet.add_record() doesn't take objects of type #{record.inspect}" unless record.respond_to?(:csv_data)
|
|
23
36
|
record = record.csv_data
|
|
24
37
|
end
|
|
25
|
-
|
|
26
|
-
record =
|
|
38
|
+
|
|
39
|
+
record = Record.new( record, self )
|
|
40
|
+
|
|
27
41
|
@records << record
|
|
28
|
-
|
|
42
|
+
|
|
43
|
+
yield record if block_given?
|
|
44
|
+
|
|
45
|
+
index_records( record ) if indexing_enabled?
|
|
46
|
+
|
|
47
|
+
record
|
|
29
48
|
end
|
|
30
49
|
|
|
31
50
|
alias :<< :add_record
|
|
32
51
|
|
|
33
52
|
def add_blank_record( &block )
|
|
34
|
-
self.add_record(
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
53
|
+
self.add_record( [], &block )
|
|
54
|
+
#
|
|
55
|
+
# if block_given?
|
|
56
|
+
# yield self.records.last
|
|
57
|
+
# else
|
|
58
|
+
# self.records.last
|
|
59
|
+
# end
|
|
40
60
|
end
|
|
41
61
|
|
|
42
62
|
# record can be the row number (integer from 0...@records.length)
|
|
43
|
-
# record can be the record itself
|
|
63
|
+
# record can be the record itself
|
|
64
|
+
#
|
|
65
|
+
# returns the record that was removed.
|
|
44
66
|
def remove_record( record )
|
|
45
|
-
|
|
46
|
-
|
|
67
|
+
if record.is_a?(Integer)
|
|
68
|
+
record = remove_record_at_index( record )
|
|
69
|
+
else
|
|
70
|
+
record = self.records.delete( record )
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
self.unindex_record( record ) if indexing_enabled?
|
|
74
|
+
record
|
|
75
|
+
end
|
|
47
76
|
|
|
48
|
-
|
|
49
|
-
|
|
77
|
+
def remove_record_at_index( index )
|
|
78
|
+
self.records.delete_at( index )
|
|
50
79
|
end
|
|
51
80
|
|
|
52
|
-
# Here's the deal: you hand
|
|
53
|
-
# it
|
|
81
|
+
# Here's the deal: you hand it an array of records (or indexes, or a mix of the two),
|
|
82
|
+
# and it will remove the records (or the index... may want to test the indexing thing).
|
|
83
|
+
# If you give it a block, and it'll remove all the records for which
|
|
84
|
+
# the block yields _true_.
|
|
85
|
+
#
|
|
86
|
+
# returns an array of the removed records, in case you want them for anything.
|
|
54
87
|
def remove_records( records = nil, &block )
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
88
|
+
[].tap do |removed|
|
|
89
|
+
if block_given?
|
|
90
|
+
for record in @records
|
|
91
|
+
removed << self.remove_record( record ) if yield( record ) == true
|
|
92
|
+
end
|
|
93
|
+
else # records should be an array
|
|
94
|
+
records = records.map{ |r| r.is_a?( Integer ) ? self[r] : r } # turn indexes into records
|
|
95
|
+
|
|
96
|
+
for record in records
|
|
97
|
+
removed << self.remove_record( record )
|
|
98
|
+
end
|
|
62
99
|
end
|
|
63
100
|
end
|
|
64
101
|
end
|
|
@@ -68,32 +105,71 @@ module CsvMadness
|
|
|
68
105
|
# same order that the keying objects appear.
|
|
69
106
|
# Index column should yield a different, unique value for each record.
|
|
70
107
|
def fetch( index_col, key )
|
|
71
|
-
if
|
|
72
|
-
key.
|
|
108
|
+
if indexing_enabled?
|
|
109
|
+
if key.is_a?(Array)
|
|
110
|
+
key.map{ |k| @indexes[index_col][k] }
|
|
111
|
+
else
|
|
112
|
+
@indexes[index_col][key]
|
|
113
|
+
end
|
|
73
114
|
else
|
|
74
|
-
|
|
115
|
+
if key.is_a?(Array)
|
|
116
|
+
key.map{ |k| self.fetch( index_col, k ) }
|
|
117
|
+
else
|
|
118
|
+
index = index_of_column( index_col )
|
|
119
|
+
@records.detect{ |r| r.data[index] == key }
|
|
120
|
+
end
|
|
75
121
|
end
|
|
76
122
|
end
|
|
77
123
|
|
|
78
124
|
# function should take an object, and return either true or false
|
|
79
125
|
# returns an array of objects that respond true when put through the
|
|
80
126
|
# meat grinder
|
|
81
|
-
def filter( &block )
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
127
|
+
def filter( record_filter = nil, &block )
|
|
128
|
+
if block_given?
|
|
129
|
+
filtered_records = []
|
|
130
|
+
|
|
131
|
+
@records.each do |record|
|
|
132
|
+
filtered_records << record if ( yield record )
|
|
133
|
+
end
|
|
134
|
+
elsif record_filter
|
|
135
|
+
filtered_records = record_filter.apply( @records )
|
|
136
|
+
else
|
|
137
|
+
warn "#{self.class}.filter called without block or RecordFilter.. "
|
|
138
|
+
filtered_records = @records
|
|
85
139
|
end
|
|
86
|
-
|
|
87
|
-
|
|
140
|
+
|
|
141
|
+
return filtered_records
|
|
88
142
|
end
|
|
89
143
|
|
|
90
144
|
# removes rows which fail the given test from the spreadsheet.
|
|
91
145
|
# TODO! Should be returning self rather than the records.a
|
|
92
|
-
def filter!( &block )
|
|
93
|
-
@records = self.filter( &block )
|
|
94
|
-
reindex
|
|
146
|
+
def filter!( record_filter = nil, &block )
|
|
147
|
+
@records = self.filter( record_filter, &block )
|
|
148
|
+
reindex if indexing_enabled?
|
|
95
149
|
@records
|
|
96
150
|
end
|
|
151
|
+
|
|
152
|
+
def extra_method?( m )
|
|
153
|
+
@extra_methods.keys.include?( m )
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
# The method given should take a record, return... well, anything.
|
|
157
|
+
def add_extra_method( method, &block )
|
|
158
|
+
@extra_methods[method.to_sym] = block
|
|
159
|
+
end
|
|
160
|
+
|
|
161
|
+
def remove_extra_method( method )
|
|
162
|
+
@extra_methods.delete( method.to_sym )
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
def call_extra_method( method, *args )
|
|
166
|
+
@extra_methods[method.to_sym].call( *args )
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
|
|
170
|
+
def convert_types( record )
|
|
171
|
+
|
|
172
|
+
end
|
|
97
173
|
end
|
|
98
174
|
end
|
|
99
175
|
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
module CsvMadness
|
|
2
|
+
module Utils
|
|
3
|
+
class ConstProc < Proc
|
|
4
|
+
def initialize( val, &block )
|
|
5
|
+
@rval = val
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
def call(*args,&block)
|
|
9
|
+
@rval
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def self.proc_for( val )
|
|
13
|
+
ConstProc.new( val ) do
|
|
14
|
+
:does_nothing
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
module CsvMadness
|
|
2
|
+
module Utils
|
|
3
|
+
class Counter
|
|
4
|
+
attr_reader :value
|
|
5
|
+
|
|
6
|
+
def initialize( initial_value = 0 )
|
|
7
|
+
@initial_value = initial_value
|
|
8
|
+
self.reset
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def click
|
|
12
|
+
@value += 1
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def reset
|
|
16
|
+
@value = resets_to()
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def resets_to
|
|
20
|
+
@initial_value
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
module CsvMadness
|
|
2
|
+
module Utils
|
|
3
|
+
class CounterProc < Proc
|
|
4
|
+
def initialize( initial_value, &block )
|
|
5
|
+
@counter = Counter.new( initial_value )
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
# Each call return the value of the internal counter at the time the call mas made.
|
|
9
|
+
# Which is one lower than the number of times called. Hence the existence of the times_called method
|
|
10
|
+
def call(*args,&block)
|
|
11
|
+
rval = @counter.value
|
|
12
|
+
@counter.click
|
|
13
|
+
rval
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def reset
|
|
17
|
+
@counter.reset
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def times_called
|
|
21
|
+
@counter.value - @counter.resets_to
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def self.counter( initial_value = 0 )
|
|
25
|
+
self.new( initial_value ) do
|
|
26
|
+
:proc_does_nothing
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
module CsvMadness
|
|
2
|
+
module Utils
|
|
3
|
+
# Fast insert/remove/lookup indexing utility.
|
|
4
|
+
#
|
|
5
|
+
# For example, if you're keeping an index of a spreadsheet column, and you want to be able at any moment to get the records
|
|
6
|
+
# containing that value (id = 7124) or (name = 'Mary'),
|
|
7
|
+
#
|
|
8
|
+
# Is it a hash? Two hashes?
|
|
9
|
+
# It's like a hash because...
|
|
10
|
+
#
|
|
11
|
+
# It's like an array because order needs to be preserved.
|
|
12
|
+
#
|
|
13
|
+
# - insert( key, val )
|
|
14
|
+
# - add_to_result_index
|
|
15
|
+
# - add_position_in_result_index_to removal index
|
|
16
|
+
# -
|
|
17
|
+
# - update( key, val )
|
|
18
|
+
#
|
|
19
|
+
# - remove( val )
|
|
20
|
+
#
|
|
21
|
+
# - fetch_results( key )
|
|
22
|
+
#
|
|
23
|
+
# Is the order important? Definitely. But that means re-indexing whenever the record order changes?
|
|
24
|
+
#
|
|
25
|
+
# results_data
|
|
26
|
+
# removal_data
|
|
27
|
+
# ordering_data ... shared by multiple
|
|
28
|
+
|
|
29
|
+
# lu = LookerUpper.new
|
|
30
|
+
# lu.keep( )
|
|
31
|
+
|
|
32
|
+
class LookerUpper
|
|
33
|
+
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
data/lib/csv_madness.rb
CHANGED
|
File without changes
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
"id","number","integer","float","date"
|
|
1
|
+
"id","number","integer","float","date","string"
|
|
2
2
|
,,,,
|
|
3
|
-
12,134.2,100,123.4,2013-01-13
|
|
3
|
+
12,134.2,100,123.4,2013-01-13,"I am the very model of a coding individual"
|
data/test/helper.rb
CHANGED
|
@@ -38,22 +38,22 @@ class MadTestCase < FunWith::Testing::TestCase # Test::Unit::TestCase
|
|
|
38
38
|
end
|
|
39
39
|
|
|
40
40
|
def load_mary
|
|
41
|
-
id = @simple.
|
|
41
|
+
id = @simple.columns.first
|
|
42
42
|
@mary = @simple.fetch( id, MARY_ID )
|
|
43
43
|
end
|
|
44
44
|
|
|
45
45
|
def load_bill
|
|
46
|
-
id = @simple.
|
|
46
|
+
id = @simple.columns.first
|
|
47
47
|
@bill = @simple.fetch( id, BILL_ID )
|
|
48
48
|
end
|
|
49
49
|
|
|
50
50
|
def load_darwin
|
|
51
|
-
id = @simple.
|
|
51
|
+
id = @simple.columns.first
|
|
52
52
|
@darwin = @simple.fetch( id, DARWIN_ID )
|
|
53
53
|
end
|
|
54
54
|
|
|
55
55
|
def load_chuck
|
|
56
|
-
id = @simple.
|
|
56
|
+
id = @simple.columns.first
|
|
57
57
|
@chuck = @simple.fetch( id, CHUCK_ID )
|
|
58
58
|
end
|
|
59
59
|
|
|
@@ -65,7 +65,6 @@ class MadTestCase < FunWith::Testing::TestCase # Test::Unit::TestCase
|
|
|
65
65
|
end
|
|
66
66
|
|
|
67
67
|
def muck_up_spreadsheet
|
|
68
|
-
debugger
|
|
69
68
|
@simple.add_column(:scrambled_name) do |val, record|
|
|
70
69
|
record.fname.chars.map(&:to_s).zip( record.lname.chars.map(&:to_s) ).flatten.compact.join
|
|
71
70
|
end
|
|
@@ -80,8 +79,12 @@ class MadTestCase < FunWith::Testing::TestCase # Test::Unit::TestCase
|
|
|
80
79
|
@simple.alter_column(:born) do |val|
|
|
81
80
|
if val.is_a?(String)
|
|
82
81
|
-1.0
|
|
83
|
-
|
|
82
|
+
elsif val.is_a?(Date)
|
|
83
|
+
val.wday
|
|
84
|
+
elsif val.is_a?(Time)
|
|
84
85
|
(Time.now - val).to_f
|
|
86
|
+
else
|
|
87
|
+
57.3
|
|
85
88
|
end
|
|
86
89
|
end
|
|
87
90
|
|
data/test/test_builder.rb
CHANGED
|
@@ -34,4 +34,40 @@ class TestBuilder < MadTestCase
|
|
|
34
34
|
assert_equal 4225, ss.records.first.square
|
|
35
35
|
end
|
|
36
36
|
end
|
|
37
|
+
|
|
38
|
+
context "testing convenience column methods" do
|
|
39
|
+
setup do
|
|
40
|
+
@builder = CsvMadness::Builder.new do |s|
|
|
41
|
+
s.constant_column :string, "String"
|
|
42
|
+
s.constant_column :int, 5
|
|
43
|
+
s.constant_column :sym, :sym
|
|
44
|
+
s.blank_column :blank
|
|
45
|
+
s.counter_column :line, 1
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
@sheet = @builder.build( [nil, nil, nil] )
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
should "calculate the resulting sheet accurately" do
|
|
52
|
+
assert_equal [nil,nil,nil], @sheet.column( :blank )
|
|
53
|
+
assert_equal ["String", "String", "String"], @sheet.column( :string )
|
|
54
|
+
assert_equal 3, @sheet.records.last.line
|
|
55
|
+
assert_equal :sym, @sheet.records[0].sym
|
|
56
|
+
assert_equal 5, @sheet.records[1].int
|
|
57
|
+
assert_equal 5, @sheet.records[0][1]
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
should "add a record without a dumpster fire ensuing" do
|
|
61
|
+
data = [7] * @builder.column_names.length
|
|
62
|
+
|
|
63
|
+
@sheet.add_record( data )
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
r = @sheet.records.last
|
|
67
|
+
|
|
68
|
+
for sym in @builder.column_names
|
|
69
|
+
assert_equal 7, r.send( sym )
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
end
|
|
37
73
|
end
|