csv_decision 0.2.0 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +5 -1
- data/README.md +11 -8
- data/benchmarks/rufus_decision.rb +9 -1
- data/csv_decision.gemspec +1 -1
- data/doc/CSVDecision/CellValidationError.html +1 -1
- data/doc/CSVDecision/Columns/Dictionary.html +29 -29
- data/doc/CSVDecision/Columns.html +394 -47
- data/doc/CSVDecision/Data.html +2 -2
- data/doc/CSVDecision/Decide.html +23 -159
- data/doc/CSVDecision/Decision.html +370 -32
- data/doc/CSVDecision/Defaults.html +1 -1
- data/doc/CSVDecision/Dictionary/Entry.html +157 -55
- data/doc/CSVDecision/Dictionary.html +37 -21
- data/doc/CSVDecision/Error.html +1 -1
- data/doc/CSVDecision/FileError.html +1 -1
- data/doc/CSVDecision/Header.html +142 -1
- data/doc/CSVDecision/Index.html +741 -0
- data/doc/CSVDecision/Input.html +14 -61
- data/doc/CSVDecision/Load.html +1 -1
- data/doc/CSVDecision/Matchers/Constant.html +1 -1
- data/doc/CSVDecision/Matchers/Function.html +1 -1
- data/doc/CSVDecision/Matchers/Guard.html +13 -147
- data/doc/CSVDecision/Matchers/Matcher.html +13 -13
- data/doc/CSVDecision/Matchers/Numeric.html +1 -1
- data/doc/CSVDecision/Matchers/Pattern.html +1 -1
- data/doc/CSVDecision/Matchers/Proc.html +147 -14
- data/doc/CSVDecision/Matchers/Range.html +1 -1
- data/doc/CSVDecision/Matchers/Symbol.html +1 -1
- data/doc/CSVDecision/Matchers.html +55 -162
- data/doc/CSVDecision/Options.html +21 -21
- data/doc/CSVDecision/Parse.html +2 -180
- data/doc/CSVDecision/Result.html +220 -38
- data/doc/CSVDecision/ScanRow.html +69 -325
- data/doc/CSVDecision/Table.html +128 -40
- data/doc/CSVDecision/TableValidationError.html +1 -1
- data/doc/CSVDecision/Validate.html +1 -1
- data/doc/CSVDecision.html +4 -4
- data/doc/_index.html +8 -8
- data/doc/class_list.html +1 -1
- data/doc/file.README.html +13 -11
- data/doc/index.html +13 -11
- data/doc/method_list.html +206 -150
- data/doc/top-level-namespace.html +1 -1
- data/lib/csv_decision/columns.rb +87 -1
- data/lib/csv_decision/decision.rb +54 -29
- data/lib/csv_decision/defaults.rb +1 -1
- data/lib/csv_decision/dictionary.rb +32 -22
- data/lib/csv_decision/header.rb +17 -0
- data/lib/csv_decision/index.rb +107 -0
- data/lib/csv_decision/input.rb +45 -13
- data/lib/csv_decision/matchers/guard.rb +2 -0
- data/lib/csv_decision/matchers.rb +14 -8
- data/lib/csv_decision/options.rb +7 -19
- data/lib/csv_decision/parse.rb +12 -96
- data/lib/csv_decision/result.rb +10 -9
- data/lib/csv_decision/scan_row.rb +20 -44
- data/lib/csv_decision/table.rb +7 -4
- data/lib/csv_decision.rb +1 -1
- data/spec/csv_decision/columns_spec.rb +6 -6
- data/spec/csv_decision/data_spec.rb +0 -5
- data/spec/csv_decision/index_spec.rb +58 -0
- data/spec/csv_decision/input_spec.rb +7 -2
- data/spec/csv_decision/options_spec.rb +16 -1
- data/spec/csv_decision/parse_spec.rb +4 -5
- data/spec/csv_decision/table_spec.rb +70 -0
- data/spec/data/{valid → invalid}/empty.csv +0 -0
- data/spec/data/valid/index_example.csv +12 -0
- data/spec/data/valid/multi_column_index.csv +10 -0
- data/spec/data/valid/multi_column_index2.csv +12 -0
- data/spec/data/valid/options_in_file3.csv +13 -0
- metadata +16 -5
- data/lib/csv_decision/decide.rb +0 -45
@@ -490,5 +490,75 @@ describe CSVDecision::Table do
|
|
490
490
|
end
|
491
491
|
end
|
492
492
|
end
|
493
|
+
|
494
|
+
context 'uses single column index to make correct decisions' do
|
495
|
+
examples = [
|
496
|
+
{ example: 'evaluates single-column index CSV string',
|
497
|
+
options: { first_match: false },
|
498
|
+
data: <<~DATA
|
499
|
+
in:topic, in:region, out:team_member
|
500
|
+
sports, Europe, Alice
|
501
|
+
sports, , Bob
|
502
|
+
finance, America, Charlie
|
503
|
+
finance, Europe, Donald
|
504
|
+
finance, , Ernest
|
505
|
+
politics, Asia, Fujio
|
506
|
+
politics, America, Gilbert
|
507
|
+
politics, , Henry
|
508
|
+
sports, , Zach
|
509
|
+
finance, , Zach
|
510
|
+
politics, , Zach
|
511
|
+
DATA
|
512
|
+
},
|
513
|
+
{ example: 'evaluates single-column index CSV file',
|
514
|
+
options: { first_match: false },
|
515
|
+
data: Pathname(File.join(SPEC_DATA_VALID, 'index_example.csv'))
|
516
|
+
}
|
517
|
+
]
|
518
|
+
examples.each do |test|
|
519
|
+
%i[decide decide!].each do |method|
|
520
|
+
it "#{method} correctly #{test[:example]}" do
|
521
|
+
table = CSVDecision.parse(test[:data], test[:options])
|
522
|
+
|
523
|
+
expect(table.send(method, topic: 'politics', region: 'Arctic'))
|
524
|
+
.to eq(team_member: %w[Henry Zach])
|
525
|
+
end
|
526
|
+
end
|
527
|
+
end
|
528
|
+
end
|
529
|
+
|
530
|
+
context 'uses multi-column index to make correct decisions' do
|
531
|
+
examples = [
|
532
|
+
{ example: 'evaluates multi-column index CSV string',
|
533
|
+
options: { first_match: true },
|
534
|
+
data: <<~DATA
|
535
|
+
guard:, in :type, IN :input, OUT :output
|
536
|
+
:number.present?, integer, none, :=0
|
537
|
+
:number.blank?, integer, none, :=nil
|
538
|
+
:number.present?, integer, one, :=1
|
539
|
+
:number.blank?, integer, one, :=nil
|
540
|
+
:string.present?, string, none, 0
|
541
|
+
:number.blank?, string, none, :=nil
|
542
|
+
:string.present?, string, one, 1
|
543
|
+
:number.blank?, string, one, :=nil
|
544
|
+
DATA
|
545
|
+
},
|
546
|
+
{ example: 'evaluates multi-column index CSV file',
|
547
|
+
options: { first_match: true },
|
548
|
+
data: Pathname(File.join(SPEC_DATA_VALID, 'multi_column_index.csv'))
|
549
|
+
}
|
550
|
+
]
|
551
|
+
examples.each do |test|
|
552
|
+
%i[decide decide!].each do |method|
|
553
|
+
it "#{method} correctly #{test[:example]}" do
|
554
|
+
table = CSVDecision.parse(test[:data], test[:options])
|
555
|
+
|
556
|
+
expect(table.send(method, number: 1, type: 'integer', input: 'none')).to eq(output: 0)
|
557
|
+
expect(table.send(method, number: nil, type: 'string', input: 'one')).to eq(output: nil)
|
558
|
+
expect(table.send(method, string: '1', type: 'string', input: 'one')).to eq(output: '1')
|
559
|
+
end
|
560
|
+
end
|
561
|
+
end
|
562
|
+
end
|
493
563
|
end
|
494
564
|
end
|
File without changes
|
@@ -0,0 +1,10 @@
|
|
1
|
+
#comment,
|
2
|
+
guard:,in :type, IN :input,OUT :output
|
3
|
+
:number.present?,integer,none,:=0
|
4
|
+
:number.blank?,integer,none,:=nil
|
5
|
+
:number.present?,integer,one,:=1
|
6
|
+
:number.blank?,integer,one,:=nil
|
7
|
+
:string.present?,string,none,0
|
8
|
+
:number.blank?,string,none,:=nil
|
9
|
+
:string.present?,string,one,1
|
10
|
+
:number.blank?,string,one,:=nil
|
@@ -0,0 +1,12 @@
|
|
1
|
+
#comment,
|
2
|
+
index : 2
|
3
|
+
guard:,in :type, IN :input,OUT :output
|
4
|
+
:number.present?,integer,none,:=0
|
5
|
+
:string.blank?,string,none,:=nil
|
6
|
+
:string.present?,string,none,0
|
7
|
+
:string.blank?,string,one,:=nil
|
8
|
+
:number.present?,integer,one,:=1
|
9
|
+
:number.blank?,integer,one,:=nil
|
10
|
+
:string.present?,string,one,1
|
11
|
+
:string.blank?,string,one,:=nil
|
12
|
+
:number.blank?,integer,none,:=nil
|
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.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Brett Vickers
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-01-
|
11
|
+
date: 2018-01-20 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -187,6 +187,7 @@ files:
|
|
187
187
|
- doc/CSVDecision/Function.html
|
188
188
|
- doc/CSVDecision/Guard.html
|
189
189
|
- doc/CSVDecision/Header.html
|
190
|
+
- doc/CSVDecision/Index.html
|
190
191
|
- doc/CSVDecision/Input.html
|
191
192
|
- doc/CSVDecision/Load.html
|
192
193
|
- doc/CSVDecision/Matchers.html
|
@@ -225,11 +226,11 @@ files:
|
|
225
226
|
- lib/csv_decision.rb
|
226
227
|
- lib/csv_decision/columns.rb
|
227
228
|
- lib/csv_decision/data.rb
|
228
|
-
- lib/csv_decision/decide.rb
|
229
229
|
- lib/csv_decision/decision.rb
|
230
230
|
- lib/csv_decision/defaults.rb
|
231
231
|
- lib/csv_decision/dictionary.rb
|
232
232
|
- lib/csv_decision/header.rb
|
233
|
+
- lib/csv_decision/index.rb
|
233
234
|
- lib/csv_decision/input.rb
|
234
235
|
- lib/csv_decision/load.rb
|
235
236
|
- lib/csv_decision/matchers.rb
|
@@ -251,6 +252,7 @@ files:
|
|
251
252
|
- spec/csv_decision/data_spec.rb
|
252
253
|
- spec/csv_decision/decision_spec.rb
|
253
254
|
- spec/csv_decision/examples_spec.rb
|
255
|
+
- spec/csv_decision/index_spec.rb
|
254
256
|
- spec/csv_decision/input_spec.rb
|
255
257
|
- spec/csv_decision/load_spec.rb
|
256
258
|
- spec/csv_decision/matchers/function_spec.rb
|
@@ -263,14 +265,18 @@ files:
|
|
263
265
|
- spec/csv_decision/parse_spec.rb
|
264
266
|
- spec/csv_decision/table_spec.rb
|
265
267
|
- spec/csv_decision_spec.rb
|
268
|
+
- spec/data/invalid/empty.csv
|
266
269
|
- spec/data/invalid/invalid_header1.csv
|
267
270
|
- spec/data/invalid/invalid_header2.csv
|
268
271
|
- spec/data/invalid/invalid_header3.csv
|
269
272
|
- spec/data/invalid/invalid_header4.csv
|
270
273
|
- spec/data/valid/benchmark_regexp.csv
|
271
|
-
- spec/data/valid/
|
274
|
+
- spec/data/valid/index_example.csv
|
275
|
+
- spec/data/valid/multi_column_index.csv
|
276
|
+
- spec/data/valid/multi_column_index2.csv
|
272
277
|
- spec/data/valid/options_in_file1.csv
|
273
278
|
- spec/data/valid/options_in_file2.csv
|
279
|
+
- spec/data/valid/options_in_file3.csv
|
274
280
|
- spec/data/valid/regular_expressions.csv
|
275
281
|
- spec/data/valid/simple_constants.csv
|
276
282
|
- spec/data/valid/simple_example.csv
|
@@ -308,6 +314,7 @@ test_files:
|
|
308
314
|
- spec/csv_decision/data_spec.rb
|
309
315
|
- spec/csv_decision/decision_spec.rb
|
310
316
|
- spec/csv_decision/examples_spec.rb
|
317
|
+
- spec/csv_decision/index_spec.rb
|
311
318
|
- spec/csv_decision/input_spec.rb
|
312
319
|
- spec/csv_decision/load_spec.rb
|
313
320
|
- spec/csv_decision/matchers/function_spec.rb
|
@@ -320,14 +327,18 @@ test_files:
|
|
320
327
|
- spec/csv_decision/parse_spec.rb
|
321
328
|
- spec/csv_decision/table_spec.rb
|
322
329
|
- spec/csv_decision_spec.rb
|
330
|
+
- spec/data/invalid/empty.csv
|
323
331
|
- spec/data/invalid/invalid_header1.csv
|
324
332
|
- spec/data/invalid/invalid_header2.csv
|
325
333
|
- spec/data/invalid/invalid_header3.csv
|
326
334
|
- spec/data/invalid/invalid_header4.csv
|
327
335
|
- spec/data/valid/benchmark_regexp.csv
|
328
|
-
- spec/data/valid/
|
336
|
+
- spec/data/valid/index_example.csv
|
337
|
+
- spec/data/valid/multi_column_index.csv
|
338
|
+
- spec/data/valid/multi_column_index2.csv
|
329
339
|
- spec/data/valid/options_in_file1.csv
|
330
340
|
- spec/data/valid/options_in_file2.csv
|
341
|
+
- spec/data/valid/options_in_file3.csv
|
331
342
|
- spec/data/valid/regular_expressions.csv
|
332
343
|
- spec/data/valid/simple_constants.csv
|
333
344
|
- spec/data/valid/simple_example.csv
|
data/lib/csv_decision/decide.rb
DELETED
@@ -1,45 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
# CSV Decision: CSV based Ruby decision tables.
|
4
|
-
# Created December 2017.
|
5
|
-
# @author Brett Vickers <brett@phillips-vickers.com>
|
6
|
-
# See LICENSE and README.md for details.
|
7
|
-
module CSVDecision
|
8
|
-
# Main module for searching the decision table looking for one or more matches
|
9
|
-
# @api private
|
10
|
-
module Decide
|
11
|
-
# Match the table row against the input hash.
|
12
|
-
#
|
13
|
-
# @param row [Array] Table row.
|
14
|
-
# @param input [Hash{Symbol=>Object}] Input hash data structure.
|
15
|
-
# @param scan_row [ScanRow]
|
16
|
-
# @return [Boolean] Returns true if a match, false otherwise.
|
17
|
-
def self.matches?(row:, input:, scan_row:)
|
18
|
-
match = scan_row.match_constants?(row: row, scan_cols: input[:scan_cols])
|
19
|
-
return false unless match
|
20
|
-
|
21
|
-
return true if scan_row.procs.empty?
|
22
|
-
|
23
|
-
scan_row.match_procs?(row: row, input: input)
|
24
|
-
end
|
25
|
-
|
26
|
-
# Main method for making decisions.
|
27
|
-
#
|
28
|
-
# @param table [CSVDecision::Table] Decision table.
|
29
|
-
# @param input [Hash] Input hash (keys may or may not be symbolized)
|
30
|
-
# @param symbolize_keys [true, false] Set to false if keys are symbolized and it's
|
31
|
-
# OK to mutate the input hash. Otherwise a copy of the input hash is symbolized.
|
32
|
-
# @return [Hash] Decision result.
|
33
|
-
def self.decide(table:, input:, symbolize_keys:)
|
34
|
-
# Parse and transform the hash supplied as input
|
35
|
-
parsed_input = Input.parse(table: table, input: input, symbolize_keys: symbolize_keys)
|
36
|
-
|
37
|
-
# The decision object collects the results of the search and
|
38
|
-
# calculates the final result
|
39
|
-
decision = Decision.new(table: table, input: parsed_input)
|
40
|
-
|
41
|
-
# table_scan(table: table, input: parsed_input, decision: decision)
|
42
|
-
decision.scan(table: table, input: parsed_input)
|
43
|
-
end
|
44
|
-
end
|
45
|
-
end
|