dentaku 3.0.0 → 3.1.0

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 (63) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +119 -0
  3. data/.travis.yml +8 -9
  4. data/CHANGELOG.md +9 -0
  5. data/Gemfile +0 -5
  6. data/LICENSE +21 -0
  7. data/README.md +44 -3
  8. data/Rakefile +4 -1
  9. data/dentaku.gemspec +8 -4
  10. data/lib/dentaku.rb +15 -2
  11. data/lib/dentaku/ast.rb +1 -0
  12. data/lib/dentaku/ast/access.rb +2 -2
  13. data/lib/dentaku/ast/arithmetic.rb +7 -7
  14. data/lib/dentaku/ast/bitwise.rb +2 -2
  15. data/lib/dentaku/ast/case.rb +5 -5
  16. data/lib/dentaku/ast/case/case_conditional.rb +1 -1
  17. data/lib/dentaku/ast/case/case_else.rb +2 -2
  18. data/lib/dentaku/ast/case/case_switch_variable.rb +2 -2
  19. data/lib/dentaku/ast/case/case_then.rb +2 -2
  20. data/lib/dentaku/ast/case/case_when.rb +2 -2
  21. data/lib/dentaku/ast/combinators.rb +10 -2
  22. data/lib/dentaku/ast/comparators.rb +34 -6
  23. data/lib/dentaku/ast/function.rb +1 -1
  24. data/lib/dentaku/ast/function_registry.rb +1 -1
  25. data/lib/dentaku/ast/functions/if.rb +6 -2
  26. data/lib/dentaku/ast/functions/max.rb +1 -1
  27. data/lib/dentaku/ast/functions/min.rb +1 -1
  28. data/lib/dentaku/ast/functions/ruby_math.rb +1 -1
  29. data/lib/dentaku/ast/functions/string_functions.rb +8 -8
  30. data/lib/dentaku/ast/functions/sum.rb +12 -0
  31. data/lib/dentaku/ast/grouping.rb +2 -2
  32. data/lib/dentaku/ast/identifier.rb +8 -5
  33. data/lib/dentaku/ast/negation.rb +2 -2
  34. data/lib/dentaku/ast/node.rb +1 -1
  35. data/lib/dentaku/ast/operation.rb +1 -1
  36. data/lib/dentaku/bulk_expression_solver.rb +39 -20
  37. data/lib/dentaku/calculator.rb +38 -28
  38. data/lib/dentaku/dependency_resolver.rb +1 -1
  39. data/lib/dentaku/flat_hash.rb +31 -0
  40. data/lib/dentaku/parser.rb +7 -6
  41. data/lib/dentaku/string_casing.rb +7 -0
  42. data/lib/dentaku/token.rb +1 -1
  43. data/lib/dentaku/token_matcher.rb +4 -4
  44. data/lib/dentaku/token_scanner.rb +18 -7
  45. data/lib/dentaku/tokenizer.rb +26 -2
  46. data/lib/dentaku/version.rb +1 -1
  47. data/spec/ast/arithmetic_spec.rb +2 -2
  48. data/spec/ast/comparator_spec.rb +57 -0
  49. data/spec/ast/function_spec.rb +1 -1
  50. data/spec/ast/max_spec.rb +5 -0
  51. data/spec/ast/min_spec.rb +5 -0
  52. data/spec/ast/sum_spec.rb +38 -0
  53. data/spec/benchmark.rb +2 -2
  54. data/spec/bulk_expression_solver_spec.rb +89 -1
  55. data/spec/calculator_spec.rb +40 -7
  56. data/spec/dentaku_spec.rb +11 -0
  57. data/spec/external_function_spec.rb +7 -7
  58. data/spec/parser_spec.rb +11 -11
  59. data/spec/spec_helper.rb +21 -3
  60. data/spec/token_matcher_spec.rb +0 -1
  61. data/spec/token_spec.rb +6 -0
  62. data/spec/tokenizer_spec.rb +37 -0
  63. metadata +70 -5
@@ -110,7 +110,7 @@ describe Dentaku::Parser do
110
110
  one = token(1)
111
111
  rbracket = token(:rbracket)
112
112
 
113
- node = described_class.new([a, lbracket, one, rbracket]).parse
113
+ node = described_class.new([a, lbracket, one, rbracket]).parse
114
114
  expect { node.value }.to raise_error(Dentaku::UnboundVariableError)
115
115
  expect(node.value(a: [1, 2, 3])).to eq 2
116
116
  end
@@ -120,24 +120,24 @@ describe Dentaku::Parser do
120
120
  d_and = Dentaku::Token.new(:combinator, :and)
121
121
  d_false = Dentaku::Token.new(:logical, false)
122
122
 
123
- node = described_class.new([d_true, d_and, d_false]).parse
123
+ node = described_class.new([d_true, d_and, d_false]).parse
124
124
  expect(node.value).to eq false
125
125
  end
126
126
 
127
127
  it 'evaluates a case statement' do
128
- case_start = Dentaku::Token.new(:case, :open)
129
- x = Dentaku::Token.new(:identifier, :x)
128
+ case_start = Dentaku::Token.new(:case, :open)
129
+ x = Dentaku::Token.new(:identifier, :x)
130
130
  case_when1 = Dentaku::Token.new(:case, :when)
131
- one = Dentaku::Token.new(:numeric, 1)
131
+ one = Dentaku::Token.new(:numeric, 1)
132
132
  case_then1 = Dentaku::Token.new(:case, :then)
133
- two = Dentaku::Token.new(:numeric, 2)
133
+ two = Dentaku::Token.new(:numeric, 2)
134
134
  case_when2 = Dentaku::Token.new(:case, :when)
135
- three = Dentaku::Token.new(:numeric, 3)
135
+ three = Dentaku::Token.new(:numeric, 3)
136
136
  case_then2 = Dentaku::Token.new(:case, :then)
137
- four = Dentaku::Token.new(:numeric, 4)
138
- case_close = Dentaku::Token.new(:case, :close)
137
+ four = Dentaku::Token.new(:numeric, 4)
138
+ case_close = Dentaku::Token.new(:case, :close)
139
139
 
140
- node = described_class.new(
140
+ node = described_class.new(
141
141
  [case_start,
142
142
  x,
143
143
  case_when1,
@@ -182,7 +182,7 @@ describe Dentaku::Parser do
182
182
  end
183
183
 
184
184
  it "evaluates explicit 'NULL' as a Nil" do
185
- null = Dentaku::Token.new(:null, nil)
185
+ null = Dentaku::Token.new(:null, nil)
186
186
  node = described_class.new([null]).parse
187
187
  expect(node.value).to eq(nil)
188
188
  end
@@ -1,8 +1,26 @@
1
1
  require 'pry'
2
- require 'coveralls'
2
+ require 'simplecov'
3
+ require 'codecov'
3
4
 
4
- # Check the amount of testcoverage
5
- Coveralls.wear!
5
+ SimpleCov.formatters = SimpleCov::Formatter::MultiFormatter.new([
6
+ SimpleCov::Formatter::HTMLFormatter,
7
+ SimpleCov::Formatter::Codecov,
8
+ ])
9
+
10
+ SimpleCov.minimum_coverage 90
11
+ SimpleCov.minimum_coverage_by_file 80
12
+
13
+ SimpleCov.start do
14
+ add_filter "spec/"
15
+ end
16
+
17
+ RSpec.configure do |c|
18
+ c.before(:all) {
19
+ # add example for alias because we can set aliases just once
20
+ # before `calculator` method called
21
+ Dentaku.aliases = { roundup: ['roundupup'] }
22
+ }
23
+ end
6
24
 
7
25
  # automatically create a token stream from bare values
8
26
  def token_stream(*args)
@@ -132,4 +132,3 @@ describe Dentaku::TokenMatcher do
132
132
  end
133
133
  end
134
134
  end
135
-
@@ -7,4 +7,10 @@ describe Dentaku::Token do
7
7
  expect(token.value).to eq(5)
8
8
  expect(token.is?(:numeric)).to be_truthy
9
9
  end
10
+
11
+ it 'compares category and value to determine equality' do
12
+ t1 = Dentaku::Token.new(:numeric, 5)
13
+ t2 = Dentaku::Token.new(:numeric, 5)
14
+ expect(t1 == t2).to be_truthy
15
+ end
10
16
  end
@@ -276,4 +276,41 @@ describe Dentaku::Tokenizer do
276
276
  expect(tokens.map(&:value)).to eq([:exp!, :open, 5, :multiply, 3, :close])
277
277
  end
278
278
  end
279
+
280
+ describe 'aliases' do
281
+ let(:aliases) {
282
+ {
283
+ round: ['rrrrround!', 'redond'],
284
+ roundup: ['округлвверх'],
285
+ rounddown: ['округлвниз'],
286
+ if: ['если', 'cuando', '如果'],
287
+ max: ['макс', 'maximo'],
288
+ min: ['мин', 'minimo']
289
+ }
290
+ }
291
+
292
+ it 'replaced with function name' do
293
+ input = 'rrrrround!(8.2) + minimo(4,6,2)'
294
+ tokenizer.tokenize(input, aliases: aliases)
295
+ expect(tokenizer.replace_aliases(input)).to eq 'round(8.2) + min(4,6,2)'
296
+ end
297
+
298
+ it 'case insensitive' do
299
+ input = 'MinImO(4,6,2)'
300
+ tokenizer.tokenize(input, aliases: aliases)
301
+ expect(tokenizer.replace_aliases(input)).to eq 'min(4,6,2)'
302
+ end
303
+
304
+ it 'replace only whole aliases without word parts' do
305
+ input = 'maximo(2,minimoooo())' # `minimoooo` doesn't match `minimo`
306
+ tokenizer.tokenize(input, aliases: aliases)
307
+ expect(tokenizer.replace_aliases(input)).to eq 'max(2,minimoooo())'
308
+ end
309
+
310
+ it 'work with non-latin symbols' do
311
+ input = '如果(1,2,3)'
312
+ tokenizer.tokenize(input, aliases: aliases)
313
+ expect(tokenizer.replace_aliases(input)).to eq 'if(1,2,3)'
314
+ end
315
+ end
279
316
  end
metadata CHANGED
@@ -1,15 +1,71 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dentaku
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.0.0
4
+ version: 3.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Solomon White
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2017-10-11 00:00:00.000000000 Z
11
+ date: 2018-01-11 00:00:00.000000000 Z
12
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: codecov
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: pry
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: pry-byebug
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: pry-stack_explorer
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
13
69
  - !ruby/object:Gem::Dependency
14
70
  name: rake
15
71
  requirement: !ruby/object:Gem::Requirement
@@ -39,7 +95,7 @@ dependencies:
39
95
  - !ruby/object:Gem::Version
40
96
  version: '0'
41
97
  - !ruby/object:Gem::Dependency
42
- name: pry
98
+ name: rubocop
43
99
  requirement: !ruby/object:Gem::Requirement
44
100
  requirements:
45
101
  - - ">="
@@ -53,7 +109,7 @@ dependencies:
53
109
  - !ruby/object:Gem::Version
54
110
  version: '0'
55
111
  - !ruby/object:Gem::Dependency
56
- name: coveralls
112
+ name: simplecov
57
113
  requirement: !ruby/object:Gem::Requirement
58
114
  requirements:
59
115
  - - ">="
@@ -75,9 +131,11 @@ extra_rdoc_files: []
75
131
  files:
76
132
  - ".gitignore"
77
133
  - ".pryrc"
134
+ - ".rubocop.yml"
78
135
  - ".travis.yml"
79
136
  - CHANGELOG.md
80
137
  - Gemfile
138
+ - LICENSE
81
139
  - README.md
82
140
  - Rakefile
83
141
  - dentaku.gemspec
@@ -108,6 +166,7 @@ files:
108
166
  - lib/dentaku/ast/functions/roundup.rb
109
167
  - lib/dentaku/ast/functions/ruby_math.rb
110
168
  - lib/dentaku/ast/functions/string_functions.rb
169
+ - lib/dentaku/ast/functions/sum.rb
111
170
  - lib/dentaku/ast/functions/switch.rb
112
171
  - lib/dentaku/ast/grouping.rb
113
172
  - lib/dentaku/ast/identifier.rb
@@ -123,7 +182,9 @@ files:
123
182
  - lib/dentaku/calculator.rb
124
183
  - lib/dentaku/dependency_resolver.rb
125
184
  - lib/dentaku/exceptions.rb
185
+ - lib/dentaku/flat_hash.rb
126
186
  - lib/dentaku/parser.rb
187
+ - lib/dentaku/string_casing.rb
127
188
  - lib/dentaku/token.rb
128
189
  - lib/dentaku/token_matcher.rb
129
190
  - lib/dentaku/token_matchers.rb
@@ -135,6 +196,7 @@ files:
135
196
  - spec/ast/and_spec.rb
136
197
  - spec/ast/arithmetic_spec.rb
137
198
  - spec/ast/case_spec.rb
199
+ - spec/ast/comparator_spec.rb
138
200
  - spec/ast/division_spec.rb
139
201
  - spec/ast/function_spec.rb
140
202
  - spec/ast/max_spec.rb
@@ -146,6 +208,7 @@ files:
146
208
  - spec/ast/rounddown_spec.rb
147
209
  - spec/ast/roundup_spec.rb
148
210
  - spec/ast/string_functions_spec.rb
211
+ - spec/ast/sum_spec.rb
149
212
  - spec/ast/switch_spec.rb
150
213
  - spec/benchmark.rb
151
214
  - spec/bulk_expression_solver_spec.rb
@@ -179,7 +242,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
179
242
  version: '0'
180
243
  requirements: []
181
244
  rubyforge_project: dentaku
182
- rubygems_version: 2.6.13
245
+ rubygems_version: 2.5.2.1
183
246
  signing_key:
184
247
  specification_version: 4
185
248
  summary: A formula language parser and evaluator
@@ -189,6 +252,7 @@ test_files:
189
252
  - spec/ast/and_spec.rb
190
253
  - spec/ast/arithmetic_spec.rb
191
254
  - spec/ast/case_spec.rb
255
+ - spec/ast/comparator_spec.rb
192
256
  - spec/ast/division_spec.rb
193
257
  - spec/ast/function_spec.rb
194
258
  - spec/ast/max_spec.rb
@@ -200,6 +264,7 @@ test_files:
200
264
  - spec/ast/rounddown_spec.rb
201
265
  - spec/ast/roundup_spec.rb
202
266
  - spec/ast/string_functions_spec.rb
267
+ - spec/ast/sum_spec.rb
203
268
  - spec/ast/switch_spec.rb
204
269
  - spec/benchmark.rb
205
270
  - spec/bulk_expression_solver_spec.rb