fat_core 1.2.5 → 1.2.6
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.
- checksums.yaml +4 -4
- data/lib/fat_core/column.rb +117 -43
- data/lib/fat_core/table.rb +1 -4
- data/lib/fat_core/version.rb +1 -1
- data/spec/lib/column_spec.rb +208 -0
- metadata +3 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5c93e591807760bad4ae026e144c216d03fbe3d7
|
4
|
+
data.tar.gz: 0a7bcf980e22635bdb4880e5ba140544ce03530d
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 91bdb2d5b8cf2dc577967462433c73fa18f6de41c72ed27564e3cf5dacecc60825ecac131aea4f1a6182e24fbecd18b3b0d752a27bee0de258446baa705dd421
|
7
|
+
data.tar.gz: aa85f79b609f356e333adb6816a9764b2bcf1cad2f7bd5e7ba1a00ef83c81310302d450b81d403890c9d5c808b208435d3fa10db97aa778a5938e3d5b0eba817
|
data/lib/fat_core/column.rb
CHANGED
@@ -6,18 +6,19 @@ module FatCore
|
|
6
6
|
class Column
|
7
7
|
attr_reader :header, :type, :items
|
8
8
|
|
9
|
-
TYPES = %w(NilClass
|
9
|
+
TYPES = %w(NilClass Boolean DateTime Numeric String)
|
10
10
|
|
11
|
-
def initialize(header:,
|
11
|
+
def initialize(header:, items: [])
|
12
12
|
@header = header.as_sym
|
13
|
-
@type =
|
13
|
+
@type = 'NilClass'
|
14
14
|
raise "Unknown column type '#{type}" unless TYPES.include?(@type.to_s)
|
15
|
-
@items =
|
15
|
+
@items = []
|
16
|
+
items.each { |i| self << i }
|
16
17
|
end
|
17
18
|
|
18
|
-
|
19
|
-
|
20
|
-
|
19
|
+
##########################################################################
|
20
|
+
# Attributes
|
21
|
+
##########################################################################
|
21
22
|
|
22
23
|
def [](k)
|
23
24
|
items[k]
|
@@ -31,16 +32,17 @@ module FatCore
|
|
31
32
|
items.size
|
32
33
|
end
|
33
34
|
|
35
|
+
def empty?
|
36
|
+
items.empty?
|
37
|
+
end
|
38
|
+
|
34
39
|
def last_i
|
35
40
|
size - 1
|
36
41
|
end
|
37
42
|
|
38
|
-
|
39
|
-
#
|
40
|
-
|
41
|
-
raise 'Cannot combine columns with different types' unless type == other.type
|
42
|
-
Column.new(header: header, type: type, items: items + other.items)
|
43
|
-
end
|
43
|
+
##########################################################################
|
44
|
+
# Aggregates
|
45
|
+
##########################################################################
|
44
46
|
|
45
47
|
def first
|
46
48
|
items.compact.first
|
@@ -56,21 +58,78 @@ module FatCore
|
|
56
58
|
end
|
57
59
|
|
58
60
|
def sum
|
61
|
+
only_with('sum', 'Numeric', 'String')
|
59
62
|
items.compact.sum
|
60
63
|
end
|
61
64
|
|
62
65
|
def min
|
66
|
+
only_with('min', 'NilClass', 'Numeric', 'String', 'DateTime')
|
63
67
|
items.compact.min
|
64
68
|
end
|
65
69
|
|
66
70
|
def max
|
71
|
+
only_with('max', 'NilClass', 'Numeric', 'String', 'DateTime')
|
67
72
|
items.compact.max
|
68
73
|
end
|
69
74
|
|
70
75
|
def avg
|
71
|
-
|
76
|
+
only_with('avg', 'DateTime', 'Numeric')
|
77
|
+
if type == 'DateTime'
|
78
|
+
avg_jd = items.compact.map(&:jd).sum / items.compact.size.to_d
|
79
|
+
DateTime.jd(avg_jd)
|
80
|
+
else
|
81
|
+
sum / items.compact.size.to_d
|
82
|
+
end
|
72
83
|
end
|
73
84
|
|
85
|
+
def any?
|
86
|
+
only_with('any?', 'Boolean')
|
87
|
+
items.compact.any?
|
88
|
+
end
|
89
|
+
|
90
|
+
def all?
|
91
|
+
only_with('all?', 'Boolean')
|
92
|
+
items.compact.all?
|
93
|
+
end
|
94
|
+
|
95
|
+
def none?
|
96
|
+
only_with('any?', 'Boolean')
|
97
|
+
items.compact.none?
|
98
|
+
end
|
99
|
+
|
100
|
+
def one?
|
101
|
+
only_with('any?', 'Boolean')
|
102
|
+
items.compact.one?
|
103
|
+
end
|
104
|
+
|
105
|
+
private
|
106
|
+
|
107
|
+
def only_with(agg, *types)
|
108
|
+
unless types.include?(type)
|
109
|
+
raise "Aggregate '#{agg}' cannot be applied to a #{type} column"
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
public
|
114
|
+
|
115
|
+
##########################################################################
|
116
|
+
# Construction
|
117
|
+
##########################################################################
|
118
|
+
|
119
|
+
# Append item to end of the column
|
120
|
+
def <<(itm)
|
121
|
+
items << convert_to_type(itm)
|
122
|
+
end
|
123
|
+
|
124
|
+
# Return a new Column appending the items of other to our items, checking
|
125
|
+
# for type compatibility.
|
126
|
+
def +(other)
|
127
|
+
raise 'Cannot combine columns with different types' unless type == other.type
|
128
|
+
Column.new(header: header, items: items + other.items)
|
129
|
+
end
|
130
|
+
|
131
|
+
private
|
132
|
+
|
74
133
|
# Convert val to the type of key, a ruby class constant, such as Date,
|
75
134
|
# Numeric, etc. If type is NilClass, the type is open, and a non-blank val
|
76
135
|
# will attempt conversion to one of the allowed types, typing it as a String
|
@@ -87,12 +146,11 @@ module FatCore
|
|
87
146
|
if val != false && val.blank?
|
88
147
|
# Leave the type of the column open. Unfortunately, false counts as
|
89
148
|
# blank and we don't want it to. It should be classified as a boolean.
|
90
|
-
|
149
|
+
new_val = nil
|
91
150
|
else
|
92
151
|
# Only non-blank values are allowed to set the type of the column
|
93
|
-
val_class = val.class
|
94
152
|
bool_val = convert_to_boolean(val)
|
95
|
-
|
153
|
+
new_val =
|
96
154
|
if bool_val.nil?
|
97
155
|
convert_to_date_time(val) ||
|
98
156
|
convert_to_numeric(val) ||
|
@@ -101,45 +159,61 @@ module FatCore
|
|
101
159
|
bool_val
|
102
160
|
end
|
103
161
|
@type =
|
104
|
-
if
|
162
|
+
if new_val == true || new_val == false
|
105
163
|
'Boolean'
|
106
|
-
elsif
|
164
|
+
elsif new_val.is_a?(Date) || new_val.is_a?(DateTime)
|
165
|
+
'DateTime'
|
166
|
+
elsif new_val.is_a?(Numeric)
|
107
167
|
'Numeric'
|
168
|
+
elsif new_val.is_a?(String)
|
169
|
+
'String'
|
108
170
|
else
|
109
|
-
val.class.name
|
171
|
+
raise "Cannot add #{val} of type #{new_val.class.name} to a column"
|
110
172
|
end
|
111
173
|
end
|
112
|
-
|
113
|
-
when 'Boolean'
|
114
|
-
val_class = val.class
|
115
|
-
val = convert_to_boolean(val)
|
174
|
+
new_val
|
175
|
+
when 'Boolean'
|
116
176
|
if val.nil?
|
117
|
-
|
177
|
+
nil
|
178
|
+
else
|
179
|
+
new_val = convert_to_boolean(val)
|
180
|
+
if new_val.nil?
|
181
|
+
raise "Attempt to add '#{val}' to a column already typed as #{type}"
|
182
|
+
end
|
183
|
+
new_val
|
118
184
|
end
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
185
|
+
when 'DateTime'
|
186
|
+
if val.nil?
|
187
|
+
nil
|
188
|
+
else
|
189
|
+
new_val = convert_to_date_time(val)
|
190
|
+
if new_val.nil?
|
191
|
+
raise "Attempt to add '#{val}' to a column already typed as #{type}"
|
192
|
+
end
|
193
|
+
new_val
|
125
194
|
end
|
126
|
-
val
|
127
195
|
when 'Numeric'
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
196
|
+
if val.nil?
|
197
|
+
nil
|
198
|
+
else
|
199
|
+
new_val = convert_to_numeric(val)
|
200
|
+
if new_val.nil?
|
201
|
+
raise "Attempt to add '#{val}' to a column already typed as #{type}"
|
202
|
+
end
|
203
|
+
new_val
|
132
204
|
end
|
133
|
-
val
|
134
205
|
when 'String'
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
206
|
+
if val.nil?
|
207
|
+
nil
|
208
|
+
else
|
209
|
+
new_val = convert_to_string(val)
|
210
|
+
if new_val.nil?
|
211
|
+
raise "Attempt to add '#{val}' to a column already typed as #{type}"
|
212
|
+
end
|
213
|
+
new_val
|
139
214
|
end
|
140
|
-
val
|
141
215
|
else
|
142
|
-
raise "
|
216
|
+
raise "Mysteriously, column has unknown type '#{type}'"
|
143
217
|
end
|
144
218
|
end
|
145
219
|
|
data/lib/fat_core/table.rb
CHANGED
@@ -174,7 +174,6 @@ module FatCore
|
|
174
174
|
raise "Header #{h} does not exist" unless headers.include?(h)
|
175
175
|
new_heads << h
|
176
176
|
new_cols[h] = Column.new(header: h,
|
177
|
-
type: column(h).type,
|
178
177
|
items: column(h).items)
|
179
178
|
when Hash
|
180
179
|
exp.each_pair do |key, xp|
|
@@ -184,7 +183,6 @@ module FatCore
|
|
184
183
|
raise "Header #{key} does not exist" unless column?(key)
|
185
184
|
new_heads << h
|
186
185
|
new_cols[h] = Column.new(header: h,
|
187
|
-
type: column(key).type,
|
188
186
|
items: column(key).items)
|
189
187
|
when String
|
190
188
|
# Evaluate xp in the context of a binding including a local
|
@@ -314,8 +312,7 @@ module FatCore
|
|
314
312
|
items = rows.map { |r| r[h] }
|
315
313
|
new_h = "#{agg_func}_#{h}"
|
316
314
|
new_row[new_h] = Column.new(header: h,
|
317
|
-
|
318
|
-
type: column(h).type).send(agg_func)
|
315
|
+
items: items).send(agg_func)
|
319
316
|
end
|
320
317
|
new_row
|
321
318
|
end
|
data/lib/fat_core/version.rb
CHANGED
@@ -0,0 +1,208 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
module FatCore
|
4
|
+
describe Column do
|
5
|
+
describe 'construction' do
|
6
|
+
it 'should be able to append items to the column' do
|
7
|
+
c = Column.new(header: 'junk')
|
8
|
+
expect(c.type).to eq('NilClass')
|
9
|
+
c << '2.71828'
|
10
|
+
expect(c.items).to eq([2.71828])
|
11
|
+
expect(c.type).to eq('Numeric')
|
12
|
+
end
|
13
|
+
|
14
|
+
it 'should leave the type of an all-nil column open' do
|
15
|
+
c = Column.new(header: :bool, items: [nil, nil, nil, nil])
|
16
|
+
expect(c.type).to eq('NilClass')
|
17
|
+
expect(c[0]).to eq(nil)
|
18
|
+
expect(c[1]).to eq(nil)
|
19
|
+
expect(c[2]).to eq(nil)
|
20
|
+
expect(c[3]).to eq(nil)
|
21
|
+
# But then, assign a type when a recognizable type comes along.
|
22
|
+
c << '625.18'
|
23
|
+
expect(c.type).to eq('Numeric')
|
24
|
+
expect { c << '2018-05-06' }.to raise_error /already typed as Numeric/
|
25
|
+
end
|
26
|
+
|
27
|
+
it 'should recognize boolean columns' do
|
28
|
+
c = Column.new(header: :bool, items: [nil, 'F', 'F', 'T'])
|
29
|
+
expect(c.type).to eq('Boolean')
|
30
|
+
c = Column.new(header: :bool,
|
31
|
+
items: [nil, 'N', 'no', 'yes', 'false', 'TRUE', nil])
|
32
|
+
expect(c.type).to eq('Boolean')
|
33
|
+
expect(c[0]).to eq(nil)
|
34
|
+
expect(c[1]).to eq(false)
|
35
|
+
expect(c[2]).to eq(false)
|
36
|
+
expect(c[3]).to eq(true)
|
37
|
+
expect(c[4]).to eq(false)
|
38
|
+
expect(c[5]).to eq(true)
|
39
|
+
expect(c[6]).to eq(nil)
|
40
|
+
end
|
41
|
+
|
42
|
+
it 'should recognize DateTime columns but allow Date and nil' do
|
43
|
+
c = Column.new(header: :when,
|
44
|
+
items: [nil, '2015-01-21', '[2015-01-12]',
|
45
|
+
'<2011-01-06>', nil, '<2017-01-25 Wed 10:00>'])
|
46
|
+
expect(c.type).to eq('DateTime')
|
47
|
+
expect(c[0]).to eq(nil)
|
48
|
+
expect(c[1]).to eq(Date.parse('2015-01-21'))
|
49
|
+
expect(c[2]).to eq(Date.parse('2015-01-12'))
|
50
|
+
expect(c[3]).to eq(Date.parse('2011-01-06'))
|
51
|
+
expect(c[4]).to eq(nil)
|
52
|
+
expect(c[5]).to eq(DateTime.parse('2017-01-25 Wed 10:00'))
|
53
|
+
expect(c[1].class).to eq(Date)
|
54
|
+
expect(c[5].class).to eq(DateTime)
|
55
|
+
end
|
56
|
+
|
57
|
+
it 'should recognize Numeric columns but allow nils and Integers' do
|
58
|
+
c = Column.new(header: :when,
|
59
|
+
items: [nil, '20151', '3.14159',
|
60
|
+
BigDecimal('2.718281828'), nil,
|
61
|
+
'45024098204982340982049802348'])
|
62
|
+
expect(c.type).to eq('Numeric')
|
63
|
+
expect(c[0]).to eq(nil)
|
64
|
+
expect(c[1]).to eq(20151)
|
65
|
+
expect(c[2]).to eq(3.14159)
|
66
|
+
expect(c[3]).to eq(2.718281828)
|
67
|
+
expect(c[4]).to eq(nil)
|
68
|
+
expect(c[5]).to eq(45024098204982340982049802348)
|
69
|
+
expect(c[0].class).to eq(NilClass)
|
70
|
+
expect(c[1].class).to eq(Fixnum)
|
71
|
+
expect(c[2].class).to eq(BigDecimal)
|
72
|
+
expect(c[3].class).to eq(BigDecimal)
|
73
|
+
expect(c[4].class).to eq(NilClass)
|
74
|
+
expect(c[5].class).to eq(Bignum)
|
75
|
+
end
|
76
|
+
|
77
|
+
it 'should recognize String columns but allow nils and Integers' do
|
78
|
+
c = Column.new(header: :when,
|
79
|
+
items: [nil, 'Four', 'score', 'and', nil, '7 years'])
|
80
|
+
expect(c.type).to eq('String')
|
81
|
+
expect(c[0]).to eq(nil)
|
82
|
+
expect(c[1]).to eq('Four')
|
83
|
+
expect(c[2]).to eq('score')
|
84
|
+
expect(c[3]).to eq('and')
|
85
|
+
expect(c[4]).to eq(nil)
|
86
|
+
expect(c[5]).to eq('7 years')
|
87
|
+
expect(c[0].class).to eq(NilClass)
|
88
|
+
expect(c[1].class).to eq(String)
|
89
|
+
expect(c[2].class).to eq(String)
|
90
|
+
expect(c[3].class).to eq(String)
|
91
|
+
expect(c[4].class).to eq(NilClass)
|
92
|
+
expect(c[5].class).to eq(String)
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
describe 'attribute getting and setting' do
|
97
|
+
it 'should be able to retrieve items by index number' do
|
98
|
+
c = Column.new(header: :when,
|
99
|
+
items: [nil, '20151', '3.14159',
|
100
|
+
BigDecimal('2.718281828'), nil,
|
101
|
+
'45024098204982340982049802348'])
|
102
|
+
expect(c[0]).to eq(nil)
|
103
|
+
expect(c[1]).to eq(20151)
|
104
|
+
expect(c[2]).to eq(3.14159)
|
105
|
+
expect(c[3]).to eq(2.718281828)
|
106
|
+
expect(c[4]).to eq(nil)
|
107
|
+
expect(c[5]).to eq(45024098204982340982049802348)
|
108
|
+
end
|
109
|
+
|
110
|
+
it 'should respond to to_a, size, empty?, and last_i' do
|
111
|
+
arr = [nil, '20151', '3.14159',
|
112
|
+
BigDecimal('2.718281828'), nil,
|
113
|
+
'45024098204982340982049802348']
|
114
|
+
c = Column.new(header: :when, items: arr)
|
115
|
+
expect(c.to_a).to eq([nil, 20151, 3.14159, 2.718281828,
|
116
|
+
nil, 45024098204982340982049802348])
|
117
|
+
expect(c.to_a.class).to eq(Array)
|
118
|
+
expect(c.size).to eq(6)
|
119
|
+
expect(c.empty?).to eq(false)
|
120
|
+
expect(c.last_i).to eq(5)
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
describe 'aggregates' do
|
125
|
+
before :each do
|
126
|
+
@nil_col =
|
127
|
+
Column.new(header: :none, items: [nil, nil, nil, nil])
|
128
|
+
@bool_col =
|
129
|
+
Column.new(header: :bool,
|
130
|
+
items: [nil, 'N', 'no', 'yes', 'false', 'TRUE', nil])
|
131
|
+
@date_col =
|
132
|
+
Column.new(header: :when,
|
133
|
+
items: [nil, '2015-01-21', '[2015-01-12]',
|
134
|
+
'<2011-01-06>', nil, '<2017-01-25 Wed 10:00>'])
|
135
|
+
@num_col =
|
136
|
+
Column.new(header: :nums,
|
137
|
+
items: [nil, '20151', '3.14159',
|
138
|
+
BigDecimal('2.718281828'), nil, '45024'])
|
139
|
+
@str_col =
|
140
|
+
Column.new(header: :strs,
|
141
|
+
items: [nil, 'Four', 'score', 'and', nil, '7 years'])
|
142
|
+
end
|
143
|
+
|
144
|
+
it 'should be able apply to first to appropriate columns' do
|
145
|
+
expect(@nil_col.first).to eq(nil)
|
146
|
+
expect(@bool_col.first).to eq(false)
|
147
|
+
expect(@date_col.first).to eq(Date.parse('2015-01-21'))
|
148
|
+
expect(@num_col.first).to eq(20151)
|
149
|
+
expect(@str_col.first).to eq('Four')
|
150
|
+
end
|
151
|
+
|
152
|
+
it 'should be able to apply last to appropriate columns' do
|
153
|
+
expect(@nil_col.last).to eq(nil)
|
154
|
+
expect(@bool_col.last).to eq(true)
|
155
|
+
expect(@date_col.last).to eq(DateTime.parse('2017-01-25 10am'))
|
156
|
+
expect(@num_col.last).to eq(45024)
|
157
|
+
expect(@str_col.last).to eq('7 years')
|
158
|
+
end
|
159
|
+
|
160
|
+
it 'should be able to apply rng_s to appropriate columns' do
|
161
|
+
expect(@nil_col.rng_s).to eq('..')
|
162
|
+
expect(@bool_col.rng_s).to eq('false..true')
|
163
|
+
expect(@date_col.rng_s).to eq('2015-01-21..2017-01-25T10:00:00+00:00')
|
164
|
+
expect(@num_col.rng_s).to eq('20151..45024')
|
165
|
+
expect(@str_col.rng_s).to eq('Four..7 years')
|
166
|
+
end
|
167
|
+
|
168
|
+
it 'should be able to sum to appropriate columns' do
|
169
|
+
expect { @nil_col.sum }.to raise_error(/cannot be applied/)
|
170
|
+
expect { @bool_col.sum }.to raise_error(/cannot be applied/)
|
171
|
+
expect { @date_col.sum }.to raise_error(/cannot be applied/)
|
172
|
+
expect(@num_col.sum).to eq(65180.859871828)
|
173
|
+
expect(@str_col.sum).to eq('Fourscoreand7 years')
|
174
|
+
end
|
175
|
+
|
176
|
+
it 'should be able to min to appropriate columns' do
|
177
|
+
expect(@nil_col.min).to eq(nil)
|
178
|
+
expect { @bool_col.min }.to raise_error(/cannot be applied/)
|
179
|
+
expect(@date_col.min).to eq(Date.parse('2011-01-06'))
|
180
|
+
expect(@num_col.min).to eq(BigDecimal('2.718281828'))
|
181
|
+
expect(@str_col.min).to eq('7 years')
|
182
|
+
end
|
183
|
+
|
184
|
+
it 'should be able to max to appropriate columns' do
|
185
|
+
expect(@nil_col.max).to eq(nil)
|
186
|
+
expect { @bool_col.max }.to raise_error(/cannot be applied/)
|
187
|
+
expect(@date_col.max).to eq(DateTime.parse('2017-01-25 10am'))
|
188
|
+
expect(@num_col.max).to eq(45024)
|
189
|
+
expect(@str_col.max).to eq('score')
|
190
|
+
end
|
191
|
+
|
192
|
+
it 'should be able to apply avg to appropriate columns' do
|
193
|
+
expect { @nil_col.avg }.to raise_error(/cannot be applied/)
|
194
|
+
expect { @bool_col.avg }.to raise_error(/cannot be applied/)
|
195
|
+
expect(@date_col.avg).to eq(DateTime.parse('2014-07-17 12pm'))
|
196
|
+
expect(@num_col.avg).to eq(16295.214967957)
|
197
|
+
expect{ @str_col.avg }.to raise_error(/cannot be applied/)
|
198
|
+
end
|
199
|
+
|
200
|
+
it 'should be able to apply boolean aggregates to boolean columns' do
|
201
|
+
expect(@bool_col.any?).to eq(true)
|
202
|
+
expect(@bool_col.all?).to eq(false)
|
203
|
+
expect(@bool_col.none?).to eq(false)
|
204
|
+
expect(@bool_col.one?).to eq(false)
|
205
|
+
end
|
206
|
+
end
|
207
|
+
end
|
208
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fat_core
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.2.
|
4
|
+
version: 1.2.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Daniel E. Doherty
|
@@ -222,6 +222,7 @@ files:
|
|
222
222
|
- spec/example_files/goldberg.org
|
223
223
|
- spec/example_files/wpcs.csv
|
224
224
|
- spec/lib/array_spec.rb
|
225
|
+
- spec/lib/column_spec.rb
|
225
226
|
- spec/lib/date_spec.rb
|
226
227
|
- spec/lib/enumerable_spec.rb
|
227
228
|
- spec/lib/evaluator_spec.rb
|
@@ -264,6 +265,7 @@ test_files:
|
|
264
265
|
- spec/example_files/goldberg.org
|
265
266
|
- spec/example_files/wpcs.csv
|
266
267
|
- spec/lib/array_spec.rb
|
268
|
+
- spec/lib/column_spec.rb
|
267
269
|
- spec/lib/date_spec.rb
|
268
270
|
- spec/lib/enumerable_spec.rb
|
269
271
|
- spec/lib/evaluator_spec.rb
|