csv_decision2 0.5.1

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 (134) hide show
  1. checksums.yaml +7 -0
  2. data/.codeclimate.yml +3 -0
  3. data/.coveralls.yml +2 -0
  4. data/.gitignore +14 -0
  5. data/.rspec +2 -0
  6. data/.rubocop.yml +30 -0
  7. data/.travis.yml +6 -0
  8. data/CHANGELOG.md +85 -0
  9. data/Dockerfile +6 -0
  10. data/Gemfile +7 -0
  11. data/LICENSE +21 -0
  12. data/README.md +356 -0
  13. data/benchmarks/rufus_decision.rb +158 -0
  14. data/csv_decision2.gemspec +38 -0
  15. data/doc/CSVDecision/CellValidationError.html +143 -0
  16. data/doc/CSVDecision/Columns/Default.html +589 -0
  17. data/doc/CSVDecision/Columns/Dictionary.html +801 -0
  18. data/doc/CSVDecision/Columns/Entry.html +508 -0
  19. data/doc/CSVDecision/Columns.html +1259 -0
  20. data/doc/CSVDecision/Constant.html +254 -0
  21. data/doc/CSVDecision/Data.html +479 -0
  22. data/doc/CSVDecision/Decide.html +302 -0
  23. data/doc/CSVDecision/Decision.html +1011 -0
  24. data/doc/CSVDecision/Defaults.html +291 -0
  25. data/doc/CSVDecision/Dictionary/Entry.html +1147 -0
  26. data/doc/CSVDecision/Dictionary.html +426 -0
  27. data/doc/CSVDecision/Error.html +139 -0
  28. data/doc/CSVDecision/FileError.html +143 -0
  29. data/doc/CSVDecision/Function.html +240 -0
  30. data/doc/CSVDecision/Guard.html +245 -0
  31. data/doc/CSVDecision/Header.html +647 -0
  32. data/doc/CSVDecision/Index.html +741 -0
  33. data/doc/CSVDecision/Input.html +404 -0
  34. data/doc/CSVDecision/Load.html +296 -0
  35. data/doc/CSVDecision/Matchers/Constant.html +484 -0
  36. data/doc/CSVDecision/Matchers/Function.html +511 -0
  37. data/doc/CSVDecision/Matchers/Guard.html +503 -0
  38. data/doc/CSVDecision/Matchers/Matcher.html +507 -0
  39. data/doc/CSVDecision/Matchers/Numeric.html +415 -0
  40. data/doc/CSVDecision/Matchers/Pattern.html +491 -0
  41. data/doc/CSVDecision/Matchers/Proc.html +704 -0
  42. data/doc/CSVDecision/Matchers/Range.html +379 -0
  43. data/doc/CSVDecision/Matchers/Symbol.html +426 -0
  44. data/doc/CSVDecision/Matchers.html +1567 -0
  45. data/doc/CSVDecision/Numeric.html +259 -0
  46. data/doc/CSVDecision/Options.html +443 -0
  47. data/doc/CSVDecision/Parse.html +282 -0
  48. data/doc/CSVDecision/Paths.html +742 -0
  49. data/doc/CSVDecision/Result.html +1200 -0
  50. data/doc/CSVDecision/Scan/InputHashes.html +369 -0
  51. data/doc/CSVDecision/Scan.html +313 -0
  52. data/doc/CSVDecision/ScanRow.html +866 -0
  53. data/doc/CSVDecision/Symbol.html +256 -0
  54. data/doc/CSVDecision/Table.html +1470 -0
  55. data/doc/CSVDecision/TableValidationError.html +143 -0
  56. data/doc/CSVDecision/Validate.html +422 -0
  57. data/doc/CSVDecision.html +621 -0
  58. data/doc/_index.html +471 -0
  59. data/doc/class_list.html +51 -0
  60. data/doc/css/common.css +1 -0
  61. data/doc/css/full_list.css +58 -0
  62. data/doc/css/style.css +499 -0
  63. data/doc/file.README.html +421 -0
  64. data/doc/file_list.html +56 -0
  65. data/doc/frames.html +17 -0
  66. data/doc/index.html +421 -0
  67. data/doc/js/app.js +248 -0
  68. data/doc/js/full_list.js +216 -0
  69. data/doc/js/jquery.js +4 -0
  70. data/doc/method_list.html +1163 -0
  71. data/doc/top-level-namespace.html +110 -0
  72. data/docker-compose.yml +13 -0
  73. data/lib/csv_decision/columns.rb +192 -0
  74. data/lib/csv_decision/data.rb +92 -0
  75. data/lib/csv_decision/decision.rb +196 -0
  76. data/lib/csv_decision/defaults.rb +47 -0
  77. data/lib/csv_decision/dictionary.rb +180 -0
  78. data/lib/csv_decision/header.rb +83 -0
  79. data/lib/csv_decision/index.rb +107 -0
  80. data/lib/csv_decision/input.rb +121 -0
  81. data/lib/csv_decision/load.rb +36 -0
  82. data/lib/csv_decision/matchers/constant.rb +74 -0
  83. data/lib/csv_decision/matchers/function.rb +56 -0
  84. data/lib/csv_decision/matchers/guard.rb +142 -0
  85. data/lib/csv_decision/matchers/numeric.rb +44 -0
  86. data/lib/csv_decision/matchers/pattern.rb +94 -0
  87. data/lib/csv_decision/matchers/range.rb +95 -0
  88. data/lib/csv_decision/matchers/symbol.rb +149 -0
  89. data/lib/csv_decision/matchers.rb +220 -0
  90. data/lib/csv_decision/options.rb +124 -0
  91. data/lib/csv_decision/parse.rb +165 -0
  92. data/lib/csv_decision/paths.rb +78 -0
  93. data/lib/csv_decision/result.rb +204 -0
  94. data/lib/csv_decision/scan.rb +117 -0
  95. data/lib/csv_decision/scan_row.rb +142 -0
  96. data/lib/csv_decision/table.rb +101 -0
  97. data/lib/csv_decision/validate.rb +85 -0
  98. data/lib/csv_decision.rb +45 -0
  99. data/spec/csv_decision/columns_spec.rb +251 -0
  100. data/spec/csv_decision/constant_spec.rb +36 -0
  101. data/spec/csv_decision/data_spec.rb +50 -0
  102. data/spec/csv_decision/decision_spec.rb +19 -0
  103. data/spec/csv_decision/examples_spec.rb +242 -0
  104. data/spec/csv_decision/index_spec.rb +58 -0
  105. data/spec/csv_decision/input_spec.rb +55 -0
  106. data/spec/csv_decision/load_spec.rb +28 -0
  107. data/spec/csv_decision/matchers/function_spec.rb +82 -0
  108. data/spec/csv_decision/matchers/guard_spec.rb +170 -0
  109. data/spec/csv_decision/matchers/numeric_spec.rb +47 -0
  110. data/spec/csv_decision/matchers/pattern_spec.rb +183 -0
  111. data/spec/csv_decision/matchers/range_spec.rb +70 -0
  112. data/spec/csv_decision/matchers/symbol_spec.rb +67 -0
  113. data/spec/csv_decision/options_spec.rb +94 -0
  114. data/spec/csv_decision/parse_spec.rb +44 -0
  115. data/spec/csv_decision/table_spec.rb +683 -0
  116. data/spec/csv_decision_spec.rb +7 -0
  117. data/spec/data/invalid/empty.csv +0 -0
  118. data/spec/data/invalid/invalid_header1.csv +4 -0
  119. data/spec/data/invalid/invalid_header2.csv +4 -0
  120. data/spec/data/invalid/invalid_header3.csv +4 -0
  121. data/spec/data/invalid/invalid_header4.csv +4 -0
  122. data/spec/data/valid/benchmark_regexp.csv +10 -0
  123. data/spec/data/valid/index_example.csv +13 -0
  124. data/spec/data/valid/multi_column_index.csv +10 -0
  125. data/spec/data/valid/multi_column_index2.csv +12 -0
  126. data/spec/data/valid/options_in_file1.csv +5 -0
  127. data/spec/data/valid/options_in_file2.csv +5 -0
  128. data/spec/data/valid/options_in_file3.csv +13 -0
  129. data/spec/data/valid/regular_expressions.csv +11 -0
  130. data/spec/data/valid/simple_constants.csv +5 -0
  131. data/spec/data/valid/simple_example.csv +10 -0
  132. data/spec/data/valid/valid.csv +4 -0
  133. data/spec/spec_helper.rb +106 -0
  134. metadata +352 -0
@@ -0,0 +1,158 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'benchmark/ips'
4
+ require 'benchmark/memory'
5
+ require 'rufus/decision'
6
+
7
+ require_relative '../lib/csv_decision'
8
+
9
+ SPEC_DATA_VALID ||= File.join(CSVDecision.root, 'spec', 'data', 'valid')
10
+
11
+ CSV_OPTIONS = { regexp_implicit: true }.freeze
12
+ RUFUS_OPTIONS = { open_uri: false, ruby_eval: false }.freeze
13
+
14
+ benchmarks = [
15
+ {
16
+ name: 'String compares only with index',
17
+ data: 'index_example.csv',
18
+ input: { 'topic' => 'politics', 'region' => 'Arctic' },
19
+ # Expected results for first_match and accumulate
20
+ first_match: { 'team_member' => 'Henry' },
21
+ accumulate: { 'team_member' => ['Henry', 'Zach'] }
22
+ },
23
+ {
24
+ name: 'String compares only',
25
+ data: 'simple_example.csv',
26
+ input: { 'topic' => 'culture', 'region' => 'America' },
27
+ # Expected results for first_match and accumulate
28
+ first_match: { 'team_member' => 'Zach' },
29
+ accumulate: { 'team_member' => 'Zach' }
30
+ },
31
+ {
32
+ name: 'Regular expressions',
33
+ data: 'benchmark_regexp.csv',
34
+ input: { 'age' => '40', 'trait' => 'cheerful' },
35
+ # Expected results for first_match and accumulate
36
+ first_match: { 'salesperson' => 'Swanson' },
37
+ accumulate: { 'salesperson' => %w[Swanson Korolev] }
38
+ }
39
+ ].freeze
40
+
41
+ tag_width = 70
42
+
43
+ puts ""
44
+ puts "Benchmarking Decisions per Second"
45
+ puts '=' * tag_width
46
+ puts ""
47
+
48
+ # First match true and false run options
49
+ [true, false].each do |first_match|
50
+ puts "Table Decision Option: first_match: #{first_match}"
51
+ puts '-' * tag_width
52
+
53
+ csv_options = CSV_OPTIONS.merge(first_match: first_match)
54
+ rufus_options = RUFUS_OPTIONS.merge(first_match: first_match, accumulate: !first_match)
55
+
56
+ benchmarks.each do |test|
57
+ name = test[:name]
58
+ data = Pathname(File.join(SPEC_DATA_VALID, test[:data]))
59
+
60
+ rufus_table = Rufus::Decision::Table.new(data.to_s, rufus_options)
61
+ csv_table = CSVDecision.parse(data, csv_options)
62
+
63
+ # Prepare input hash
64
+ input = test[:input].deep_dup
65
+ input_symbolized = input.symbolize_keys
66
+
67
+ # Test expected results
68
+ expected = first_match ? test[:first_match] : test[:accumulate]
69
+
70
+ result = rufus_table.transform(input)
71
+
72
+ unless result.slice(*expected.keys).eql?(expected)
73
+ raise "Rufus expected results check failed for test: #{name}"
74
+ end
75
+
76
+ result = csv_table.decide!(input_symbolized)
77
+
78
+ unless result.eql?(expected.symbolize_keys)
79
+ raise "CSV Decision expected results check failed for test: #{name}"
80
+ end
81
+
82
+ Benchmark.ips do |x|
83
+ GC.start
84
+ x.report("CSV decision (first_match: #{first_match}) - #{name}: ") do |count|
85
+ count.times { csv_table.decide!(input_symbolized) }
86
+ end
87
+
88
+ GC.start
89
+ x.report("Rufus decision (first_match: #{first_match}) - #{name}: ") do |count|
90
+ count.times { rufus_table.transform!(input) }
91
+ end
92
+
93
+ x.compare!
94
+ end
95
+ end
96
+ end
97
+
98
+ puts ""
99
+ puts "Benchmarking Memory"
100
+ puts '=' * tag_width
101
+ puts ""
102
+
103
+ def benchmark_memory(test, quiet: false)
104
+ name = test[:name]
105
+ data = Pathname(File.join(SPEC_DATA_VALID, test[:data]))
106
+ file_name = data.to_s
107
+
108
+ rufus_tables = {}
109
+ csv_tables = {}
110
+ key = File.basename(file_name, '.csv').to_sym
111
+
112
+ Benchmark.memory(quiet: quiet) do |x|
113
+ GC.start
114
+ x.report("Rufus new table - #{name} ") do
115
+ rufus_tables[key] = Rufus::Decision::Table.new(file_name, RUFUS_OPTIONS)
116
+ end
117
+
118
+ GC.start
119
+ x.report("CSV Decision new table - #{name} ") do
120
+ csv_tables[key] = CSVDecision.parse(data, CSV_OPTIONS)
121
+ end
122
+
123
+ x.compare!
124
+ end
125
+ end
126
+
127
+ # Warmup
128
+ benchmarks.each { |test| benchmark_memory(test, quiet: true) }
129
+
130
+ # Run the test
131
+ benchmarks.each { |test| benchmark_memory(test, quiet: false) }
132
+
133
+ puts ""
134
+ puts "Benchmarking Table Loads per Second"
135
+ puts '=' * tag_width
136
+ puts ""
137
+
138
+ benchmarks.each do |test|
139
+ name = test[:name]
140
+ data = Pathname(File.join(SPEC_DATA_VALID, test[:data]))
141
+ file_name = data.to_s
142
+
143
+ Benchmark.ips do |x|
144
+ GC.start
145
+ x.report("CSV new table - #{name}: ") do |count|
146
+ count.times { CSVDecision.parse(data) }
147
+ end
148
+
149
+ GC.start
150
+ x.report("Rufus new table - #{name}: ") do |count|
151
+ count.times { Rufus::Decision::Table.new(file_name, RUFUS_OPTIONS) }
152
+ end
153
+
154
+ x.compare!
155
+ end
156
+ end
157
+
158
+
@@ -0,0 +1,38 @@
1
+ # frozen_string_literal: true
2
+
3
+ lib = File.expand_path('../lib', __FILE__)
4
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = 'csv_decision2'
8
+ spec.version = '0.5.1'
9
+ spec.authors = ['Imamul Akhyar']
10
+ spec.email = ['imamulakhyar93@gmail.com']
11
+ spec.description = 'CSV based Ruby decision tables.'
12
+ spec.summary = <<-DESC
13
+ CSV Decision implements CSV based Ruby decision tables. It parses and loads
14
+ decision table files which can then be used to execute complex conditional
15
+ logic against an input hash, producing a decision as an output hash.
16
+ DESC
17
+ spec.homepage = 'https://github.com/imamulakhyar93/csv_decision.git'
18
+ spec.license = 'MIT'
19
+
20
+ spec.files = `git ls-files`.split($INPUT_RECORD_SEPARATOR)
21
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
22
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
23
+ spec.require_paths = ['lib']
24
+
25
+ spec.required_ruby_version = '>= 2.7.0'
26
+
27
+ spec.add_dependency 'activesupport', '~> 7.0'
28
+
29
+ spec.add_development_dependency 'benchmark-ips', '~> 2.7'
30
+ spec.add_development_dependency 'benchmark-memory', '~> 0.1'
31
+ spec.add_development_dependency 'bundler', '~> 2.1'
32
+ spec.add_development_dependency 'oj', '~> 3.3'
33
+ spec.add_development_dependency 'rake', '~> 12.3'
34
+ spec.add_development_dependency 'rspec', '~> 3.7'
35
+ spec.add_development_dependency 'rubocop', '~> 0.52'
36
+ spec.add_development_dependency 'rufus-decision', '~> 1.3'
37
+ spec.add_development_dependency 'simplecov', '~> 0.15'
38
+ end
@@ -0,0 +1,143 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <meta charset="utf-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>
7
+ Exception: CSVDecision::CellValidationError
8
+
9
+ &mdash; Documentation by YARD 0.9.12
10
+
11
+ </title>
12
+
13
+ <link rel="stylesheet" href="../css/style.css" type="text/css" charset="utf-8" />
14
+
15
+ <link rel="stylesheet" href="../css/common.css" type="text/css" charset="utf-8" />
16
+
17
+ <script type="text/javascript" charset="utf-8">
18
+ pathId = "CSVDecision::CellValidationError";
19
+ relpath = '../';
20
+ </script>
21
+
22
+
23
+ <script type="text/javascript" charset="utf-8" src="../js/jquery.js"></script>
24
+
25
+ <script type="text/javascript" charset="utf-8" src="../js/app.js"></script>
26
+
27
+
28
+ </head>
29
+ <body>
30
+ <div class="nav_wrap">
31
+ <iframe id="nav" src="../class_list.html?1"></iframe>
32
+ <div id="resizer"></div>
33
+ </div>
34
+
35
+ <div id="main" tabindex="-1">
36
+ <div id="header">
37
+ <div id="menu">
38
+
39
+ <a href="../_index.html">Index (C)</a> &raquo;
40
+ <span class='title'><span class='object_link'><a href="../CSVDecision.html" title="CSVDecision (module)">CSVDecision</a></span></span>
41
+ &raquo;
42
+ <span class="title">CellValidationError</span>
43
+
44
+ </div>
45
+
46
+ <div id="search">
47
+
48
+ <a class="full_list_link" id="class_list_link"
49
+ href="../class_list.html">
50
+
51
+ <svg width="24" height="24">
52
+ <rect x="0" y="4" width="24" height="4" rx="1" ry="1"></rect>
53
+ <rect x="0" y="12" width="24" height="4" rx="1" ry="1"></rect>
54
+ <rect x="0" y="20" width="24" height="4" rx="1" ry="1"></rect>
55
+ </svg>
56
+ </a>
57
+
58
+ </div>
59
+ <div class="clear"></div>
60
+ </div>
61
+
62
+ <div id="content"><h1>Exception: CSVDecision::CellValidationError
63
+
64
+
65
+
66
+ </h1>
67
+ <div class="box_info">
68
+
69
+ <dl>
70
+ <dt>Inherits:</dt>
71
+ <dd>
72
+ <span class="inheritName"><span class='object_link'><a href="Error.html" title="CSVDecision::Error (class)">Error</a></span></span>
73
+
74
+ <ul class="fullTree">
75
+ <li>Object</li>
76
+
77
+ <li class="next">StandardError</li>
78
+
79
+ <li class="next"><span class='object_link'><a href="Error.html" title="CSVDecision::Error (class)">Error</a></span></li>
80
+
81
+ <li class="next">CSVDecision::CellValidationError</li>
82
+
83
+ </ul>
84
+ <a href="#" class="inheritanceTree">show all</a>
85
+
86
+ </dd>
87
+ </dl>
88
+
89
+
90
+
91
+
92
+
93
+
94
+
95
+
96
+
97
+
98
+
99
+ <dl>
100
+ <dt>Defined in:</dt>
101
+ <dd>lib/csv_decision/parse.rb</dd>
102
+ </dl>
103
+
104
+ </div>
105
+
106
+ <h2>Overview</h2><div class="docstring">
107
+ <div class="discussion">
108
+
109
+ <p>Error validating a cell when parsing input table cell data.</p>
110
+
111
+
112
+ </div>
113
+ </div>
114
+ <div class="tags">
115
+
116
+
117
+ </div>
118
+
119
+
120
+
121
+
122
+
123
+
124
+
125
+
126
+
127
+
128
+
129
+
130
+
131
+
132
+
133
+ </div>
134
+
135
+ <div id="footer">
136
+ Generated on Sun Feb 11 10:26:07 2018 by
137
+ <a href="http://yardoc.org" title="Yay! A Ruby Documentation Tool" target="_parent">yard</a>
138
+ 0.9.12 (ruby-2.4.0).
139
+ </div>
140
+
141
+ </div>
142
+ </body>
143
+ </html>