dentaku 3.3.0 → 3.4.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 +5 -10
- data/.travis.yml +3 -6
- data/CHANGELOG.md +38 -1
- data/README.md +2 -2
- data/dentaku.gemspec +0 -2
- data/lib/dentaku.rb +14 -6
- data/lib/dentaku/ast.rb +5 -0
- data/lib/dentaku/ast/access.rb +15 -1
- data/lib/dentaku/ast/arithmetic.rb +29 -6
- data/lib/dentaku/ast/array.rb +15 -1
- data/lib/dentaku/ast/case.rb +13 -3
- data/lib/dentaku/ast/case/case_conditional.rb +13 -2
- data/lib/dentaku/ast/case/case_else.rb +12 -4
- data/lib/dentaku/ast/case/case_switch_variable.rb +8 -0
- data/lib/dentaku/ast/case/case_then.rb +12 -4
- data/lib/dentaku/ast/case/case_when.rb +12 -4
- data/lib/dentaku/ast/function.rb +11 -2
- data/lib/dentaku/ast/function_registry.rb +21 -0
- data/lib/dentaku/ast/functions/all.rb +36 -0
- data/lib/dentaku/ast/functions/any.rb +36 -0
- data/lib/dentaku/ast/functions/avg.rb +2 -2
- data/lib/dentaku/ast/functions/count.rb +8 -0
- data/lib/dentaku/ast/functions/duration.rb +51 -0
- data/lib/dentaku/ast/functions/if.rb +15 -2
- data/lib/dentaku/ast/functions/map.rb +36 -0
- data/lib/dentaku/ast/functions/mul.rb +3 -2
- data/lib/dentaku/ast/functions/pluck.rb +29 -0
- data/lib/dentaku/ast/functions/round.rb +1 -1
- data/lib/dentaku/ast/functions/rounddown.rb +1 -1
- data/lib/dentaku/ast/functions/roundup.rb +1 -1
- data/lib/dentaku/ast/functions/ruby_math.rb +47 -3
- data/lib/dentaku/ast/functions/string_functions.rb +68 -4
- data/lib/dentaku/ast/functions/sum.rb +3 -2
- data/lib/dentaku/ast/grouping.rb +3 -1
- data/lib/dentaku/ast/identifier.rb +5 -1
- data/lib/dentaku/ast/negation.rb +3 -1
- data/lib/dentaku/ast/node.rb +4 -0
- data/lib/dentaku/ast/operation.rb +8 -0
- data/lib/dentaku/bulk_expression_solver.rb +34 -25
- data/lib/dentaku/calculator.rb +19 -6
- data/lib/dentaku/date_arithmetic.rb +45 -0
- data/lib/dentaku/exceptions.rb +4 -4
- data/lib/dentaku/flat_hash.rb +9 -2
- data/lib/dentaku/parser.rb +31 -14
- data/lib/dentaku/token_matcher.rb +1 -1
- data/lib/dentaku/token_scanner.rb +1 -1
- data/lib/dentaku/tokenizer.rb +7 -2
- data/lib/dentaku/version.rb +1 -1
- data/spec/ast/addition_spec.rb +7 -1
- data/spec/ast/and_function_spec.rb +6 -6
- data/spec/ast/and_spec.rb +1 -1
- data/spec/ast/arithmetic_spec.rb +57 -29
- data/spec/ast/avg_spec.rb +9 -5
- data/spec/ast/count_spec.rb +7 -7
- data/spec/ast/division_spec.rb +7 -1
- data/spec/ast/function_spec.rb +9 -9
- data/spec/ast/max_spec.rb +3 -3
- data/spec/ast/min_spec.rb +3 -3
- data/spec/ast/mul_spec.rb +10 -6
- data/spec/ast/negation_spec.rb +48 -0
- data/spec/ast/node_spec.rb +11 -8
- data/spec/ast/numeric_spec.rb +1 -1
- data/spec/ast/or_spec.rb +6 -6
- data/spec/ast/round_spec.rb +14 -4
- data/spec/ast/rounddown_spec.rb +14 -4
- data/spec/ast/roundup_spec.rb +14 -4
- data/spec/ast/string_functions_spec.rb +35 -0
- data/spec/ast/sum_spec.rb +10 -6
- data/spec/ast/switch_spec.rb +5 -5
- data/spec/bulk_expression_solver_spec.rb +18 -1
- data/spec/calculator_spec.rb +173 -28
- data/spec/dentaku_spec.rb +18 -5
- data/spec/external_function_spec.rb +29 -5
- data/spec/parser_spec.rb +85 -123
- data/spec/spec_helper.rb +6 -4
- data/spec/token_matcher_spec.rb +8 -8
- data/spec/token_scanner_spec.rb +4 -4
- data/spec/tokenizer_spec.rb +32 -13
- metadata +11 -4
data/spec/ast/count_spec.rb
CHANGED
@@ -5,36 +5,36 @@ require 'dentaku'
|
|
5
5
|
describe 'Dentaku::AST::Count' do
|
6
6
|
it 'returns the length of an array' do
|
7
7
|
result = Dentaku('COUNT(1, x, 1.8)', x: 2.3)
|
8
|
-
expect(result).to eq
|
8
|
+
expect(result).to eq(3)
|
9
9
|
end
|
10
10
|
|
11
11
|
it 'returns the length of a single number object' do
|
12
12
|
result = Dentaku('COUNT(x)', x: 2.3)
|
13
|
-
expect(result).to eq
|
13
|
+
expect(result).to eq(1)
|
14
14
|
end
|
15
15
|
|
16
16
|
it 'returns the length if a single String is passed' do
|
17
17
|
result = Dentaku('COUNT(x)', x: 'dentaku')
|
18
|
-
expect(result).to eq
|
18
|
+
expect(result).to eq(7)
|
19
19
|
end
|
20
20
|
|
21
21
|
it 'returns the length if an array is passed' do
|
22
22
|
result = Dentaku('COUNT(x)', x: [4, 5])
|
23
|
-
expect(result).to eq
|
23
|
+
expect(result).to eq(2)
|
24
24
|
end
|
25
25
|
|
26
26
|
it 'returns the length if an array with one element is passed' do
|
27
27
|
result = Dentaku('COUNT(x)', x: [4])
|
28
|
-
expect(result).to eq
|
28
|
+
expect(result).to eq(1)
|
29
29
|
end
|
30
30
|
|
31
31
|
it 'returns the length if an array even if it has nested array' do
|
32
32
|
result = Dentaku('COUNT(1, x, 3)', x: [4, 5])
|
33
|
-
expect(result).to eq
|
33
|
+
expect(result).to eq(3)
|
34
34
|
end
|
35
35
|
|
36
36
|
it 'returns the length if an array is passed' do
|
37
37
|
result = Dentaku('COUNT()')
|
38
|
-
expect(result).to eq
|
38
|
+
expect(result).to eq(0)
|
39
39
|
end
|
40
40
|
end
|
data/spec/ast/division_spec.rb
CHANGED
@@ -9,9 +9,15 @@ describe Dentaku::AST::Division do
|
|
9
9
|
|
10
10
|
let(:t) { Dentaku::AST::Numeric.new Dentaku::Token.new(:logical, true) }
|
11
11
|
|
12
|
+
it 'allows access to its sub-trees' do
|
13
|
+
node = described_class.new(five, six)
|
14
|
+
expect(node.left).to eq(five)
|
15
|
+
expect(node.right).to eq(six)
|
16
|
+
end
|
17
|
+
|
12
18
|
it 'performs division' do
|
13
19
|
node = described_class.new(five, six)
|
14
|
-
expect(node.value.round(4)).to eq
|
20
|
+
expect(node.value.round(4)).to eq(0.8333)
|
15
21
|
end
|
16
22
|
|
17
23
|
it 'requires numeric operands' do
|
data/spec/ast/function_spec.rb
CHANGED
@@ -14,7 +14,7 @@ describe Dentaku::AST::Function do
|
|
14
14
|
described_class.register("flarble", :string, -> { "flarble" })
|
15
15
|
expect { described_class.get("flarble") }.not_to raise_error
|
16
16
|
function = described_class.get("flarble").new
|
17
|
-
expect(function.value).to eq
|
17
|
+
expect(function.value).to eq("flarble")
|
18
18
|
end
|
19
19
|
|
20
20
|
it 'does not throw an error when registering a function with a name that matches a currently defined constant' do
|
@@ -22,15 +22,15 @@ describe Dentaku::AST::Function do
|
|
22
22
|
end
|
23
23
|
|
24
24
|
describe "#arity" do
|
25
|
-
it "
|
25
|
+
it "returns the correct arity for custom functions" do
|
26
26
|
zero = described_class.register("zero", :numeric, ->() { 0 })
|
27
|
-
expect(zero.arity).to eq
|
27
|
+
expect(zero.arity).to eq(0)
|
28
28
|
|
29
29
|
one = described_class.register("one", :numeric, ->(x) { x * 2 })
|
30
|
-
expect(one.arity).to eq
|
30
|
+
expect(one.arity).to eq(1)
|
31
31
|
|
32
32
|
two = described_class.register("two", :numeric, ->(x, y) { x + y })
|
33
|
-
expect(two.arity).to eq
|
33
|
+
expect(two.arity).to eq(2)
|
34
34
|
|
35
35
|
many = described_class.register("many", :numeric, ->(*args) { args.max })
|
36
36
|
expect(many.arity).to be_nil
|
@@ -38,19 +38,19 @@ describe Dentaku::AST::Function do
|
|
38
38
|
end
|
39
39
|
|
40
40
|
it 'casts a String to an Integer if possible' do
|
41
|
-
expect(described_class.numeric('3')).to eq
|
41
|
+
expect(described_class.numeric('3')).to eq(3)
|
42
42
|
end
|
43
43
|
|
44
44
|
it 'casts a String to a BigDecimal if possible and if Integer would loose information' do
|
45
|
-
expect(described_class.numeric('3.2')).to eq
|
45
|
+
expect(described_class.numeric('3.2')).to eq(3.2)
|
46
46
|
end
|
47
47
|
|
48
48
|
it 'casts a String to a BigDecimal with a negative number' do
|
49
|
-
expect(described_class.numeric('-3.2')).to eq
|
49
|
+
expect(described_class.numeric('-3.2')).to eq(-3.2)
|
50
50
|
end
|
51
51
|
|
52
52
|
it 'casts a String to a BigDecimal without a leading zero' do
|
53
|
-
expect(described_class.numeric('-.2')).to eq
|
53
|
+
expect(described_class.numeric('-.2')).to eq(-0.2)
|
54
54
|
end
|
55
55
|
|
56
56
|
it 'raises an error if the value could not be cast to a Numeric' do
|
data/spec/ast/max_spec.rb
CHANGED
@@ -5,16 +5,16 @@ require 'dentaku'
|
|
5
5
|
describe 'Dentaku::AST::Function::Max' do
|
6
6
|
it 'returns the largest numeric value in an array of Numeric values' do
|
7
7
|
result = Dentaku('MAX(1, x, 1.8)', x: 2.3)
|
8
|
-
expect(result).to eq
|
8
|
+
expect(result).to eq(2.3)
|
9
9
|
end
|
10
10
|
|
11
11
|
it 'returns the largest value even if a String is passed' do
|
12
12
|
result = Dentaku('MAX(1, x, 1.8)', x: '2.3')
|
13
|
-
expect(result).to eq
|
13
|
+
expect(result).to eq(2.3)
|
14
14
|
end
|
15
15
|
|
16
16
|
it 'returns the largest value even if an Array is passed' do
|
17
17
|
result = Dentaku('MAX(1, x, 1.8)', x: [1.5, 2.3, 1.7])
|
18
|
-
expect(result).to eq
|
18
|
+
expect(result).to eq(2.3)
|
19
19
|
end
|
20
20
|
end
|
data/spec/ast/min_spec.rb
CHANGED
@@ -5,16 +5,16 @@ require 'dentaku'
|
|
5
5
|
describe 'Dentaku::AST::Function::Min' do
|
6
6
|
it 'returns the smallest numeric value in an array of Numeric values' do
|
7
7
|
result = Dentaku('MIN(1, x, 1.8)', x: 2.3)
|
8
|
-
expect(result).to eq
|
8
|
+
expect(result).to eq(1)
|
9
9
|
end
|
10
10
|
|
11
11
|
it 'returns the smallest value even if a String is passed' do
|
12
12
|
result = Dentaku('MIN(1, x, 1.8)', x: '0.3')
|
13
|
-
expect(result).to eq
|
13
|
+
expect(result).to eq(0.3)
|
14
14
|
end
|
15
15
|
|
16
16
|
it 'returns the smallest value even if an Array is passed' do
|
17
17
|
result = Dentaku('MIN(1, x, 1.8)', x: [1.5, 0.3, 1.7])
|
18
|
-
expect(result).to eq
|
18
|
+
expect(result).to eq(0.3)
|
19
19
|
end
|
20
20
|
end
|
data/spec/ast/mul_spec.rb
CHANGED
@@ -5,34 +5,38 @@ require 'dentaku'
|
|
5
5
|
describe 'Dentaku::AST::Function::Mul' do
|
6
6
|
it 'returns the product of an array of Numeric values' do
|
7
7
|
result = Dentaku('MUL(1, x, 1.8)', x: 2.3)
|
8
|
-
expect(result).to eq
|
8
|
+
expect(result).to eq(4.14)
|
9
9
|
end
|
10
10
|
|
11
11
|
it 'returns the product of a single entry array of a Numeric value' do
|
12
12
|
result = Dentaku('MUL(x)', x: 2.3)
|
13
|
-
expect(result).to eq
|
13
|
+
expect(result).to eq(2.3)
|
14
14
|
end
|
15
15
|
|
16
16
|
it 'coerces string inputs to numeric' do
|
17
17
|
result = Dentaku('mul(1, x, 1.8)', x: '2.3')
|
18
|
-
expect(result).to eq
|
18
|
+
expect(result).to eq(4.14)
|
19
19
|
end
|
20
20
|
|
21
21
|
it 'returns the product even if an array is passed' do
|
22
22
|
result = Dentaku('mul(1, x, 2.3)', x: [4, 5])
|
23
|
-
expect(result).to eq
|
23
|
+
expect(result).to eq(46)
|
24
24
|
end
|
25
25
|
|
26
26
|
it 'handles nested calls' do
|
27
27
|
result = Dentaku('mul(1, x, mul(4, 5))', x: '2.3')
|
28
|
-
expect(result).to eq
|
28
|
+
expect(result).to eq(46)
|
29
29
|
end
|
30
30
|
|
31
31
|
context 'checking errors' do
|
32
32
|
let(:calculator) { Dentaku::Calculator.new }
|
33
33
|
|
34
34
|
it 'raises an error if no arguments are passed' do
|
35
|
-
expect { calculator.evaluate!('MUL()') }.to raise_error(ArgumentError)
|
35
|
+
expect { calculator.evaluate!('MUL()') }.to raise_error(Dentaku::ArgumentError)
|
36
|
+
end
|
37
|
+
|
38
|
+
it 'raises an error if an empty array is passed' do
|
39
|
+
expect { calculator.evaluate!('MUL(x)', x: []) }.to raise_error(Dentaku::ArgumentError)
|
36
40
|
end
|
37
41
|
end
|
38
42
|
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'dentaku/ast/arithmetic'
|
3
|
+
|
4
|
+
require 'dentaku/token'
|
5
|
+
|
6
|
+
describe Dentaku::AST::Negation do
|
7
|
+
let(:five) { Dentaku::AST::Numeric.new Dentaku::Token.new(:numeric, 5) }
|
8
|
+
let(:t) { Dentaku::AST::Logical.new Dentaku::Token.new(:logical, true) }
|
9
|
+
let(:x) { Dentaku::AST::Identifier.new Dentaku::Token.new(:identifier, 'x') }
|
10
|
+
|
11
|
+
it 'allows access to its sub-node' do
|
12
|
+
node = described_class.new(five)
|
13
|
+
expect(node.node).to eq(five)
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'performs negation' do
|
17
|
+
node = described_class.new(five)
|
18
|
+
expect(node.value).to eq(-5)
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'requires numeric operands' do
|
22
|
+
expect {
|
23
|
+
described_class.new(t)
|
24
|
+
}.to raise_error(Dentaku::NodeError, /requires numeric operands/)
|
25
|
+
|
26
|
+
expression = Dentaku::AST::Negation.new(five)
|
27
|
+
group = Dentaku::AST::Grouping.new(expression)
|
28
|
+
|
29
|
+
expect {
|
30
|
+
described_class.new(group)
|
31
|
+
}.not_to raise_error
|
32
|
+
end
|
33
|
+
|
34
|
+
it 'correctly parses string operands to numeric values' do
|
35
|
+
node = described_class.new(x)
|
36
|
+
expect(node.value('x' => '5')).to eq(-5)
|
37
|
+
end
|
38
|
+
|
39
|
+
it 'raises error if input string is not coercible to numeric' do
|
40
|
+
node = described_class.new(x)
|
41
|
+
expect { node.value('x' => 'invalid') }.to raise_error(Dentaku::ArgumentError)
|
42
|
+
end
|
43
|
+
|
44
|
+
it 'raises error if given a non-numeric argument' do
|
45
|
+
node = described_class.new(x)
|
46
|
+
expect { node.value('x' => true) }.to raise_error(Dentaku::ArgumentError)
|
47
|
+
end
|
48
|
+
end
|
data/spec/ast/node_spec.rb
CHANGED
@@ -6,30 +6,33 @@ require 'dentaku/parser'
|
|
6
6
|
describe Dentaku::AST::Node do
|
7
7
|
it 'returns list of dependencies' do
|
8
8
|
node = make_node('x + 5')
|
9
|
-
expect(node.dependencies).to eq
|
9
|
+
expect(node.dependencies).to eq(['x'])
|
10
10
|
|
11
11
|
node = make_node('5 < x')
|
12
|
-
expect(node.dependencies).to eq
|
12
|
+
expect(node.dependencies).to eq(['x'])
|
13
13
|
|
14
14
|
node = make_node('5 < 7')
|
15
|
-
expect(node.dependencies).to eq
|
15
|
+
expect(node.dependencies).to eq([])
|
16
16
|
|
17
17
|
node = make_node('(y * 7)')
|
18
|
-
expect(node.dependencies).to eq
|
18
|
+
expect(node.dependencies).to eq(['y'])
|
19
19
|
|
20
20
|
node = make_node('if(x > 5, y, z)')
|
21
|
-
expect(node.dependencies).to eq
|
21
|
+
expect(node.dependencies).to eq(['x', 'y', 'z'])
|
22
22
|
|
23
23
|
node = make_node('if(x > 5, y, z)')
|
24
|
-
expect(node.dependencies('x' => 7)).to eq
|
24
|
+
expect(node.dependencies('x' => 7)).to eq(['y'])
|
25
|
+
|
26
|
+
node = make_node('if(x > 5, y, z)')
|
27
|
+
expect(node.dependencies('x' => 2)).to eq(['z'])
|
25
28
|
|
26
29
|
node = make_node('')
|
27
|
-
expect(node.dependencies).to eq
|
30
|
+
expect(node.dependencies).to eq([])
|
28
31
|
end
|
29
32
|
|
30
33
|
it 'returns unique list of dependencies' do
|
31
34
|
node = make_node('x + x')
|
32
|
-
expect(node.dependencies).to eq
|
35
|
+
expect(node.dependencies).to eq(['x'])
|
33
36
|
end
|
34
37
|
|
35
38
|
private
|
data/spec/ast/numeric_spec.rb
CHANGED
data/spec/ast/or_spec.rb
CHANGED
@@ -7,29 +7,29 @@ describe 'Dentaku::AST::Or' do
|
|
7
7
|
|
8
8
|
it 'returns false if all of the arguments are false' do
|
9
9
|
result = Dentaku('OR(1 = "1", 0 = 1)')
|
10
|
-
expect(result).to eq
|
10
|
+
expect(result).to eq(false)
|
11
11
|
end
|
12
12
|
|
13
13
|
it 'supports nested expressions' do
|
14
14
|
result = Dentaku('OR(y = 1, x = 1)', x: 1, y: 2)
|
15
|
-
expect(result).to eq
|
15
|
+
expect(result).to eq(true)
|
16
16
|
end
|
17
17
|
|
18
18
|
it 'returns true if any of the arguments is true' do
|
19
19
|
result = Dentaku('OR(1 = "1", "2" = "2", true = false, false)')
|
20
|
-
expect(result).to eq
|
20
|
+
expect(result).to eq(true)
|
21
21
|
end
|
22
22
|
|
23
23
|
it 'returns true if any nested OR function returns true' do
|
24
24
|
result = Dentaku('OR(OR(1 = 0), OR(true = false, OR(true)))')
|
25
|
-
expect(result).to eq
|
25
|
+
expect(result).to eq(true)
|
26
26
|
end
|
27
27
|
|
28
28
|
it 'raises an error if no arguments are passed' do
|
29
|
-
expect { calculator.evaluate!('OR()') }.to raise_error(ArgumentError)
|
29
|
+
expect { calculator.evaluate!('OR()') }.to raise_error(Dentaku::ArgumentError)
|
30
30
|
end
|
31
31
|
|
32
32
|
it 'raises an error if a non logical argument is passed' do
|
33
|
-
expect { calculator.evaluate!('OR("r")') }.to raise_error(ArgumentError)
|
33
|
+
expect { calculator.evaluate!('OR("r")') }.to raise_error(Dentaku::ArgumentError)
|
34
34
|
end
|
35
35
|
end
|
data/spec/ast/round_spec.rb
CHANGED
@@ -5,21 +5,31 @@ require 'dentaku'
|
|
5
5
|
describe 'Dentaku::AST::Function::Round' do
|
6
6
|
it 'returns the rounded down value' do
|
7
7
|
result = Dentaku('ROUND(1.8)')
|
8
|
-
expect(result).to eq
|
8
|
+
expect(result).to eq(2)
|
9
9
|
end
|
10
10
|
|
11
11
|
it 'returns the rounded down value to the given precision' do
|
12
12
|
result = Dentaku('ROUND(x, y)', x: 1.8453, y: 3)
|
13
|
-
expect(result).to eq
|
13
|
+
expect(result).to eq(1.845)
|
14
14
|
end
|
15
15
|
|
16
16
|
it 'returns the rounded down value to the given precision, also with strings' do
|
17
17
|
result = Dentaku('ROUND(x, y)', x: '1.8453', y: '3')
|
18
|
-
expect(result).to eq
|
18
|
+
expect(result).to eq(1.845)
|
19
19
|
end
|
20
20
|
|
21
21
|
it 'returns the rounded down value to the given precision, also with nil' do
|
22
22
|
result = Dentaku('ROUND(x, y)', x: '1.8453', y: nil)
|
23
|
-
expect(result).to eq
|
23
|
+
expect(result).to eq(2)
|
24
|
+
end
|
25
|
+
|
26
|
+
context 'checking errors' do
|
27
|
+
it 'raises an error if first argument is not numeric' do
|
28
|
+
expect { Dentaku!("ROUND(2020-1-1, 0)") }.to raise_error(Dentaku::ArgumentError)
|
29
|
+
end
|
30
|
+
|
31
|
+
it 'raises an error if places is not numeric' do
|
32
|
+
expect { Dentaku!("ROUND(1.8, 2020-1-1)") }.to raise_error(Dentaku::ArgumentError)
|
33
|
+
end
|
24
34
|
end
|
25
35
|
end
|
data/spec/ast/rounddown_spec.rb
CHANGED
@@ -5,21 +5,31 @@ require 'dentaku'
|
|
5
5
|
describe 'Dentaku::AST::Function::Round' do
|
6
6
|
it 'returns the rounded value' do
|
7
7
|
result = Dentaku('ROUNDDOWN(1.8)')
|
8
|
-
expect(result).to eq
|
8
|
+
expect(result).to eq(1)
|
9
9
|
end
|
10
10
|
|
11
11
|
it 'returns the rounded value to the given precision' do
|
12
12
|
result = Dentaku('ROUNDDOWN(x, y)', x: 1.8453, y: 3)
|
13
|
-
expect(result).to eq
|
13
|
+
expect(result).to eq(1.845)
|
14
14
|
end
|
15
15
|
|
16
16
|
it 'returns the rounded value to the given precision, also with strings' do
|
17
17
|
result = Dentaku('ROUNDDOWN(x, y)', x: '1.8453', y: '3')
|
18
|
-
expect(result).to eq
|
18
|
+
expect(result).to eq(1.845)
|
19
19
|
end
|
20
20
|
|
21
21
|
it 'returns the rounded value to the given precision, also with nil' do
|
22
22
|
result = Dentaku('ROUNDDOWN(x, y)', x: '1.8453', y: nil)
|
23
|
-
expect(result).to eq
|
23
|
+
expect(result).to eq(1)
|
24
|
+
end
|
25
|
+
|
26
|
+
context 'checking errors' do
|
27
|
+
it 'raises an error if first argument is not numeric' do
|
28
|
+
expect { Dentaku!("ROUND(2020-1-1, 0)") }.to raise_error(Dentaku::ArgumentError)
|
29
|
+
end
|
30
|
+
|
31
|
+
it 'raises an error if places is not numeric' do
|
32
|
+
expect { Dentaku!("ROUND(1.8, 2020-1-1)") }.to raise_error(Dentaku::ArgumentError)
|
33
|
+
end
|
24
34
|
end
|
25
35
|
end
|
data/spec/ast/roundup_spec.rb
CHANGED
@@ -5,21 +5,31 @@ require 'dentaku'
|
|
5
5
|
describe 'Dentaku::AST::Function::Round' do
|
6
6
|
it 'returns the rounded value' do
|
7
7
|
result = Dentaku('ROUNDUP(1.8)')
|
8
|
-
expect(result).to eq
|
8
|
+
expect(result).to eq(2)
|
9
9
|
end
|
10
10
|
|
11
11
|
it 'returns the rounded value to the given precision' do
|
12
12
|
result = Dentaku('ROUNDUP(x, y)', x: 1.8453, y: 3)
|
13
|
-
expect(result).to eq
|
13
|
+
expect(result).to eq(1.846)
|
14
14
|
end
|
15
15
|
|
16
16
|
it 'returns the rounded value to the given precision, also with strings' do
|
17
17
|
result = Dentaku('ROUNDUP(x, y)', x: '1.8453', y: '3')
|
18
|
-
expect(result).to eq
|
18
|
+
expect(result).to eq(1.846)
|
19
19
|
end
|
20
20
|
|
21
21
|
it 'returns the rounded value to the given precision, also with nil' do
|
22
22
|
result = Dentaku('ROUNDUP(x, y)', x: '1.8453', y: nil)
|
23
|
-
expect(result).to eq
|
23
|
+
expect(result).to eq(2)
|
24
|
+
end
|
25
|
+
|
26
|
+
context 'checking errors' do
|
27
|
+
it 'raises an error if first argument is not numeric' do
|
28
|
+
expect { Dentaku!("ROUND(2020-1-1, 0)") }.to raise_error(Dentaku::ArgumentError)
|
29
|
+
end
|
30
|
+
|
31
|
+
it 'raises an error if places is not numeric' do
|
32
|
+
expect { Dentaku!("ROUND(1.8, 2020-1-1)") }.to raise_error(Dentaku::ArgumentError)
|
33
|
+
end
|
24
34
|
end
|
25
35
|
end
|