dentaku 3.0.0 → 3.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +119 -0
- data/.travis.yml +8 -9
- data/CHANGELOG.md +9 -0
- data/Gemfile +0 -5
- data/LICENSE +21 -0
- data/README.md +44 -3
- data/Rakefile +4 -1
- data/dentaku.gemspec +8 -4
- data/lib/dentaku.rb +15 -2
- data/lib/dentaku/ast.rb +1 -0
- data/lib/dentaku/ast/access.rb +2 -2
- data/lib/dentaku/ast/arithmetic.rb +7 -7
- data/lib/dentaku/ast/bitwise.rb +2 -2
- data/lib/dentaku/ast/case.rb +5 -5
- data/lib/dentaku/ast/case/case_conditional.rb +1 -1
- data/lib/dentaku/ast/case/case_else.rb +2 -2
- data/lib/dentaku/ast/case/case_switch_variable.rb +2 -2
- data/lib/dentaku/ast/case/case_then.rb +2 -2
- data/lib/dentaku/ast/case/case_when.rb +2 -2
- data/lib/dentaku/ast/combinators.rb +10 -2
- data/lib/dentaku/ast/comparators.rb +34 -6
- data/lib/dentaku/ast/function.rb +1 -1
- data/lib/dentaku/ast/function_registry.rb +1 -1
- data/lib/dentaku/ast/functions/if.rb +6 -2
- data/lib/dentaku/ast/functions/max.rb +1 -1
- data/lib/dentaku/ast/functions/min.rb +1 -1
- data/lib/dentaku/ast/functions/ruby_math.rb +1 -1
- data/lib/dentaku/ast/functions/string_functions.rb +8 -8
- data/lib/dentaku/ast/functions/sum.rb +12 -0
- data/lib/dentaku/ast/grouping.rb +2 -2
- data/lib/dentaku/ast/identifier.rb +8 -5
- data/lib/dentaku/ast/negation.rb +2 -2
- data/lib/dentaku/ast/node.rb +1 -1
- data/lib/dentaku/ast/operation.rb +1 -1
- data/lib/dentaku/bulk_expression_solver.rb +39 -20
- data/lib/dentaku/calculator.rb +38 -28
- data/lib/dentaku/dependency_resolver.rb +1 -1
- data/lib/dentaku/flat_hash.rb +31 -0
- data/lib/dentaku/parser.rb +7 -6
- data/lib/dentaku/string_casing.rb +7 -0
- data/lib/dentaku/token.rb +1 -1
- data/lib/dentaku/token_matcher.rb +4 -4
- data/lib/dentaku/token_scanner.rb +18 -7
- data/lib/dentaku/tokenizer.rb +26 -2
- data/lib/dentaku/version.rb +1 -1
- data/spec/ast/arithmetic_spec.rb +2 -2
- data/spec/ast/comparator_spec.rb +57 -0
- data/spec/ast/function_spec.rb +1 -1
- data/spec/ast/max_spec.rb +5 -0
- data/spec/ast/min_spec.rb +5 -0
- data/spec/ast/sum_spec.rb +38 -0
- data/spec/benchmark.rb +2 -2
- data/spec/bulk_expression_solver_spec.rb +89 -1
- data/spec/calculator_spec.rb +40 -7
- data/spec/dentaku_spec.rb +11 -0
- data/spec/external_function_spec.rb +7 -7
- data/spec/parser_spec.rb +11 -11
- data/spec/spec_helper.rb +21 -3
- data/spec/token_matcher_spec.rb +0 -1
- data/spec/token_spec.rb +6 -0
- data/spec/tokenizer_spec.rb +37 -0
- metadata +70 -5
data/spec/parser_spec.rb
CHANGED
@@ -110,7 +110,7 @@ describe Dentaku::Parser do
|
|
110
110
|
one = token(1)
|
111
111
|
rbracket = token(:rbracket)
|
112
112
|
|
113
|
-
node
|
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
|
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
|
129
|
-
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
|
131
|
+
one = Dentaku::Token.new(:numeric, 1)
|
132
132
|
case_then1 = Dentaku::Token.new(:case, :then)
|
133
|
-
two
|
133
|
+
two = Dentaku::Token.new(:numeric, 2)
|
134
134
|
case_when2 = Dentaku::Token.new(:case, :when)
|
135
|
-
three
|
135
|
+
three = Dentaku::Token.new(:numeric, 3)
|
136
136
|
case_then2 = Dentaku::Token.new(:case, :then)
|
137
|
-
four
|
138
|
-
case_close
|
137
|
+
four = Dentaku::Token.new(:numeric, 4)
|
138
|
+
case_close = Dentaku::Token.new(:case, :close)
|
139
139
|
|
140
|
-
node
|
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
|
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
|
data/spec/spec_helper.rb
CHANGED
@@ -1,8 +1,26 @@
|
|
1
1
|
require 'pry'
|
2
|
-
require '
|
2
|
+
require 'simplecov'
|
3
|
+
require 'codecov'
|
3
4
|
|
4
|
-
|
5
|
-
|
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)
|
data/spec/token_matcher_spec.rb
CHANGED
data/spec/token_spec.rb
CHANGED
@@ -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
|
data/spec/tokenizer_spec.rb
CHANGED
@@ -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.
|
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:
|
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:
|
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:
|
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.
|
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
|