csv_decision 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.
Files changed (87) hide show
  1. checksums.yaml +4 -4
  2. data/.codeclimate.yml +2 -0
  3. data/.gitignore +2 -1
  4. data/.travis.yml +2 -3
  5. data/CHANGELOG.md +19 -1
  6. data/README.md +49 -16
  7. data/{benchmark.rb → benchmarks/rufus_decision.rb} +1 -1
  8. data/csv_decision.gemspec +1 -1
  9. data/doc/CSVDecision/CellValidationError.html +143 -0
  10. data/doc/CSVDecision/Columns/Default.html +409 -0
  11. data/doc/CSVDecision/Columns/Dictionary.html +410 -0
  12. data/doc/CSVDecision/Columns/Entry.html +321 -0
  13. data/doc/CSVDecision/Columns.html +476 -0
  14. data/doc/CSVDecision/Constant.html +295 -0
  15. data/doc/CSVDecision/Data.html +344 -0
  16. data/doc/CSVDecision/Decide.html +434 -0
  17. data/doc/CSVDecision/Decision.html +604 -0
  18. data/doc/CSVDecision/Error.html +139 -0
  19. data/doc/CSVDecision/FileError.html +143 -0
  20. data/doc/CSVDecision/Function.html +229 -0
  21. data/doc/CSVDecision/Header.html +520 -0
  22. data/doc/CSVDecision/Input.html +305 -0
  23. data/doc/CSVDecision/Load.html +225 -0
  24. data/doc/CSVDecision/Matchers/Constant.html +242 -0
  25. data/doc/CSVDecision/Matchers/Function.html +342 -0
  26. data/doc/CSVDecision/Matchers/Matcher.html +325 -0
  27. data/doc/CSVDecision/Matchers/Numeric.html +277 -0
  28. data/doc/CSVDecision/Matchers/Pattern.html +600 -0
  29. data/doc/CSVDecision/Matchers/Range.html +413 -0
  30. data/doc/CSVDecision/Matchers/Symbol.html +280 -0
  31. data/doc/CSVDecision/Matchers.html +1529 -0
  32. data/doc/CSVDecision/Numeric.html +259 -0
  33. data/doc/CSVDecision/Options.html +445 -0
  34. data/doc/CSVDecision/Parse.html +270 -0
  35. data/doc/CSVDecision/ScanRow.html +746 -0
  36. data/doc/CSVDecision/Symbol.html +256 -0
  37. data/doc/CSVDecision/Table.html +1115 -0
  38. data/doc/CSVDecision.html +652 -0
  39. data/doc/_index.html +410 -0
  40. data/doc/class_list.html +51 -0
  41. data/doc/css/common.css +1 -0
  42. data/doc/css/full_list.css +58 -0
  43. data/doc/css/style.css +499 -0
  44. data/doc/file.README.html +264 -0
  45. data/doc/file_list.html +56 -0
  46. data/doc/frames.html +17 -0
  47. data/doc/index.html +264 -0
  48. data/doc/js/app.js +248 -0
  49. data/doc/js/full_list.js +216 -0
  50. data/doc/js/jquery.js +4 -0
  51. data/doc/method_list.html +683 -0
  52. data/doc/top-level-namespace.html +110 -0
  53. data/lib/csv_decision/columns.rb +15 -12
  54. data/lib/csv_decision/constant.rb +54 -0
  55. data/lib/csv_decision/decide.rb +5 -5
  56. data/lib/csv_decision/decision.rb +3 -1
  57. data/lib/csv_decision/function.rb +32 -0
  58. data/lib/csv_decision/header.rb +27 -18
  59. data/lib/csv_decision/input.rb +11 -8
  60. data/lib/csv_decision/matchers/constant.rb +18 -0
  61. data/lib/csv_decision/matchers/function.rb +11 -44
  62. data/lib/csv_decision/matchers/numeric.rb +5 -33
  63. data/lib/csv_decision/matchers/pattern.rb +26 -11
  64. data/lib/csv_decision/matchers/range.rb +21 -5
  65. data/lib/csv_decision/matchers/symbol.rb +20 -0
  66. data/lib/csv_decision/matchers.rb +85 -20
  67. data/lib/csv_decision/numeric.rb +38 -0
  68. data/lib/csv_decision/options.rb +36 -27
  69. data/lib/csv_decision/parse.rb +46 -39
  70. data/lib/csv_decision/scan_row.rb +19 -7
  71. data/lib/csv_decision/symbol.rb +73 -0
  72. data/lib/csv_decision/table.rb +24 -18
  73. data/lib/csv_decision.rb +25 -18
  74. data/spec/csv_decision/columns_spec.rb +1 -1
  75. data/spec/csv_decision/constant_spec.rb +60 -0
  76. data/spec/csv_decision/examples_spec.rb +119 -0
  77. data/spec/csv_decision/matchers/function_spec.rb +48 -28
  78. data/spec/csv_decision/matchers/numeric_spec.rb +4 -41
  79. data/spec/csv_decision/matchers/range_spec.rb +31 -61
  80. data/spec/csv_decision/matchers/symbol_spec.rb +65 -0
  81. data/spec/csv_decision/options_spec.rb +14 -2
  82. data/spec/csv_decision/parse_spec.rb +10 -0
  83. data/spec/csv_decision/table_spec.rb +112 -6
  84. data/spec/data/valid/simple_constants.csv +3 -3
  85. metadata +62 -7
  86. data/spec/csv_decision/simple_example_spec.rb +0 -75
  87. /data/spec/{csv_decision.rb → csv_decision_spec.rb} +0 -0
@@ -28,17 +28,29 @@ describe CSVDecision::Options do
28
28
  input0, output0
29
29
  DATA
30
30
 
31
- result = CSVDecision.parse(data, first_match: false)
31
+ result = CSVDecision.parse(data,
32
+ first_match: false,
33
+ matchers: [CSVDecision::Matchers::Pattern])
32
34
 
33
35
  expected = {
34
36
  first_match: false,
35
37
  regexp_implicit: false,
36
38
  text_only: false,
37
- matchers: CSVDecision::DEFAULT_MATCHERS
39
+ matchers: [CSVDecision::Matchers::Pattern]
38
40
  }
39
41
  expect(result.options).to eql expected
40
42
  end
41
43
 
44
+ it 'rejects an invalid option argument' do
45
+ data = <<~DATA
46
+ IN :input, OUT :output
47
+ input0, output0
48
+ DATA
49
+
50
+ expect { CSVDecision.parse(data, bad_option: false) }
51
+ .to raise_error(ArgumentError, "invalid option(s) supplied: [:bad_option]")
52
+ end
53
+
42
54
  it 'parses options from a CSV file' do
43
55
  file = Pathname(File.join(SPEC_DATA_VALID, 'options_in_file1.csv'))
44
56
  result = CSVDecision.parse(file)
@@ -32,4 +32,14 @@ describe CSVDecision::Parse do
32
32
  end
33
33
  end
34
34
  end
35
+
36
+ context 'it rejects invalid CSV files' do
37
+ Dir[File.join(CSVDecision.root, 'spec/data/invalid/*.csv')].each do |file_name|
38
+ pathname = Pathname(file_name)
39
+
40
+ it "rejects CSV file: #{pathname.basename}" do
41
+ expect { CSVDecision.parse(pathname) }.to raise_error(CSVDecision::FileError)
42
+ end
43
+ end
44
+ end
35
45
  end
@@ -68,9 +68,9 @@ describe CSVDecision::Table do
68
68
  options: {},
69
69
  data: <<~DATA
70
70
  in :constant, out :type
71
- :=nil, NilClass
72
- = 0, Zero
73
- :=100.0, 100%
71
+ :=nil, :=nil
72
+ = 0, = 0
73
+ :=100.0, :=100
74
74
  , Unrecognized
75
75
  DATA
76
76
  },
@@ -81,9 +81,9 @@ describe CSVDecision::Table do
81
81
  options = test[:options].merge(first_match: true)
82
82
  table = CSVDecision.parse(test[:data], options)
83
83
 
84
- expect(table.send(method, constant: nil)).to eq(type: 'NilClass')
85
- expect(table.send(method, constant: 0)).to eq(type: 'Zero')
86
- expect(table.send(method, constant: BigDecimal.new('100.0'))).to eq(type: '100%')
84
+ expect(table.send(method, constant: nil)).to eq(type: nil)
85
+ expect(table.send(method, constant: 0)).to eq(type: 0)
86
+ expect(table.send(method, constant: BigDecimal.new('100.0'))).to eq(type: BigDecimal('100.0'))
87
87
  expect(table.send(method, constant: ':=nil')).to eq(type: 'Unrecognized')
88
88
  expect(table.send(method, constant: '= 0')).to eq(type: 'Unrecognized')
89
89
  expect(table.send(method, constant: ':=100.0')).to eq(type: 'Unrecognized')
@@ -183,5 +183,111 @@ describe CSVDecision::Table do
183
183
  end
184
184
  end
185
185
  end
186
+
187
+ context 'makes correct decision for table with symbol equality compares' do
188
+ examples = [
189
+ { example: 'uses == :node',
190
+ options: {},
191
+ data: <<~DATA
192
+ in :node, in :parent, out :top?
193
+ , ==:node, yes
194
+ , , no
195
+ DATA
196
+ },
197
+ { example: 'uses :node',
198
+ options: {},
199
+ data: <<~DATA
200
+ in :node, in :parent, out :top?
201
+ , :node, yes
202
+ , , no
203
+ DATA
204
+ },
205
+ { example: 'uses := :node',
206
+ options: {},
207
+ data: <<~DATA
208
+ in :node, in :parent, out :top?
209
+ , := :node, yes
210
+ , , no
211
+ DATA
212
+ },
213
+ { example: 'uses = :node',
214
+ options: {},
215
+ data: <<~DATA
216
+ in :node, in :parent, out :top?
217
+ , = :node, yes
218
+ , , no
219
+ DATA
220
+ },
221
+ { example: 'uses :node, drops :node input column',
222
+ options: {},
223
+ data: <<~DATA
224
+ in :parent, out :top?
225
+ :node, yes
226
+ , no
227
+ DATA
228
+ },
229
+ { example: 'uses :parent, drops :parent input column',
230
+ options: {},
231
+ data: <<~DATA
232
+ in :node, out :top?
233
+ :parent, yes
234
+ , no
235
+ DATA
236
+ },
237
+ { example: 'uses != :parent, drops :parent input column',
238
+ options: {},
239
+ data: <<~DATA
240
+ in :node, out :top?
241
+ != :parent, no
242
+ , yes
243
+ DATA
244
+ }
245
+ ]
246
+
247
+ examples.each do |test|
248
+ %i[decide decide!].each do |method|
249
+ it "#{method} correctly #{test[:example]}" do
250
+ options = test[:options]
251
+ table = CSVDecision.parse(test[:data], options)
252
+
253
+ expect(table.send(method, node: 0, parent: 0)).to eq(top?: 'yes')
254
+ expect(table.send(method, node: 1, parent: 0)).to eq(top?: 'no')
255
+ expect(table.send(method, node: '0', parent: 0)).to eq(top?: 'no')
256
+ end
257
+ end
258
+ end
259
+ end
260
+
261
+ context 'makes correct decision for table with symbol ordered compares' do
262
+ examples = [
263
+ { example: 'uses == :node',
264
+ options: {},
265
+ data: <<~DATA
266
+ in :traded, in :settled, out :status
267
+ , :traded, same day
268
+ , >:traded, pending
269
+ , <:traded, invalid trade
270
+ , , invalid data
271
+ DATA
272
+ },
273
+ ]
274
+
275
+ examples.each do |test|
276
+ %i[decide decide!].each do |method|
277
+ it "#{method} correctly #{test[:example]}" do
278
+ options = test[:options]
279
+ table = CSVDecision.parse(test[:data], options)
280
+
281
+ expect(table.send(method, traded: '20171227', settled: '20171227')).to eq(status: 'same day')
282
+ expect(table.send(method, traded: 20171227, settled: 20171227 )).to eq(status: 'same day')
283
+ expect(table.send(method, traded: '20171227', settled: '20171228')).to eq(status: 'pending')
284
+ expect(table.send(method, traded: 20171227, settled: 20171228 )).to eq(status: 'pending')
285
+ expect(table.send(method, traded: '20171228', settled: '20171227')).to eq(status: 'invalid trade')
286
+ expect(table.send(method, traded: 20171228, settled: 20171227 )).to eq(status: 'invalid trade')
287
+ expect(table.send(method, traded: '20171227', settled: 20171228 )).to eq(status: 'invalid data')
288
+ end
289
+ end
290
+ end
291
+ end
186
292
  end
187
293
  end
@@ -1,5 +1,5 @@
1
1
  in :constant,out :type
2
- :=nil, NilClass
3
- ==0, Zero
4
- :=100.0, 100%
2
+ :=nil, := nil
3
+ ==0, =0
4
+ :=100.0, =100.0
5
5
  , Unrecognized
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: csv_decision
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.3
4
+ version: 0.0.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - Brett Vickers
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-12-23 00:00:00.000000000 Z
11
+ date: 2017-12-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -185,6 +185,7 @@ executables: []
185
185
  extensions: []
186
186
  extra_rdoc_files: []
187
187
  files:
188
+ - ".codeclimate.yml"
188
189
  - ".coveralls.yml"
189
190
  - ".gitignore"
190
191
  - ".rspec"
@@ -194,39 +195,91 @@ files:
194
195
  - Gemfile
195
196
  - LICENSE
196
197
  - README.md
197
- - benchmark.rb
198
+ - benchmarks/rufus_decision.rb
198
199
  - csv_decision.gemspec
200
+ - doc/CSVDecision.html
201
+ - doc/CSVDecision/CellValidationError.html
202
+ - doc/CSVDecision/Columns.html
203
+ - doc/CSVDecision/Columns/Default.html
204
+ - doc/CSVDecision/Columns/Dictionary.html
205
+ - doc/CSVDecision/Columns/Entry.html
206
+ - doc/CSVDecision/Constant.html
207
+ - doc/CSVDecision/Data.html
208
+ - doc/CSVDecision/Decide.html
209
+ - doc/CSVDecision/Decision.html
210
+ - doc/CSVDecision/Error.html
211
+ - doc/CSVDecision/FileError.html
212
+ - doc/CSVDecision/Function.html
213
+ - doc/CSVDecision/Header.html
214
+ - doc/CSVDecision/Input.html
215
+ - doc/CSVDecision/Load.html
216
+ - doc/CSVDecision/Matchers.html
217
+ - doc/CSVDecision/Matchers/Constant.html
218
+ - doc/CSVDecision/Matchers/Function.html
219
+ - doc/CSVDecision/Matchers/Matcher.html
220
+ - doc/CSVDecision/Matchers/Numeric.html
221
+ - doc/CSVDecision/Matchers/Pattern.html
222
+ - doc/CSVDecision/Matchers/Range.html
223
+ - doc/CSVDecision/Matchers/Symbol.html
224
+ - doc/CSVDecision/Numeric.html
225
+ - doc/CSVDecision/Options.html
226
+ - doc/CSVDecision/Parse.html
227
+ - doc/CSVDecision/ScanRow.html
228
+ - doc/CSVDecision/Symbol.html
229
+ - doc/CSVDecision/Table.html
230
+ - doc/_index.html
231
+ - doc/class_list.html
232
+ - doc/css/common.css
233
+ - doc/css/full_list.css
234
+ - doc/css/style.css
235
+ - doc/file.README.html
236
+ - doc/file_list.html
237
+ - doc/frames.html
238
+ - doc/index.html
239
+ - doc/js/app.js
240
+ - doc/js/full_list.js
241
+ - doc/js/jquery.js
242
+ - doc/method_list.html
243
+ - doc/top-level-namespace.html
199
244
  - lib/csv_decision.rb
200
245
  - lib/csv_decision/columns.rb
246
+ - lib/csv_decision/constant.rb
201
247
  - lib/csv_decision/data.rb
202
248
  - lib/csv_decision/decide.rb
203
249
  - lib/csv_decision/decision.rb
250
+ - lib/csv_decision/function.rb
204
251
  - lib/csv_decision/header.rb
205
252
  - lib/csv_decision/input.rb
206
253
  - lib/csv_decision/load.rb
207
254
  - lib/csv_decision/matchers.rb
255
+ - lib/csv_decision/matchers/constant.rb
208
256
  - lib/csv_decision/matchers/function.rb
209
257
  - lib/csv_decision/matchers/numeric.rb
210
258
  - lib/csv_decision/matchers/pattern.rb
211
259
  - lib/csv_decision/matchers/range.rb
260
+ - lib/csv_decision/matchers/symbol.rb
261
+ - lib/csv_decision/numeric.rb
212
262
  - lib/csv_decision/options.rb
213
263
  - lib/csv_decision/parse.rb
214
264
  - lib/csv_decision/scan_row.rb
265
+ - lib/csv_decision/symbol.rb
215
266
  - lib/csv_decision/table.rb
216
- - spec/csv_decision.rb
217
267
  - spec/csv_decision/columns_spec.rb
268
+ - spec/csv_decision/constant_spec.rb
218
269
  - spec/csv_decision/data_spec.rb
219
270
  - spec/csv_decision/decision_spec.rb
271
+ - spec/csv_decision/examples_spec.rb
220
272
  - spec/csv_decision/input_spec.rb
221
273
  - spec/csv_decision/load_spec.rb
222
274
  - spec/csv_decision/matchers/function_spec.rb
223
275
  - spec/csv_decision/matchers/numeric_spec.rb
224
276
  - spec/csv_decision/matchers/pattern_spec.rb
225
277
  - spec/csv_decision/matchers/range_spec.rb
278
+ - spec/csv_decision/matchers/symbol_spec.rb
226
279
  - spec/csv_decision/options_spec.rb
227
280
  - spec/csv_decision/parse_spec.rb
228
- - spec/csv_decision/simple_example_spec.rb
229
281
  - spec/csv_decision/table_spec.rb
282
+ - spec/csv_decision_spec.rb
230
283
  - spec/data/invalid/invalid_header1.csv
231
284
  - spec/data/invalid/invalid_header2.csv
232
285
  - spec/data/invalid/invalid_header3.csv
@@ -263,20 +316,22 @@ signing_key:
263
316
  specification_version: 4
264
317
  summary: CSV based Ruby decision tables.
265
318
  test_files:
266
- - spec/csv_decision.rb
267
319
  - spec/csv_decision/columns_spec.rb
320
+ - spec/csv_decision/constant_spec.rb
268
321
  - spec/csv_decision/data_spec.rb
269
322
  - spec/csv_decision/decision_spec.rb
323
+ - spec/csv_decision/examples_spec.rb
270
324
  - spec/csv_decision/input_spec.rb
271
325
  - spec/csv_decision/load_spec.rb
272
326
  - spec/csv_decision/matchers/function_spec.rb
273
327
  - spec/csv_decision/matchers/numeric_spec.rb
274
328
  - spec/csv_decision/matchers/pattern_spec.rb
275
329
  - spec/csv_decision/matchers/range_spec.rb
330
+ - spec/csv_decision/matchers/symbol_spec.rb
276
331
  - spec/csv_decision/options_spec.rb
277
332
  - spec/csv_decision/parse_spec.rb
278
- - spec/csv_decision/simple_example_spec.rb
279
333
  - spec/csv_decision/table_spec.rb
334
+ - spec/csv_decision_spec.rb
280
335
  - spec/data/invalid/invalid_header1.csv
281
336
  - spec/data/invalid/invalid_header2.csv
282
337
  - spec/data/invalid/invalid_header3.csv
@@ -1,75 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative '../../lib/csv_decision'
4
-
5
- context 'simple example - strings-only' do
6
- data = <<~DATA
7
- in :topic, in :region, out :team_member
8
- sports, Europe, Alice
9
- sports, , Bob
10
- finance, America, Charlie
11
- finance, Europe, Donald
12
- finance, , Ernest
13
- politics, Asia, Fujio
14
- politics, America, Gilbert
15
- politics, , Henry
16
- , , Zach
17
- DATA
18
-
19
- it 'makes correct decisions for CSV string' do
20
- table = CSVDecision.parse(data)
21
-
22
- result = table.decide(topic: 'finance', region: 'Europe')
23
- expect(result).to eq(team_member: 'Donald')
24
-
25
- result = table.decide(topic: 'sports', region: nil)
26
- expect(result).to eq(team_member: 'Bob')
27
-
28
- result = table.decide(topic: 'culture', region: 'America')
29
- expect(result).to eq(team_member: 'Zach')
30
- end
31
-
32
- it 'makes correct decisions for CSV file' do
33
- table = CSVDecision.parse(Pathname('spec/data/valid/simple_example.csv'))
34
-
35
- result = table.decide(topic: 'finance', region: 'Europe')
36
- expect(result).to eq(team_member: 'Donald')
37
-
38
- result = table.decide(topic: 'sports', region: nil)
39
- expect(result).to eq(team_member: 'Bob')
40
-
41
- result = table.decide(topic: 'culture', region: 'America')
42
- expect(result).to eq(team_member: 'Zach')
43
- end
44
- end
45
-
46
- context 'simple example - constants' do
47
- data = <<~DATA
48
- in :constant, out :type
49
- :=nil, NilClass
50
- ==false, FALSE
51
- =true, TRUE
52
- = 0, Zero
53
- :=100.0, 100%
54
- DATA
55
-
56
- it 'makes correct decisions for CSV string' do
57
- table = CSVDecision.parse(data)
58
-
59
- result = table.decide(constant: nil)
60
- expect(result).to eq(type: 'NilClass')
61
-
62
- result = table.decide(constant: true)
63
- expect(result).to eq(type: 'TRUE')
64
-
65
- result = table.decide(constant: false)
66
- expect(result).to eq(type: 'FALSE')
67
-
68
- result = table.decide(constant: 0)
69
- expect(result).to eq(type: 'Zero')
70
-
71
- result = table.decide(constant: BigDecimal.new('100.0'))
72
- expect(result).to eq(type: '100%')
73
- end
74
- end
75
-
File without changes