dentaku 2.0.4 → 2.0.5

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 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