dentaku 2.0.4 → 2.0.5

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 568297af6c05c99fdd87b6a2d70cd78b4d1f5828
4
- data.tar.gz: 9e7668dd3998237a5fe6aaf50370dadfb6941bee
3
+ metadata.gz: 91e1c068c1ad4f4399eece3c6ac66ab9c17591cf
4
+ data.tar.gz: 2df26e17bb06fa076d30e56e880b5d5797df1dc3
5
5
  SHA512:
6
- metadata.gz: 51685ec73f241afaed1bf66961b55837792100a0ecf06c2d5b283eca227fdb3129c76045fe676b8416fa40d54e11d1ef0da8ef298c504faeace2f77caf168955
7
- data.tar.gz: a9a6914b90950b7616e3c82c704ab58921d0107045a3f440f5de2848acbf056ee95fefd8f2f63b663cb33f71f72f3733d94f13b7dd1f0895c1285f5bcab9181c
6
+ metadata.gz: 83222ea1e9505e2cdfa692f37142776fdb7be70cf39098d536b6a0c85958272421800f04e7876f9d7ba39bfe4d3eb19a49f2efa5b631b0ecddea4ed858c3e4ca
7
+ data.tar.gz: 32dc26ce15c748d7091c775356735fabf5abdf3f391db3407b663769e56c361247478edae5f3b3dc725aa97cb44b3a635e5212b293dc97af9940dedab83852a8
@@ -1,5 +1,10 @@
1
1
  # Change Log
2
2
 
3
+ ## [v2.0.5] 2015-09-03
4
+ - fix bug with detecting unbound nodes
5
+ - silence warnings
6
+ - allow registration of custom token scanners
7
+
3
8
  ## [v2.0.4] 2015-09-03
4
9
  - fix BigDecimal conversion bug
5
10
  - add caching for bulk expression solving dependency order
@@ -85,6 +90,7 @@
85
90
  ## [v0.1.0] 2012-01-20
86
91
  - initial release
87
92
 
93
+ [v2.0.5]: https://github.com/rubysolo/dentaku/compare/v2.0.4...v2.0.5
88
94
  [v2.0.4]: https://github.com/rubysolo/dentaku/compare/v2.0.3...v2.0.4
89
95
  [v2.0.3]: https://github.com/rubysolo/dentaku/compare/v2.0.1...v2.0.3
90
96
  [v2.0.1]: https://github.com/rubysolo/dentaku/compare/v2.0.0...v2.0.1
@@ -3,6 +3,9 @@ require "dentaku/calculator"
3
3
  require "dentaku/version"
4
4
 
5
5
  module Dentaku
6
+ @enable_ast_caching = false
7
+ @enable_dependency_order_caching = false
8
+
6
9
  def self.evaluate(expression, data={})
7
10
  calculator.evaluate(expression, data)
8
11
  end
@@ -29,7 +29,7 @@ module Dentaku
29
29
  end
30
30
 
31
31
  def valid_node?(node)
32
- node.is_a?(Identifier) || node.type == :numeric
32
+ node.dependencies.any? || node.type == :numeric
33
33
  end
34
34
  end
35
35
 
@@ -15,7 +15,7 @@ module Dentaku
15
15
  private
16
16
 
17
17
  def valid_node?(node)
18
- node.is_a?(Identifier) || node.type == :logical
18
+ node.dependencies.any? || node.type == :logical
19
19
  end
20
20
  end
21
21
 
@@ -12,6 +12,10 @@ module Dentaku
12
12
  def type
13
13
  @node.type
14
14
  end
15
+
16
+ def dependencies(context={})
17
+ @node.dependencies(context)
18
+ end
15
19
  end
16
20
  end
17
21
  end
@@ -26,10 +26,14 @@ module Dentaku
26
26
  40
27
27
  end
28
28
 
29
+ def dependencies(context={})
30
+ @node.dependencies(context)
31
+ end
32
+
29
33
  private
30
34
 
31
35
  def valid_node?(node)
32
- node.is_a?(Identifier) || node.type == :numeric
36
+ node.dependencies.any? || node.type == :numeric
33
37
  end
34
38
  end
35
39
  end
@@ -8,6 +8,10 @@ module Dentaku
8
8
  def self.arity
9
9
  nil
10
10
  end
11
+
12
+ def dependencies(context={})
13
+ []
14
+ end
11
15
  end
12
16
  end
13
17
  end
@@ -41,16 +41,26 @@ module Dentaku
41
41
  ]
42
42
  end
43
43
 
44
- def scanners=(token_scanners)
45
- @scanners = (token_scanners & available_scanners).map { |scanner|
46
- self.send(scanner)
47
- }
44
+ def register_default_scanners
45
+ register_scanners(available_scanners)
46
+ end
47
+
48
+ def register_scanners(scanner_ids)
49
+ @scanners = scanner_ids.each_with_object({}) do |id, scanners|
50
+ scanners[id] = self.send(id)
51
+ end
52
+ end
53
+
54
+ def register_scanner(id, scanner)
55
+ @scanners[id] = scanner
56
+ end
57
+
58
+ def scanners=(scanner_ids)
59
+ @scanners.select! { |k,v| scanner_ids.include?(k) }
48
60
  end
49
61
 
50
62
  def scanners
51
- @scanners ||= available_scanners.map { |scanner|
52
- self.send(scanner)
53
- }
63
+ @scanners.values
54
64
  end
55
65
 
56
66
  def whitespace
@@ -112,8 +122,10 @@ module Dentaku
112
122
  end
113
123
 
114
124
  def identifier
115
- new(:identifier, '\w+\b', lambda { |raw| raw.strip.downcase.to_s })
125
+ new(:identifier, '\w+\b', lambda { |raw| raw.strip.downcase })
116
126
  end
117
127
  end
128
+
129
+ register_default_scanners
118
130
  end
119
131
  end
@@ -1,3 +1,3 @@
1
1
  module Dentaku
2
- VERSION = "2.0.4"
2
+ VERSION = "2.0.5"
3
3
  end
@@ -22,6 +22,9 @@ describe Dentaku::AST::Node do
22
22
 
23
23
  node = make_node('if(x > 5, y, z)')
24
24
  expect(node.dependencies('x' => 7)).to eq ['y', 'z']
25
+
26
+ node = make_node('')
27
+ expect(node.dependencies).to eq []
25
28
  end
26
29
 
27
30
  it 'returns unique list of dependencies' do
@@ -221,6 +221,12 @@ describe Dentaku::Calculator do
221
221
  expect(calculator.evaluate('round(-1.23, 1)')).to eq(BigDecimal.new('-1.2'))
222
222
  expect(calculator.evaluate('NOT(some_boolean) AND -1 > 3', some_boolean: true)).to be_falsey
223
223
  end
224
+
225
+ it 'evaluates functions with stored variables' do
226
+ calculator.store("multi_color" => true, "number_of_sheets" => 5000, "sheets_per_minute_black" => 2000, "sheets_per_minute_color" => 1000)
227
+ result = calculator.evaluate('number_of_sheets / if(multi_color, sheets_per_minute_color, sheets_per_minute_black)')
228
+ expect(result).to eq(5)
229
+ end
224
230
  end
225
231
 
226
232
  describe 'math functions' do
@@ -3,8 +3,13 @@ require 'dentaku/token_scanner'
3
3
  describe Dentaku::TokenScanner do
4
4
  let(:whitespace) { described_class.new(:whitespace, '\s') }
5
5
  let(:numeric) { described_class.new(:numeric, '(\d+(\.\d+)?|\.\d+)',
6
- lambda { |raw| raw =~ /\./ ? BigDecimal.new(raw) : raw.to_i })
6
+ ->(raw) { raw =~ /\./ ? BigDecimal.new(raw) : raw.to_i })
7
7
  }
8
+ let(:custom) { described_class.new(:identifier, '#\w+\b',
9
+ ->(raw) { raw.gsub('#', '').to_sym })
10
+ }
11
+
12
+ after { described_class.register_default_scanners }
8
13
 
9
14
  it 'returns a token for a matching string' do
10
15
  token = whitespace.scan(' ').first
@@ -29,12 +34,20 @@ describe Dentaku::TokenScanner do
29
34
  it 'allows customizing available scanners' do
30
35
  described_class.scanners = [:whitespace, :numeric]
31
36
  expect(described_class.scanners.length).to eq 2
32
- described_class.scanners = described_class.available_scanners
33
37
  end
34
38
 
35
39
  it 'ignores invalid scanners' do
36
40
  described_class.scanners = [:whitespace, :numeric, :fake]
37
41
  expect(described_class.scanners.length).to eq 2
38
- described_class.scanners = described_class.available_scanners
42
+ end
43
+
44
+ it 'uses a custom scanner' do
45
+ described_class.scanners = [:whitespace, :numeric]
46
+ described_class.register_scanner(:custom, custom)
47
+ expect(described_class.scanners.length).to eq 3
48
+
49
+ token = custom.scan('#apple + #pear').first
50
+ expect(token.category).to eq(:identifier)
51
+ expect(token.value).to eq(:apple)
39
52
  end
40
53
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dentaku
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.4
4
+ version: 2.0.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Solomon White
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-09-03 00:00:00.000000000 Z
11
+ date: 2015-10-19 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake
@@ -141,7 +141,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
141
141
  version: '0'
142
142
  requirements: []
143
143
  rubyforge_project: dentaku
144
- rubygems_version: 2.4.8
144
+ rubygems_version: 2.4.5.1
145
145
  signing_key:
146
146
  specification_version: 4
147
147
  summary: A formula language parser and evaluator