rley 0.6.00 → 0.6.01
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.
- checksums.yaml +4 -4
- data/.rubocop.yml +8 -1
- data/CHANGELOG.md +3 -0
- data/Gemfile +1 -1
- data/examples/NLP/benchmark_pico_en.rb +6 -10
- data/examples/NLP/nano_eng/nano_en_demo.rb +2 -2
- data/examples/NLP/nano_eng/nano_grammar.rb +1 -2
- data/examples/data_formats/JSON/json_ast_builder.rb +8 -8
- data/examples/general/SRL/lib/ast_builder.rb +74 -72
- data/examples/general/SRL/lib/grammar.rb +2 -2
- data/examples/general/SRL/lib/regex/abstract_method.rb +28 -28
- data/examples/general/SRL/lib/regex/alternation.rb +21 -25
- data/examples/general/SRL/lib/regex/anchor.rb +6 -9
- data/examples/general/SRL/lib/regex/atomic_expression.rb +10 -15
- data/examples/general/SRL/lib/regex/capturing_group.rb +15 -14
- data/examples/general/SRL/lib/regex/char_class.rb +10 -13
- data/examples/general/SRL/lib/regex/char_range.rb +45 -46
- data/examples/general/SRL/lib/regex/char_shorthand.rb +8 -9
- data/examples/general/SRL/lib/regex/character.rb +196 -191
- data/examples/general/SRL/lib/regex/compound_expression.rb +47 -50
- data/examples/general/SRL/lib/regex/concatenation.rb +23 -27
- data/examples/general/SRL/lib/regex/expression.rb +53 -56
- data/examples/general/SRL/lib/regex/lookaround.rb +23 -20
- data/examples/general/SRL/lib/regex/match_option.rb +26 -28
- data/examples/general/SRL/lib/regex/monadic_expression.rb +20 -23
- data/examples/general/SRL/lib/regex/multiplicity.rb +17 -20
- data/examples/general/SRL/lib/regex/non_capturing_group.rb +9 -12
- data/examples/general/SRL/lib/regex/polyadic_expression.rb +51 -55
- data/examples/general/SRL/lib/regex/quantifiable.rb +14 -20
- data/examples/general/SRL/lib/regex/repetition.rb +20 -23
- data/examples/general/SRL/lib/regex/wildcard.rb +15 -19
- data/examples/general/SRL/lib/regex_repr.rb +1 -1
- data/examples/general/SRL/lib/tokenizer.rb +2 -2
- data/examples/general/SRL/spec/integration_spec.rb +17 -12
- data/examples/general/SRL/spec/regex/character_spec.rb +160 -153
- data/examples/general/SRL/spec/regex/multiplicity_spec.rb +27 -31
- data/examples/general/SRL/spec/spec_helper.rb +1 -1
- data/examples/general/SRL/spec/tokenizer_spec.rb +25 -27
- data/examples/general/calc_iter1/calc_ast_builder.rb +10 -10
- data/examples/general/calc_iter2/calc_ast_builder.rb +7 -9
- data/examples/general/calc_iter2/calc_ast_nodes.rb +5 -6
- data/examples/general/calc_iter2/calc_lexer.rb +3 -5
- data/examples/general/calc_iter2/spec/calculator_spec.rb +16 -14
- data/examples/general/left.rb +8 -8
- data/examples/general/right.rb +8 -8
- data/lib/rley/constants.rb +1 -1
- data/lib/rley/engine.rb +16 -20
- data/lib/rley/formatter/json.rb +1 -1
- data/lib/rley/gfg/grm_flow_graph.rb +1 -1
- data/lib/rley/gfg/item_vertex.rb +6 -5
- data/lib/rley/gfg/vertex.rb +3 -3
- data/lib/rley/lexical/token.rb +4 -3
- data/lib/rley/parse_rep/ast_base_builder.rb +4 -3
- data/lib/rley/parse_rep/parse_rep_creator.rb +1 -1
- data/lib/rley/parse_rep/parse_tree_builder.rb +3 -2
- data/lib/rley/parser/error_reason.rb +1 -1
- data/lib/rley/parser/gfg_chart.rb +6 -6
- data/lib/rley/parser/gfg_parsing.rb +19 -19
- data/lib/rley/parser/parse_entry.rb +3 -3
- data/lib/rley/parser/parse_entry_set.rb +1 -1
- data/lib/rley/parser/parse_walker_factory.rb +15 -15
- data/lib/rley/syntax/grammar.rb +1 -1
- data/lib/rley/syntax/grammar_builder.rb +2 -2
- data/lib/rley/syntax/production.rb +4 -3
- data/lib/rley/syntax/symbol_seq.rb +2 -2
- data/spec/rley/base/grm_items_builder_spec.rb +1 -1
- data/spec/rley/engine_spec.rb +3 -6
- data/spec/rley/formatter/asciitree_spec.rb +0 -1
- data/spec/rley/formatter/bracket_notation_spec.rb +0 -1
- data/spec/rley/formatter/debug_spec.rb +2 -3
- data/spec/rley/gfg/grm_flow_graph_spec.rb +19 -19
- data/spec/rley/parse_rep/ast_builder_spec.rb +12 -12
- data/spec/rley/parser/gfg_earley_parser_spec.rb +1 -1
- data/spec/rley/parser/parse_entry_set_spec.rb +5 -5
- data/spec/rley/parser/parse_state_spec.rb +8 -3
- data/spec/rley/parser/parse_tracer_spec.rb +3 -1
- data/spec/rley/parser/parse_walker_factory_spec.rb +1 -1
- data/spec/rley/ptree/parse_tree_node_spec.rb +1 -1
- data/spec/rley/syntax/grammar_builder_spec.rb +1 -1
- data/spec/rley/syntax/grammar_spec.rb +1 -1
- metadata +2 -3
- data/spec/rley/support/ast_builder.rb +0 -403
@@ -1,53 +1,50 @@
|
|
1
1
|
# File: Multiplicity_spec.rb
|
2
2
|
|
3
|
-
|
4
|
-
require_relative '../spec_helper' # Use the RSpec test framework
|
3
|
+
require_relative '../spec_helper' # Use the RSpec test framework
|
5
4
|
require_relative '../../lib/regex/multiplicity'
|
6
5
|
|
7
6
|
module SRL
|
8
7
|
# Reopen the module, in order to get rid of fully qualified names
|
9
|
-
module Regex
|
10
|
-
|
8
|
+
module Regex # This module is used as a namespace
|
11
9
|
describe Multiplicity do
|
12
|
-
|
13
|
-
|
14
|
-
it "should be created with 3 arguments" do
|
10
|
+
context 'Creation & initialisation' do
|
11
|
+
it 'should be created with 3 arguments' do
|
15
12
|
# Valid cases: initialized with two integer values and a policy symbol
|
16
|
-
[
|
13
|
+
%i[greedy lazy possessive].each do |aPolicy|
|
17
14
|
expect { Multiplicity.new(0, 1, aPolicy) }.not_to raise_error
|
18
15
|
end
|
19
|
-
|
16
|
+
|
20
17
|
# Invalid case: initialized with invalid policy value
|
21
|
-
err =
|
22
|
-
|
18
|
+
err = StandardError
|
19
|
+
msg = "Invalid repetition policy 'KO'."
|
20
|
+
expect { Multiplicity.new(0, :more, 'KO') }.to raise_error(err, msg)
|
23
21
|
end
|
24
|
-
|
25
22
|
end
|
26
|
-
|
27
|
-
context
|
23
|
+
|
24
|
+
context 'Provided services' do
|
28
25
|
it 'should know its text representation' do
|
29
|
-
policy2text = { :
|
30
|
-
|
26
|
+
policy2text = { greedy: '', lazy: '?', possessive: '+' }
|
27
|
+
|
31
28
|
# Case: zero or one
|
32
|
-
policy2text.
|
29
|
+
policy2text.each_key do |aPolicy|
|
33
30
|
multi = Multiplicity.new(0, 1, aPolicy)
|
34
31
|
expect(multi.to_str).to eq("?#{policy2text[aPolicy]}")
|
35
32
|
end
|
36
|
-
|
33
|
+
|
37
34
|
# Case: zero or more
|
38
|
-
policy2text.
|
35
|
+
policy2text.each_key do |aPolicy|
|
39
36
|
multi = Multiplicity.new(0, :more, aPolicy)
|
40
37
|
expect(multi.to_str).to eq("*#{policy2text[aPolicy]}")
|
41
38
|
end
|
42
|
-
|
39
|
+
|
43
40
|
# Case: one or more
|
44
|
-
policy2text.
|
41
|
+
policy2text.each_key do |aPolicy|
|
45
42
|
multi = Multiplicity.new(1, :more, aPolicy)
|
46
43
|
expect(multi.to_str).to eq("+#{policy2text[aPolicy]}")
|
47
44
|
end
|
48
|
-
|
45
|
+
|
49
46
|
# Case: exactly m times
|
50
|
-
policy2text.
|
47
|
+
policy2text.each_key do |aPolicy|
|
51
48
|
samples = [1, 2, 5, 100]
|
52
49
|
samples.each do |aCount|
|
53
50
|
multi = Multiplicity.new(aCount, aCount, aPolicy)
|
@@ -56,28 +53,27 @@ module SRL
|
|
56
53
|
end
|
57
54
|
|
58
55
|
# Case: m, n times
|
59
|
-
policy2text.
|
56
|
+
policy2text.each_key do |aPolicy|
|
60
57
|
samples = [1, 2, 5, 100]
|
61
58
|
samples.each do |aCount|
|
62
59
|
upper = aCount + 1 + rand(20)
|
63
60
|
multi = Multiplicity.new(aCount, upper, aPolicy)
|
64
|
-
|
61
|
+
expectation = "{#{aCount},#{upper}}#{policy2text[aPolicy]}"
|
62
|
+
expect(multi.to_str).to eq(expectation)
|
65
63
|
end
|
66
64
|
end
|
67
65
|
|
68
66
|
# Case: m or more
|
69
|
-
policy2text.
|
67
|
+
policy2text.each_key do |aPolicy|
|
70
68
|
samples = [2, 3, 5, 100]
|
71
69
|
samples.each do |aCount|
|
72
70
|
multi = Multiplicity.new(aCount, :more, aPolicy)
|
73
71
|
expect(multi.to_str).to eq("{#{aCount},}#{policy2text[aPolicy]}")
|
74
72
|
end
|
75
|
-
end
|
73
|
+
end
|
76
74
|
end
|
77
|
-
end
|
78
|
-
|
75
|
+
end
|
79
76
|
end
|
80
|
-
|
81
77
|
end # module
|
82
78
|
end # module
|
83
|
-
# End of file
|
79
|
+
# End of file
|
@@ -12,11 +12,9 @@ module SRL
|
|
12
12
|
end
|
13
13
|
end
|
14
14
|
|
15
|
-
|
16
15
|
subject { Tokenizer.new('') }
|
17
16
|
|
18
17
|
context 'Initialization:' do
|
19
|
-
|
20
18
|
it 'should be initialized with a text to tokenize and a grammar' do
|
21
19
|
expect { Tokenizer.new('anything') }.not_to raise_error
|
22
20
|
end
|
@@ -66,8 +64,8 @@ module SRL
|
|
66
64
|
input = 'literally "hello"'
|
67
65
|
subject.scanner.string = input
|
68
66
|
expectations = [
|
69
|
-
[
|
70
|
-
[
|
67
|
+
%w[LITERALLY literally],
|
68
|
+
%w[STRING_LIT hello]
|
71
69
|
]
|
72
70
|
match_expectations(subject, expectations)
|
73
71
|
end
|
@@ -78,10 +76,10 @@ module SRL
|
|
78
76
|
input = 'letter a to f'
|
79
77
|
subject.scanner.string = input
|
80
78
|
expectations = [
|
81
|
-
[
|
82
|
-
[
|
83
|
-
[
|
84
|
-
[
|
79
|
+
%w[LETTER letter],
|
80
|
+
%w[LETTER_LIT a],
|
81
|
+
%w[TO to],
|
82
|
+
%w[LETTER_LIT f]
|
85
83
|
]
|
86
84
|
match_expectations(subject, expectations)
|
87
85
|
end
|
@@ -92,9 +90,9 @@ module SRL
|
|
92
90
|
input = 'exactly 4 Times'
|
93
91
|
subject.scanner.string = input
|
94
92
|
expectations = [
|
95
|
-
[
|
96
|
-
[
|
97
|
-
[
|
93
|
+
%w[EXACTLY exactly],
|
94
|
+
%w[DIGIT_LIT 4],
|
95
|
+
%w[TIMES Times]
|
98
96
|
]
|
99
97
|
match_expectations(subject, expectations)
|
100
98
|
end
|
@@ -103,11 +101,11 @@ module SRL
|
|
103
101
|
input = 'Between 2 AND 4 times'
|
104
102
|
subject.scanner.string = input
|
105
103
|
expectations = [
|
106
|
-
[
|
107
|
-
[
|
108
|
-
[
|
109
|
-
[
|
110
|
-
[
|
104
|
+
%w[BETWEEN Between],
|
105
|
+
%w[DIGIT_LIT 2],
|
106
|
+
%w[AND AND],
|
107
|
+
%w[DIGIT_LIT 4],
|
108
|
+
%w[TIMES times]
|
111
109
|
]
|
112
110
|
match_expectations(subject, expectations)
|
113
111
|
end
|
@@ -116,9 +114,9 @@ module SRL
|
|
116
114
|
input = 'Once or MORE'
|
117
115
|
subject.scanner.string = input
|
118
116
|
expectations = [
|
119
|
-
[
|
120
|
-
[
|
121
|
-
[
|
117
|
+
%w[ONCE Once],
|
118
|
+
%w[OR or],
|
119
|
+
%w[MORE MORE]
|
122
120
|
]
|
123
121
|
match_expectations(subject, expectations)
|
124
122
|
end
|
@@ -127,9 +125,9 @@ module SRL
|
|
127
125
|
input = 'never or more'
|
128
126
|
subject.scanner.string = input
|
129
127
|
expectations = [
|
130
|
-
[
|
131
|
-
[
|
132
|
-
[
|
128
|
+
%w[NEVER never],
|
129
|
+
%w[OR or],
|
130
|
+
%w[MORE more]
|
133
131
|
]
|
134
132
|
match_expectations(subject, expectations)
|
135
133
|
end
|
@@ -138,13 +136,13 @@ module SRL
|
|
138
136
|
input = 'at least 10 times'
|
139
137
|
subject.scanner.string = input
|
140
138
|
expectations = [
|
141
|
-
[
|
142
|
-
[
|
143
|
-
[
|
144
|
-
[
|
139
|
+
%w[AT at],
|
140
|
+
%w[LEAST least],
|
141
|
+
%w[INTEGER 10],
|
142
|
+
%w[TIMES times]
|
145
143
|
]
|
146
144
|
match_expectations(subject, expectations)
|
147
145
|
end
|
148
146
|
end # context
|
149
147
|
end # describe
|
150
|
-
end # module
|
148
|
+
end # module
|
@@ -26,13 +26,13 @@ class CalcASTBuilder < Rley::ParseRep::ASTBaseBuilder
|
|
26
26
|
end
|
27
27
|
|
28
28
|
# rule 'expression' => 'simple_expression'
|
29
|
-
def reduce_expression_0(
|
30
|
-
return_first_child(
|
29
|
+
def reduce_expression_0(_production, aRange, theTokens, theChildren)
|
30
|
+
return_first_child(aRange, theTokens, theChildren)
|
31
31
|
end
|
32
32
|
|
33
33
|
# rule 'simple_expression' => 'term'
|
34
|
-
def reduce_simple_expression_0(
|
35
|
-
return_first_child(
|
34
|
+
def reduce_simple_expression_0(_production, aRange, theTokens, theChildren)
|
35
|
+
return_first_child(aRange, theTokens, theChildren)
|
36
36
|
end
|
37
37
|
|
38
38
|
# rule 'simple_expression' => %w[simple_expression add_operator term]
|
@@ -41,8 +41,8 @@ class CalcASTBuilder < Rley::ParseRep::ASTBaseBuilder
|
|
41
41
|
end
|
42
42
|
|
43
43
|
# rule 'term' => 'factor'
|
44
|
-
def reduce_term_0(
|
45
|
-
return_first_child(
|
44
|
+
def reduce_term_0(_production, aRange, theTokens, theChildren)
|
45
|
+
return_first_child(aRange, theTokens, theChildren)
|
46
46
|
end
|
47
47
|
|
48
48
|
# rule 'term' => %w[term mul_operator factor]
|
@@ -51,13 +51,13 @@ class CalcASTBuilder < Rley::ParseRep::ASTBaseBuilder
|
|
51
51
|
end
|
52
52
|
|
53
53
|
# rule 'factor' => 'NUMBER'
|
54
|
-
def reduce_factor_0(_aProd,
|
55
|
-
return_first_child(
|
54
|
+
def reduce_factor_0(_aProd, aRange, theTokens, theChildren)
|
55
|
+
return_first_child(aRange, theTokens, theChildren)
|
56
56
|
end
|
57
57
|
|
58
58
|
# # rule 'factor' => %w[LPAREN expression RPAREN]
|
59
|
-
def reduce_factor_1(_aProd,
|
60
|
-
return_second_child(
|
59
|
+
def reduce_factor_1(_aProd, aRange, theTokens, theChildren)
|
60
|
+
return_second_child(aRange, theTokens, theChildren)
|
61
61
|
end
|
62
62
|
|
63
63
|
# rule 'add_operator' => 'PLUS'
|
@@ -8,7 +8,6 @@ require_relative 'calc_ast_nodes'
|
|
8
8
|
# (say, a parse tree) from simpler objects (terminal and non-terminal
|
9
9
|
# nodes) and using a step by step approach.
|
10
10
|
class CalcASTBuilder < Rley::ParseRep::ASTBaseBuilder
|
11
|
-
|
12
11
|
Terminal2NodeClass = {
|
13
12
|
# Lexical ambiguity: minus sign represents two very concepts:
|
14
13
|
# The unary negation operator on one hand, the binary substraction operator
|
@@ -28,7 +27,6 @@ class CalcASTBuilder < Rley::ParseRep::ASTBaseBuilder
|
|
28
27
|
Terminal2NodeClass
|
29
28
|
end
|
30
29
|
|
31
|
-
|
32
30
|
def reduce_binary_operator(theChildren)
|
33
31
|
operator_node = theChildren[1]
|
34
32
|
operator_node.children << theChildren[0]
|
@@ -47,7 +45,7 @@ class CalcASTBuilder < Rley::ParseRep::ASTBaseBuilder
|
|
47
45
|
end
|
48
46
|
|
49
47
|
# rule 'factor' => %w[simple_factor POWER simple_factor]]
|
50
|
-
def reduce_factor_1(
|
48
|
+
def reduce_factor_1(_production, aRange, _tokens, theChildren)
|
51
49
|
result = PowerNode.new(theChildren[1].symbol, aRange)
|
52
50
|
result.children << theChildren[0]
|
53
51
|
result.children << theChildren[2]
|
@@ -56,7 +54,7 @@ class CalcASTBuilder < Rley::ParseRep::ASTBaseBuilder
|
|
56
54
|
end
|
57
55
|
|
58
56
|
# rule 'simple_factor' => %[sign scalar]
|
59
|
-
def reduce_simple_factor_0(
|
57
|
+
def reduce_simple_factor_0(_production, _range, _tokens, theChildren)
|
60
58
|
first_child = theChildren[0]
|
61
59
|
result = if first_child.kind_of?(CalcNegateNode)
|
62
60
|
-theChildren[1]
|
@@ -68,7 +66,7 @@ class CalcASTBuilder < Rley::ParseRep::ASTBaseBuilder
|
|
68
66
|
end
|
69
67
|
|
70
68
|
# rule 'simple_factor' => %w[unary_function in_parenthesis]
|
71
|
-
def reduce_simple_factor_1(
|
69
|
+
def reduce_simple_factor_1(_production, aRange, _tokens, theChildren)
|
72
70
|
func = CalcUnaryFunction.new(theChildren[0].symbol, aRange.low)
|
73
71
|
func.func_name = theChildren[0].value
|
74
72
|
func.children << theChildren[1]
|
@@ -76,15 +74,15 @@ class CalcASTBuilder < Rley::ParseRep::ASTBaseBuilder
|
|
76
74
|
end
|
77
75
|
|
78
76
|
# rule 'simple_factor' => %w[MINUS in_parenthesis]
|
79
|
-
def reduce_simple_factor_2(
|
77
|
+
def reduce_simple_factor_2(_production, aRange, _tokens, theChildren)
|
80
78
|
negation = CalcNegateNode.new(theChildren[0].symbol, aRange.low)
|
81
79
|
negation.children << theChildren[1]
|
82
80
|
return negation
|
83
81
|
end
|
84
82
|
|
85
|
-
|
86
|
-
def reduce_in_parenthesis_0(_production,
|
87
|
-
return_second_child(
|
83
|
+
# rule 'in_parenthesis' => %w[LPAREN expression RPAREN]
|
84
|
+
def reduce_in_parenthesis_0(_production, aRange, theTokens, theChildren)
|
85
|
+
return_second_child(aRange, theTokens, theChildren)
|
88
86
|
end
|
89
87
|
|
90
88
|
# rule 'add_operator' => 'PLUS'
|
@@ -42,7 +42,7 @@ class CalcNumberNode < CalcTerminalNode
|
|
42
42
|
|
43
43
|
# Overriding the unary minus operator
|
44
44
|
def -@()
|
45
|
-
self.value = -
|
45
|
+
self.value = - value
|
46
46
|
return self
|
47
47
|
end
|
48
48
|
end
|
@@ -59,7 +59,6 @@ class CalcConstantNode < CalcNumberNode
|
|
59
59
|
end
|
60
60
|
|
61
61
|
class CalcReservedNode < CalcTerminalNode
|
62
|
-
|
63
62
|
end
|
64
63
|
|
65
64
|
class CalcCompositeNode
|
@@ -84,7 +83,7 @@ end # class
|
|
84
83
|
|
85
84
|
class CalcUnaryOpNode < CalcCompositeNode
|
86
85
|
def initialize(aSymbol, aPosition)
|
87
|
-
super(aSymbol,aPosition)
|
86
|
+
super(aSymbol, aPosition)
|
88
87
|
end
|
89
88
|
|
90
89
|
alias members children
|
@@ -92,7 +91,7 @@ end # class
|
|
92
91
|
|
93
92
|
class CalcNegateNode < CalcUnaryOpNode
|
94
93
|
def interpret()
|
95
|
-
return -
|
94
|
+
return -children[0].interpret
|
96
95
|
end
|
97
96
|
end # class
|
98
97
|
|
@@ -108,7 +107,7 @@ class CalcUnaryFunction < CalcCompositeNode
|
|
108
107
|
|
109
108
|
def interpret()
|
110
109
|
argument = children[0].interpret
|
111
|
-
internal_name = @@name_mapping[@func_name]
|
110
|
+
internal_name = @@name_mapping[@func_name]
|
112
111
|
return Math.send(internal_name.to_sym, argument)
|
113
112
|
end
|
114
113
|
end
|
@@ -177,7 +176,7 @@ class PowerNode < CalcBinaryOpNode
|
|
177
176
|
# TODO
|
178
177
|
def interpret()
|
179
178
|
operands = retrieve_operands
|
180
|
-
exponentiation = operands[0]
|
179
|
+
exponentiation = operands[0]**operands[1]
|
181
180
|
return exponentiation
|
182
181
|
end
|
183
182
|
end # class
|
@@ -21,11 +21,9 @@ class CalcLexer
|
|
21
21
|
'E' => 'E'
|
22
22
|
}.freeze
|
23
23
|
|
24
|
-
@@unary_functions = [
|
25
|
-
|
26
|
-
|
27
|
-
'sqrt', 'cbrt', 'exp',
|
28
|
-
'ln', 'log'
|
24
|
+
@@unary_functions = %w[
|
25
|
+
sin cos tan asin acos atan
|
26
|
+
sqrt cbrt exp ln log
|
29
27
|
].freeze
|
30
28
|
|
31
29
|
class ScanError < StandardError; end
|
@@ -37,6 +37,8 @@ describe 'Calculator' do
|
|
37
37
|
end
|
38
38
|
|
39
39
|
context 'Parsing valid expressions' do
|
40
|
+
let(:epsilon) { 0.0000000001 }
|
41
|
+
|
40
42
|
it 'should evaluate simple integer literals' do
|
41
43
|
expect_expr('2').to eq(2)
|
42
44
|
end
|
@@ -169,10 +171,10 @@ describe 'Calculator' do
|
|
169
171
|
end
|
170
172
|
|
171
173
|
it 'should evaluate exponential of expressions' do
|
172
|
-
expect_expr('exp(-1)').to eq(1/Math::E)
|
174
|
+
expect_expr('exp(-1)').to eq(1 / Math::E)
|
173
175
|
expect_expr('exp(0)').to eq(1)
|
174
176
|
expect_expr('exp(1)').to eq(Math::E)
|
175
|
-
expect_expr('exp(2)').to be_within(
|
177
|
+
expect_expr('exp(2)').to be_within(epsilon).of(Math::E * Math::E)
|
176
178
|
end
|
177
179
|
|
178
180
|
it 'should evaluate natural logarithm of expressions' do
|
@@ -193,42 +195,42 @@ describe 'Calculator' do
|
|
193
195
|
|
194
196
|
it 'should compute the sinus of an expression' do
|
195
197
|
expect_expr('sin(0)').to eq(0)
|
196
|
-
expect_expr('sin(PI/6)').to be_within(
|
198
|
+
expect_expr('sin(PI/6)').to be_within(epsilon).of(0.5)
|
197
199
|
expect_expr('sin(PI/2)').to eq(1)
|
198
200
|
end
|
199
201
|
|
200
202
|
it 'should compute the cosinus of an expression' do
|
201
203
|
expect_expr('cos(0)').to eq(1)
|
202
|
-
expect_expr('cos(PI/3)').to be_within(
|
203
|
-
expect_expr('cos(PI/2)').to be_within(
|
204
|
+
expect_expr('cos(PI/3)').to be_within(epsilon).of(0.5)
|
205
|
+
expect_expr('cos(PI/2)').to be_within(epsilon).of(0)
|
204
206
|
end
|
205
207
|
|
206
208
|
it 'should compute the tangent of an expression' do
|
207
209
|
expect_expr('tan(0)').to eq(0)
|
208
|
-
expect_expr('tan(PI/4)').to be_within(
|
209
|
-
expect_expr('tan(5*PI/12)').to be_within(
|
210
|
+
expect_expr('tan(PI/4)').to be_within(epsilon).of(1)
|
211
|
+
expect_expr('tan(5*PI/12)').to be_within(epsilon).of(2 + Math.sqrt(3))
|
210
212
|
end
|
211
213
|
|
212
214
|
# Inverse trigonometric functions
|
213
215
|
|
214
216
|
it 'should compute the arcsinus of an expression' do
|
215
217
|
expect_expr('asin(0)').to eq(0)
|
216
|
-
expect_expr('asin(0.5)').to be_within(
|
217
|
-
expect_expr('asin(1)').to eq(Math::PI/2)
|
218
|
+
expect_expr('asin(0.5)').to be_within(epsilon).of(Math::PI / 6)
|
219
|
+
expect_expr('asin(1)').to eq(Math::PI / 2)
|
218
220
|
end
|
219
221
|
|
220
222
|
it 'should compute the arccosinus of an expression' do
|
221
223
|
expect_expr('acos(1)').to eq(0)
|
222
|
-
expect_expr('acos(0.5)').to be_within(
|
223
|
-
expect_expr('acos(0)').to be_within(
|
224
|
+
expect_expr('acos(0.5)').to be_within(epsilon).of(Math::PI / 3)
|
225
|
+
expect_expr('acos(0)').to be_within(epsilon).of(Math::PI / 2)
|
224
226
|
end
|
225
227
|
|
226
228
|
it 'should compute the tangent of an expression' do
|
227
229
|
expect_expr('atan(0)').to eq(0)
|
228
|
-
|
229
|
-
expect_expr('atan(
|
230
|
+
pi = Math::PI
|
231
|
+
expect_expr('atan(1)').to be_within(epsilon).of(pi / 4)
|
232
|
+
expect_expr('atan(2 + sqrt(3))').to be_within(epsilon).of(5 * pi / 12)
|
230
233
|
end
|
231
|
-
|
232
234
|
end # context
|
233
235
|
end # describe
|
234
236
|
# End of file
|