logicality 1.0.5 → 2.0.0
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 +5 -5
- data/.gitignore +2 -0
- data/.rubocop.yml +6 -0
- data/.rubocop_todo.yml +2 -2
- data/.ruby-version +1 -1
- data/.travis.yml +14 -2
- data/CHANGELOG.md +10 -0
- data/Gemfile.lock +61 -9
- data/Guardfile +16 -0
- data/README.md +33 -5
- data/bin/console +15 -0
- data/lib/logicality/lexer/grammar.rb +6 -6
- data/lib/logicality/logicality.rb +54 -1
- data/lib/logicality/version.rb +1 -1
- data/logicality.gemspec +5 -2
- data/spec/{logic_spec.rb → logicality_spec.rb} +3 -3
- data/spec/spec_helper.rb +16 -0
- metadata +57 -11
- data/lib/logicality/logic.rb +0 -66
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
|
-
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: 9c095a928ca7ca83e2ac40bdbbe85569bf66475d78deea2aa48e3b78400aa71a
|
|
4
|
+
data.tar.gz: 131023ffc29713d3f48a57c9ba8422066872289c646cc06d7ce494ecebbc68aa
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 1230714c64c4756c0eb2e312502b322cb0466b97ee293a09306a2f5d43347857c69a27d2d19fa1b3abf40f4a86dc9099d022af498eced1f3aa1d99853a5cd98f
|
|
7
|
+
data.tar.gz: f4c7b55eb37bbcf67a4415f327bafc91802ead3ad4a07a39be1c1682b41e685b64f98a2d3983d6eb8145ab96097e7b1ac7edb77c62807392e8b34694d51f3619
|
data/.gitignore
CHANGED
data/.rubocop.yml
CHANGED
data/.rubocop_todo.yml
CHANGED
|
@@ -25,10 +25,10 @@ Metrics/MethodLength:
|
|
|
25
25
|
Style/DoubleNegation:
|
|
26
26
|
Exclude:
|
|
27
27
|
- 'lib/logicality/interpreter/simple_interpreter.rb'
|
|
28
|
-
- 'lib/logicality/
|
|
28
|
+
- 'lib/logicality/logicality.rb'
|
|
29
29
|
|
|
30
30
|
# Offense count: 1
|
|
31
31
|
# Cop supports --auto-correct.
|
|
32
32
|
Style/OrAssignment:
|
|
33
33
|
Exclude:
|
|
34
|
-
- 'lib/logicality/
|
|
34
|
+
- 'lib/logicality/logicality.rb'
|
data/.ruby-version
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
2.
|
|
1
|
+
2.6.0
|
data/.travis.yml
CHANGED
|
@@ -1,8 +1,20 @@
|
|
|
1
|
+
env:
|
|
2
|
+
global:
|
|
3
|
+
- CC_TEST_REPORTER_ID=20e69ab96711ba4fbc9e0ddce90bc3fc33cd5b110194aa778ed1ec227b597f09
|
|
1
4
|
language: ruby
|
|
2
5
|
rvm:
|
|
3
|
-
|
|
4
|
-
- 2.3.
|
|
6
|
+
# Build on the latest stable of all supported Rubies (https://www.ruby-lang.org/en/downloads/):
|
|
7
|
+
- 2.3.8
|
|
8
|
+
- 2.4.5
|
|
9
|
+
- 2.5.3
|
|
10
|
+
- 2.6.0
|
|
5
11
|
cache: bundler
|
|
12
|
+
before_script:
|
|
13
|
+
- curl -L https://codeclimate.com/downloads/test-reporter/test-reporter-latest-linux-amd64 > ./cc-test-reporter
|
|
14
|
+
- chmod +x ./cc-test-reporter
|
|
15
|
+
- ./cc-test-reporter before-build
|
|
6
16
|
script:
|
|
7
17
|
- bundle exec rubocop
|
|
8
18
|
- bundle exec rspec
|
|
19
|
+
after_script:
|
|
20
|
+
- ./cc-test-reporter after-build --exit-code $TRAVIS_TEST_RESULT
|
data/CHANGELOG.md
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
# 2.0.0 (January 30th, 2019)
|
|
2
|
+
|
|
3
|
+
Maintenance Release + Top-Level API Change
|
|
4
|
+
|
|
5
|
+
* Added bin/console script
|
|
6
|
+
* Added CHANGELOG
|
|
7
|
+
* Updated README with publication steps, additional testing steps
|
|
8
|
+
* Bumped minimum Ruby to 2.3.8
|
|
9
|
+
* Added Guard
|
|
10
|
+
* Changed Logicality::Logic#evaluate to Logicality#evaluate (breaking change)
|
data/Gemfile.lock
CHANGED
|
@@ -1,19 +1,56 @@
|
|
|
1
1
|
PATH
|
|
2
2
|
remote: .
|
|
3
3
|
specs:
|
|
4
|
-
logicality (
|
|
4
|
+
logicality (2.0.0)
|
|
5
5
|
|
|
6
6
|
GEM
|
|
7
7
|
remote: https://rubygems.org/
|
|
8
8
|
specs:
|
|
9
|
+
ansi (1.5.0)
|
|
9
10
|
ast (2.4.0)
|
|
11
|
+
coderay (1.1.2)
|
|
10
12
|
diff-lcs (1.3)
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
13
|
+
docile (1.3.1)
|
|
14
|
+
ffi (1.10.0)
|
|
15
|
+
formatador (0.2.5)
|
|
16
|
+
guard (2.15.0)
|
|
17
|
+
formatador (>= 0.2.4)
|
|
18
|
+
listen (>= 2.7, < 4.0)
|
|
19
|
+
lumberjack (>= 1.0.12, < 2.0)
|
|
20
|
+
nenv (~> 0.1)
|
|
21
|
+
notiffany (~> 0.0)
|
|
22
|
+
pry (>= 0.9.12)
|
|
23
|
+
shellany (~> 0.0)
|
|
24
|
+
thor (>= 0.18.1)
|
|
25
|
+
guard-compat (1.2.1)
|
|
26
|
+
guard-rspec (4.7.3)
|
|
27
|
+
guard (~> 2.1)
|
|
28
|
+
guard-compat (~> 1.1)
|
|
29
|
+
rspec (>= 2.99.0, < 4.0)
|
|
30
|
+
hirb (0.7.3)
|
|
31
|
+
jaro_winkler (1.5.2)
|
|
32
|
+
json (2.1.0)
|
|
33
|
+
listen (3.1.5)
|
|
34
|
+
rb-fsevent (~> 0.9, >= 0.9.4)
|
|
35
|
+
rb-inotify (~> 0.9, >= 0.9.7)
|
|
36
|
+
ruby_dep (~> 1.2)
|
|
37
|
+
lumberjack (1.0.13)
|
|
38
|
+
method_source (0.9.2)
|
|
39
|
+
nenv (0.3.0)
|
|
40
|
+
notiffany (0.1.1)
|
|
41
|
+
nenv (~> 0.1)
|
|
42
|
+
shellany (~> 0.0)
|
|
43
|
+
parallel (1.13.0)
|
|
44
|
+
parser (2.6.0.0)
|
|
14
45
|
ast (~> 2.4.0)
|
|
15
46
|
powerpack (0.1.2)
|
|
47
|
+
pry (0.12.2)
|
|
48
|
+
coderay (~> 1.1.0)
|
|
49
|
+
method_source (~> 0.9.0)
|
|
16
50
|
rainbow (3.0.0)
|
|
51
|
+
rb-fsevent (0.10.3)
|
|
52
|
+
rb-inotify (0.10.0)
|
|
53
|
+
ffi (~> 1.0)
|
|
17
54
|
rspec (3.8.0)
|
|
18
55
|
rspec-core (~> 3.8.0)
|
|
19
56
|
rspec-expectations (~> 3.8.0)
|
|
@@ -27,24 +64,39 @@ GEM
|
|
|
27
64
|
diff-lcs (>= 1.2.0, < 2.0)
|
|
28
65
|
rspec-support (~> 3.8.0)
|
|
29
66
|
rspec-support (3.8.0)
|
|
30
|
-
rubocop (0.
|
|
67
|
+
rubocop (0.63.1)
|
|
31
68
|
jaro_winkler (~> 1.5.1)
|
|
32
69
|
parallel (~> 1.10)
|
|
33
70
|
parser (>= 2.5, != 2.5.1.1)
|
|
34
71
|
powerpack (~> 0.1)
|
|
35
72
|
rainbow (>= 2.2.2, < 4.0)
|
|
36
73
|
ruby-progressbar (~> 1.7)
|
|
37
|
-
unicode-display_width (~> 1.
|
|
74
|
+
unicode-display_width (~> 1.4.0)
|
|
38
75
|
ruby-progressbar (1.10.0)
|
|
39
|
-
|
|
76
|
+
ruby_dep (1.5.0)
|
|
77
|
+
shellany (0.0.1)
|
|
78
|
+
simplecov (0.16.1)
|
|
79
|
+
docile (~> 1.1)
|
|
80
|
+
json (>= 1.8, < 3)
|
|
81
|
+
simplecov-html (~> 0.10.0)
|
|
82
|
+
simplecov-console (0.4.2)
|
|
83
|
+
ansi
|
|
84
|
+
hirb
|
|
85
|
+
simplecov
|
|
86
|
+
simplecov-html (0.10.2)
|
|
87
|
+
thor (0.20.3)
|
|
88
|
+
unicode-display_width (1.4.1)
|
|
40
89
|
|
|
41
90
|
PLATFORMS
|
|
42
91
|
ruby
|
|
43
92
|
|
|
44
93
|
DEPENDENCIES
|
|
94
|
+
guard-rspec (~> 4.7)
|
|
45
95
|
logicality!
|
|
46
96
|
rspec
|
|
47
|
-
rubocop (~> 0.
|
|
97
|
+
rubocop (~> 0.63.1)
|
|
98
|
+
simplecov (~> 0.16.1)
|
|
99
|
+
simplecov-console (~> 0.4.2)
|
|
48
100
|
|
|
49
101
|
BUNDLED WITH
|
|
50
|
-
1.
|
|
102
|
+
1.17.2
|
data/Guardfile
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
guard :rspec, cmd: 'bundle exec rspec' do
|
|
4
|
+
require 'guard/rspec/dsl'
|
|
5
|
+
dsl = Guard::RSpec::Dsl.new(self)
|
|
6
|
+
|
|
7
|
+
# RSpec files
|
|
8
|
+
rspec = dsl.rspec
|
|
9
|
+
watch(rspec.spec_helper) { rspec.spec_dir }
|
|
10
|
+
watch(rspec.spec_support) { rspec.spec_dir }
|
|
11
|
+
watch(rspec.spec_files)
|
|
12
|
+
|
|
13
|
+
# Ruby files
|
|
14
|
+
ruby = dsl.ruby
|
|
15
|
+
dsl.watch_spec_files_for(ruby.lib_files)
|
|
16
|
+
end
|
data/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
# Logicality
|
|
4
4
|
|
|
5
|
-
[](https://travis-ci.org/bluemarblepayroll/logicality-rb)
|
|
5
|
+
[](https://badge.fury.io/rb/logicality) [](https://travis-ci.org/bluemarblepayroll/logicality-rb) [](https://codeclimate.com/github/bluemarblepayroll/logicality-rb/maintainability) [](https://codeclimate.com/github/bluemarblepayroll/logicality-rb/test_coverage) [](https://opensource.org/licenses/MIT)
|
|
6
6
|
|
|
7
7
|
A common problem that many frameworks have is the ability to give developers an expressive
|
|
8
8
|
intermediary scripting language or DSL. Logicality helps solve this problem by providing a simple
|
|
@@ -19,7 +19,7 @@ resolving boolean values such as:
|
|
|
19
19
|
|
|
20
20
|
## Credit
|
|
21
21
|
|
|
22
|
-
Deep inspiration was taken from [this set of articles](https://ruslanspivak.com/lsbasi-part7/).
|
|
22
|
+
Deep inspiration was taken from [this set of articles](https://ruslanspivak.com/lsbasi-part7/).
|
|
23
23
|
Here, the author gives details around the theory and practical implementation of creating a basic
|
|
24
24
|
language processor and compiler.
|
|
25
25
|
|
|
@@ -51,7 +51,7 @@ Now you can bind and evaluate this expression against passed in objects:
|
|
|
51
51
|
|
|
52
52
|
````
|
|
53
53
|
record = { 'visible' => false, 'admin' => true }
|
|
54
|
-
visible = Logicality
|
|
54
|
+
visible = Logicality.evaluate('visible || admin', record) # resolves to true.
|
|
55
55
|
````
|
|
56
56
|
|
|
57
57
|
### Plugging in a Custom Resolver
|
|
@@ -65,7 +65,7 @@ resolver = lambda do |value, input|
|
|
|
65
65
|
end
|
|
66
66
|
|
|
67
67
|
record = { visible: false, admin: true }
|
|
68
|
-
visible = Logicality
|
|
68
|
+
visible = Logicality.evaluate('visible || admin', record, resolver) # resolves to true.
|
|
69
69
|
````
|
|
70
70
|
|
|
71
71
|
## Contributing
|
|
@@ -85,9 +85,37 @@ Basic steps to take to get this repository compiling:
|
|
|
85
85
|
To execute the test suite run:
|
|
86
86
|
|
|
87
87
|
````
|
|
88
|
-
rspec
|
|
88
|
+
bundle exec rspec spec --format documentation
|
|
89
89
|
````
|
|
90
90
|
|
|
91
|
+
Alternatively, you can have Guard watch for changes:
|
|
92
|
+
|
|
93
|
+
````
|
|
94
|
+
bundle exec guard
|
|
95
|
+
````
|
|
96
|
+
|
|
97
|
+
Also, do not forget to run Rubocop:
|
|
98
|
+
|
|
99
|
+
````
|
|
100
|
+
bundle exec rubocop
|
|
101
|
+
````
|
|
102
|
+
|
|
103
|
+
### Publishing
|
|
104
|
+
|
|
105
|
+
Note: ensure you have proper authorization before trying to publish new versions.
|
|
106
|
+
|
|
107
|
+
After code changes have successfully gone through the Pull Request review process then the following steps should be followed for publishing new versions:
|
|
108
|
+
|
|
109
|
+
1. Merge Pull Request into master
|
|
110
|
+
2. Update ```lib/logicality/version.rb``` using [semantic versioning](https://semver.org/)
|
|
111
|
+
3. Install dependencies: ```bundle```
|
|
112
|
+
4. Update ```CHANGELOG.md``` with release notes
|
|
113
|
+
5. Commit & push master to remote and ensure CI builds master successfully
|
|
114
|
+
6. Build the project locally: `gem build logicality`
|
|
115
|
+
7. Publish package to RubyGems: `gem push logicality-X.gem` where X is the version to push
|
|
116
|
+
8. Tag master with new version: `git tag <version>`
|
|
117
|
+
9. Push tags remotely: `git push origin --tags`
|
|
118
|
+
|
|
91
119
|
## License
|
|
92
120
|
|
|
93
121
|
This project is MIT Licensed.
|
data/bin/console
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
# frozen_string_literal: true
|
|
3
|
+
|
|
4
|
+
require 'bundler/setup'
|
|
5
|
+
require 'logicality'
|
|
6
|
+
|
|
7
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
|
8
|
+
# with your gem easier. You can also use a different console, if you like.
|
|
9
|
+
|
|
10
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
|
11
|
+
# require "pry"
|
|
12
|
+
# Pry.start
|
|
13
|
+
|
|
14
|
+
require 'irb'
|
|
15
|
+
IRB.start
|
|
@@ -11,12 +11,12 @@ module Logicality
|
|
|
11
11
|
module Lexer
|
|
12
12
|
# Define the main regular expression matchers used by the lexer.
|
|
13
13
|
module Grammar
|
|
14
|
-
VALUE = /([a-zA-Z0-9_$@?\.]+)
|
|
15
|
-
AND_OP = /(&&)
|
|
16
|
-
OR_OP = /(\|\|)
|
|
17
|
-
NOT_OP = /(\!)
|
|
18
|
-
LEFT_PAREN = /(\()
|
|
19
|
-
RIGHT_PAREN = /(\))
|
|
14
|
+
VALUE = /([a-zA-Z0-9_$@?\.]+)/.freeze
|
|
15
|
+
AND_OP = /(&&)/.freeze
|
|
16
|
+
OR_OP = /(\|\|)/.freeze
|
|
17
|
+
NOT_OP = /(\!)/.freeze
|
|
18
|
+
LEFT_PAREN = /(\()/.freeze
|
|
19
|
+
RIGHT_PAREN = /(\))/.freeze
|
|
20
20
|
end
|
|
21
21
|
end
|
|
22
22
|
end
|
|
@@ -10,4 +10,57 @@
|
|
|
10
10
|
require_relative 'lexer/lexer'
|
|
11
11
|
require_relative 'parser/parser'
|
|
12
12
|
require_relative 'interpreter/interpreter'
|
|
13
|
-
|
|
13
|
+
|
|
14
|
+
# Module that defines the main class-level API for this library.
|
|
15
|
+
module Logicality
|
|
16
|
+
class << self
|
|
17
|
+
def evaluate(expression, input = nil, resolver = nil)
|
|
18
|
+
node = get(expression)
|
|
19
|
+
wrapper = resolver_wrapper(input, resolver)
|
|
20
|
+
interpreter = Interpreter::SimpleInterpreter.new(wrapper)
|
|
21
|
+
|
|
22
|
+
interpreter.visit(node)
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
private
|
|
26
|
+
|
|
27
|
+
def resolver_wrapper(input, resolver)
|
|
28
|
+
if resolver
|
|
29
|
+
->(value) { resolver.call(value, input) }
|
|
30
|
+
else
|
|
31
|
+
->(value) { object_resolver.call(value, input) }
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def object_resolver
|
|
36
|
+
lambda do |value, input|
|
|
37
|
+
return false unless input
|
|
38
|
+
|
|
39
|
+
if input.respond_to?(value)
|
|
40
|
+
!!input.send(value)
|
|
41
|
+
elsif input.respond_to?(:[])
|
|
42
|
+
!!input[value]
|
|
43
|
+
else
|
|
44
|
+
false
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def cache
|
|
50
|
+
@cache ||= {}
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def set(expression, node)
|
|
54
|
+
cache[expression] ||= node
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def get(expression)
|
|
58
|
+
return cache[expression] if cache[expression]
|
|
59
|
+
|
|
60
|
+
lexer = Lexer::RegexpLexer.new(expression)
|
|
61
|
+
parser = Parser::SimpleParser.new(lexer)
|
|
62
|
+
|
|
63
|
+
set(expression, parser.parse)
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
end
|
data/lib/logicality/version.rb
CHANGED
data/logicality.gemspec
CHANGED
|
@@ -22,8 +22,11 @@ Gem::Specification.new do |s|
|
|
|
22
22
|
s.homepage = 'https://github.com/bluemarblepayroll/logicality-rb'
|
|
23
23
|
s.license = 'MIT'
|
|
24
24
|
|
|
25
|
-
s.required_ruby_version = '>= 2.3.
|
|
25
|
+
s.required_ruby_version = '>= 2.3.8'
|
|
26
26
|
|
|
27
|
+
s.add_development_dependency('guard-rspec', '~>4.7')
|
|
27
28
|
s.add_development_dependency('rspec')
|
|
28
|
-
s.add_development_dependency('rubocop', '~>
|
|
29
|
+
s.add_development_dependency('rubocop', '~>0.63.1')
|
|
30
|
+
s.add_development_dependency('simplecov', '~>0.16.1')
|
|
31
|
+
s.add_development_dependency('simplecov-console', '~>0.4.2')
|
|
29
32
|
end
|
|
@@ -7,13 +7,13 @@
|
|
|
7
7
|
# LICENSE file in the root directory of this source tree.
|
|
8
8
|
#
|
|
9
9
|
|
|
10
|
-
require './
|
|
10
|
+
require './spec/spec_helper'
|
|
11
11
|
|
|
12
12
|
def run(tests)
|
|
13
13
|
tests.each do |x|
|
|
14
14
|
input = x[1] ? x[1].map { |k, v| [k.to_s, v] }.to_h : nil
|
|
15
15
|
|
|
16
|
-
result = Logicality
|
|
16
|
+
result = Logicality.evaluate(x[0], input)
|
|
17
17
|
|
|
18
18
|
expect(result).to eq(x[2]), "Failed: #{x[0]} (input: #{input}): expected #{x[2]} got: #{result}"
|
|
19
19
|
end
|
|
@@ -21,7 +21,7 @@ def run(tests)
|
|
|
21
21
|
nil
|
|
22
22
|
end
|
|
23
23
|
|
|
24
|
-
describe Logicality
|
|
24
|
+
describe Logicality do
|
|
25
25
|
context 'when evaluating' do
|
|
26
26
|
it 'should evaluate boolean-only expressions' do
|
|
27
27
|
tests = [
|
data/spec/spec_helper.rb
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
#
|
|
4
|
+
# Copyright (c) 2018-present, Blue Marble Payroll, LLC
|
|
5
|
+
#
|
|
6
|
+
# This source code is licensed under the MIT license found in the
|
|
7
|
+
# LICENSE file in the root directory of this source tree.
|
|
8
|
+
#
|
|
9
|
+
|
|
10
|
+
require 'simplecov'
|
|
11
|
+
require 'simplecov-console'
|
|
12
|
+
|
|
13
|
+
SimpleCov.formatter = SimpleCov::Formatter::Console
|
|
14
|
+
SimpleCov.start
|
|
15
|
+
|
|
16
|
+
require './lib/logicality'
|
metadata
CHANGED
|
@@ -1,15 +1,29 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: logicality
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version:
|
|
4
|
+
version: 2.0.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Matthew Ruggio
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date:
|
|
11
|
+
date: 2019-02-05 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
|
+
- !ruby/object:Gem::Dependency
|
|
14
|
+
name: guard-rspec
|
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
|
16
|
+
requirements:
|
|
17
|
+
- - "~>"
|
|
18
|
+
- !ruby/object:Gem::Version
|
|
19
|
+
version: '4.7'
|
|
20
|
+
type: :development
|
|
21
|
+
prerelease: false
|
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
23
|
+
requirements:
|
|
24
|
+
- - "~>"
|
|
25
|
+
- !ruby/object:Gem::Version
|
|
26
|
+
version: '4.7'
|
|
13
27
|
- !ruby/object:Gem::Dependency
|
|
14
28
|
name: rspec
|
|
15
29
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -30,14 +44,42 @@ dependencies:
|
|
|
30
44
|
requirements:
|
|
31
45
|
- - "~>"
|
|
32
46
|
- !ruby/object:Gem::Version
|
|
33
|
-
version: 0.
|
|
47
|
+
version: 0.63.1
|
|
48
|
+
type: :development
|
|
49
|
+
prerelease: false
|
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
51
|
+
requirements:
|
|
52
|
+
- - "~>"
|
|
53
|
+
- !ruby/object:Gem::Version
|
|
54
|
+
version: 0.63.1
|
|
55
|
+
- !ruby/object:Gem::Dependency
|
|
56
|
+
name: simplecov
|
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
|
58
|
+
requirements:
|
|
59
|
+
- - "~>"
|
|
60
|
+
- !ruby/object:Gem::Version
|
|
61
|
+
version: 0.16.1
|
|
62
|
+
type: :development
|
|
63
|
+
prerelease: false
|
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
65
|
+
requirements:
|
|
66
|
+
- - "~>"
|
|
67
|
+
- !ruby/object:Gem::Version
|
|
68
|
+
version: 0.16.1
|
|
69
|
+
- !ruby/object:Gem::Dependency
|
|
70
|
+
name: simplecov-console
|
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
|
72
|
+
requirements:
|
|
73
|
+
- - "~>"
|
|
74
|
+
- !ruby/object:Gem::Version
|
|
75
|
+
version: 0.4.2
|
|
34
76
|
type: :development
|
|
35
77
|
prerelease: false
|
|
36
78
|
version_requirements: !ruby/object:Gem::Requirement
|
|
37
79
|
requirements:
|
|
38
80
|
- - "~>"
|
|
39
81
|
- !ruby/object:Gem::Version
|
|
40
|
-
version: 0.
|
|
82
|
+
version: 0.4.2
|
|
41
83
|
description: |2
|
|
42
84
|
A common problem that many frameworks have is the ability to give developers
|
|
43
85
|
an expressive intermediary scripting language or DSL.
|
|
@@ -45,7 +87,8 @@ description: |2
|
|
|
45
87
|
expression evaluator.
|
|
46
88
|
email:
|
|
47
89
|
- mruggio@bluemarblepayroll.com
|
|
48
|
-
executables:
|
|
90
|
+
executables:
|
|
91
|
+
- console
|
|
49
92
|
extensions: []
|
|
50
93
|
extra_rdoc_files: []
|
|
51
94
|
files:
|
|
@@ -55,10 +98,13 @@ files:
|
|
|
55
98
|
- ".rubocop_todo.yml"
|
|
56
99
|
- ".ruby-version"
|
|
57
100
|
- ".travis.yml"
|
|
101
|
+
- CHANGELOG.md
|
|
58
102
|
- Gemfile
|
|
59
103
|
- Gemfile.lock
|
|
104
|
+
- Guardfile
|
|
60
105
|
- LICENSE
|
|
61
106
|
- README.md
|
|
107
|
+
- bin/console
|
|
62
108
|
- lib/logicality.rb
|
|
63
109
|
- lib/logicality/interpreter/interpreter.rb
|
|
64
110
|
- lib/logicality/interpreter/node_visitor.rb
|
|
@@ -67,7 +113,6 @@ files:
|
|
|
67
113
|
- lib/logicality/lexer/lexer.rb
|
|
68
114
|
- lib/logicality/lexer/regexp_lexer.rb
|
|
69
115
|
- lib/logicality/lexer/token.rb
|
|
70
|
-
- lib/logicality/logic.rb
|
|
71
116
|
- lib/logicality/logicality.rb
|
|
72
117
|
- lib/logicality/parser/ast/ast.rb
|
|
73
118
|
- lib/logicality/parser/ast/binary_operator_node.rb
|
|
@@ -78,7 +123,8 @@ files:
|
|
|
78
123
|
- lib/logicality/parser/simple_parser.rb
|
|
79
124
|
- lib/logicality/version.rb
|
|
80
125
|
- logicality.gemspec
|
|
81
|
-
- spec/
|
|
126
|
+
- spec/logicality_spec.rb
|
|
127
|
+
- spec/spec_helper.rb
|
|
82
128
|
homepage: https://github.com/bluemarblepayroll/logicality-rb
|
|
83
129
|
licenses:
|
|
84
130
|
- MIT
|
|
@@ -91,17 +137,17 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
|
91
137
|
requirements:
|
|
92
138
|
- - ">="
|
|
93
139
|
- !ruby/object:Gem::Version
|
|
94
|
-
version: 2.3.
|
|
140
|
+
version: 2.3.8
|
|
95
141
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
96
142
|
requirements:
|
|
97
143
|
- - ">="
|
|
98
144
|
- !ruby/object:Gem::Version
|
|
99
145
|
version: '0'
|
|
100
146
|
requirements: []
|
|
101
|
-
|
|
102
|
-
rubygems_version: 2.5.2.3
|
|
147
|
+
rubygems_version: 3.0.1
|
|
103
148
|
signing_key:
|
|
104
149
|
specification_version: 4
|
|
105
150
|
summary: String-based boolean expression evaluator
|
|
106
151
|
test_files:
|
|
107
|
-
- spec/
|
|
152
|
+
- spec/logicality_spec.rb
|
|
153
|
+
- spec/spec_helper.rb
|
data/lib/logicality/logic.rb
DELETED
|
@@ -1,66 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
#
|
|
4
|
-
# Copyright (c) 2018-present, Blue Marble Payroll, LLC
|
|
5
|
-
#
|
|
6
|
-
# This source code is licensed under the MIT license found in the
|
|
7
|
-
# LICENSE file in the root directory of this source tree.
|
|
8
|
-
#
|
|
9
|
-
|
|
10
|
-
module Logicality
|
|
11
|
-
# Class that defines the main class-level API for this library.
|
|
12
|
-
class Logic
|
|
13
|
-
class << self
|
|
14
|
-
def evaluate(expression, input = nil, resolver = nil)
|
|
15
|
-
node = get(expression)
|
|
16
|
-
wrapper = resolver_wrapper(input, resolver)
|
|
17
|
-
interpreter = Interpreter::SimpleInterpreter.new(wrapper)
|
|
18
|
-
|
|
19
|
-
interpreter.visit(node)
|
|
20
|
-
end
|
|
21
|
-
|
|
22
|
-
private
|
|
23
|
-
|
|
24
|
-
def resolver_wrapper(input, resolver)
|
|
25
|
-
if resolver
|
|
26
|
-
->(value) { resolver.call(value, input) }
|
|
27
|
-
else
|
|
28
|
-
->(value) { object_resolver.call(value, input) }
|
|
29
|
-
end
|
|
30
|
-
end
|
|
31
|
-
|
|
32
|
-
def object_resolver
|
|
33
|
-
lambda do |value, input|
|
|
34
|
-
return false unless input
|
|
35
|
-
|
|
36
|
-
if input.respond_to?(value)
|
|
37
|
-
!!input.send(value)
|
|
38
|
-
elsif input.respond_to?(:[])
|
|
39
|
-
!!input[value]
|
|
40
|
-
else
|
|
41
|
-
false
|
|
42
|
-
end
|
|
43
|
-
end
|
|
44
|
-
end
|
|
45
|
-
|
|
46
|
-
def cache
|
|
47
|
-
@cache || {}
|
|
48
|
-
end
|
|
49
|
-
|
|
50
|
-
def set(expression, node)
|
|
51
|
-
@cache = {} unless @cache
|
|
52
|
-
|
|
53
|
-
@cache[expression] = node
|
|
54
|
-
end
|
|
55
|
-
|
|
56
|
-
def get(expression)
|
|
57
|
-
return cache[expression] if cache[expression]
|
|
58
|
-
|
|
59
|
-
lexer = Lexer::RegexpLexer.new(expression)
|
|
60
|
-
parser = Parser::SimpleParser.new(lexer)
|
|
61
|
-
|
|
62
|
-
set(expression, parser.parse)
|
|
63
|
-
end
|
|
64
|
-
end
|
|
65
|
-
end
|
|
66
|
-
end
|