dentaku 3.0.0 → 3.1.0

Sign up to get free protection for your applications and to get access to all the features.
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