logicality 1.0.4 → 1.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 +4 -4
- data/.rubocop.yml +4 -0
- data/.rubocop_todo.yml +34 -0
- data/.travis.yml +1 -0
- data/Gemfile +2 -0
- data/Gemfile.lock +19 -1
- data/lib/logicality/interpreter/interpreter.rb +2 -0
- data/lib/logicality/interpreter/node_visitor.rb +3 -2
- data/lib/logicality/interpreter/simple_interpreter.rb +6 -6
- data/lib/logicality/lexer/grammar.rb +3 -0
- data/lib/logicality/lexer/lexer.rb +2 -0
- data/lib/logicality/lexer/regexp_lexer.rb +12 -12
- data/lib/logicality/lexer/token.rb +6 -4
- data/lib/logicality/logic.rb +5 -4
- data/lib/logicality/logicality.rb +2 -0
- data/lib/logicality/parser/ast/ast.rb +2 -0
- data/lib/logicality/parser/ast/binary_operator_node.rb +3 -2
- data/lib/logicality/parser/ast/node.rb +3 -2
- data/lib/logicality/parser/ast/unary_operator_node.rb +3 -2
- data/lib/logicality/parser/ast/value_operand_node.rb +3 -2
- data/lib/logicality/parser/parser.rb +2 -0
- data/lib/logicality/parser/simple_parser.rb +6 -7
- data/lib/logicality/version.rb +3 -1
- data/lib/logicality.rb +2 -0
- data/logicality.gemspec +10 -9
- data/spec/logic_spec.rb +28 -30
- metadata +18 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7edc9358a6d67553428d41c02f336e25dd7a9763
|
4
|
+
data.tar.gz: 1e66c111450fba24d0b0fb3d2e680c6d8ca63cdf
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 402fab8bc9d1889cf311f2d9455f558f7fe2a4b6e4d4b9735277f2fe228350cb4aee5a593f8445c18ca8ef4a6884ab4481c1237f690f7521cf097fb616ccc8b5
|
7
|
+
data.tar.gz: bd27b379426d0cda3db948eeb01e458a9867f9dade37c1e8c80941806f891ca935b8b3a3ca8fb0a6605e214bda995896f41491e2499ffa85418965ce6a00293a
|
data/.rubocop.yml
ADDED
data/.rubocop_todo.yml
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
# This configuration was generated by
|
2
|
+
# `rubocop --auto-gen-config`
|
3
|
+
# on 2018-09-28 09:05:21 -0500 using RuboCop version 0.59.2.
|
4
|
+
# The point is for the user to remove these configuration records
|
5
|
+
# one by one as the offenses are removed from the code base.
|
6
|
+
# Note that changes in the inspected code, or installation of new
|
7
|
+
# versions of RuboCop, may require this file to be generated again.
|
8
|
+
|
9
|
+
# Offense count: 4
|
10
|
+
Metrics/AbcSize:
|
11
|
+
Max: 23
|
12
|
+
|
13
|
+
# Offense count: 2
|
14
|
+
# Configuration parameters: CountComments, ExcludedMethods.
|
15
|
+
# ExcludedMethods: refine
|
16
|
+
Metrics/BlockLength:
|
17
|
+
Max: 51
|
18
|
+
|
19
|
+
# Offense count: 3
|
20
|
+
# Configuration parameters: CountComments, ExcludedMethods.
|
21
|
+
Metrics/MethodLength:
|
22
|
+
Max: 16
|
23
|
+
|
24
|
+
# Offense count: 3
|
25
|
+
Style/DoubleNegation:
|
26
|
+
Exclude:
|
27
|
+
- 'lib/logicality/interpreter/simple_interpreter.rb'
|
28
|
+
- 'lib/logicality/logic.rb'
|
29
|
+
|
30
|
+
# Offense count: 1
|
31
|
+
# Cop supports --auto-correct.
|
32
|
+
Style/OrAssignment:
|
33
|
+
Exclude:
|
34
|
+
- 'lib/logicality/logic.rb'
|
data/.travis.yml
CHANGED
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,12 +1,19 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
logicality (1.0.
|
4
|
+
logicality (1.0.5)
|
5
5
|
|
6
6
|
GEM
|
7
7
|
remote: https://rubygems.org/
|
8
8
|
specs:
|
9
|
+
ast (2.4.0)
|
9
10
|
diff-lcs (1.3)
|
11
|
+
jaro_winkler (1.5.1)
|
12
|
+
parallel (1.12.1)
|
13
|
+
parser (2.5.1.2)
|
14
|
+
ast (~> 2.4.0)
|
15
|
+
powerpack (0.1.2)
|
16
|
+
rainbow (3.0.0)
|
10
17
|
rspec (3.8.0)
|
11
18
|
rspec-core (~> 3.8.0)
|
12
19
|
rspec-expectations (~> 3.8.0)
|
@@ -20,6 +27,16 @@ GEM
|
|
20
27
|
diff-lcs (>= 1.2.0, < 2.0)
|
21
28
|
rspec-support (~> 3.8.0)
|
22
29
|
rspec-support (3.8.0)
|
30
|
+
rubocop (0.59.2)
|
31
|
+
jaro_winkler (~> 1.5.1)
|
32
|
+
parallel (~> 1.10)
|
33
|
+
parser (>= 2.5, != 2.5.1.1)
|
34
|
+
powerpack (~> 0.1)
|
35
|
+
rainbow (>= 2.2.2, < 4.0)
|
36
|
+
ruby-progressbar (~> 1.7)
|
37
|
+
unicode-display_width (~> 1.0, >= 1.0.1)
|
38
|
+
ruby-progressbar (1.10.0)
|
39
|
+
unicode-display_width (1.4.0)
|
23
40
|
|
24
41
|
PLATFORMS
|
25
42
|
ruby
|
@@ -27,6 +44,7 @@ PLATFORMS
|
|
27
44
|
DEPENDENCIES
|
28
45
|
logicality!
|
29
46
|
rspec
|
47
|
+
rubocop (~> 0.59.2)
|
30
48
|
|
31
49
|
BUNDLED WITH
|
32
50
|
1.16.3
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
#
|
2
4
|
# Copyright (c) 2018-present, Blue Marble Payroll, LLC
|
3
5
|
#
|
@@ -7,8 +9,8 @@
|
|
7
9
|
|
8
10
|
module Logicality
|
9
11
|
module Interpreter
|
12
|
+
# This is a base class for traversing a node.
|
10
13
|
class NodeVisitor
|
11
|
-
|
12
14
|
def visit(node)
|
13
15
|
return nil unless node
|
14
16
|
|
@@ -30,7 +32,6 @@ module Logicality
|
|
30
32
|
def method_name(node)
|
31
33
|
"visit_#{node.name}"
|
32
34
|
end
|
33
|
-
|
34
35
|
end
|
35
36
|
end
|
36
37
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
#
|
2
4
|
# Copyright (c) 2018-present, Blue Marble Payroll, LLC
|
3
5
|
#
|
@@ -7,12 +9,13 @@
|
|
7
9
|
|
8
10
|
module Logicality
|
9
11
|
module Interpreter
|
12
|
+
# This class implements NodeVisitor and gives each type of node the proper type of visitor
|
13
|
+
# implementation.
|
10
14
|
class SimpleInterpreter < NodeVisitor
|
11
|
-
|
12
15
|
attr_reader :resolver
|
13
16
|
|
14
17
|
def initialize(resolver)
|
15
|
-
raise ArgumentError,
|
18
|
+
raise ArgumentError, 'Resolver is required' unless resolver
|
16
19
|
|
17
20
|
@resolver = resolver
|
18
21
|
end
|
@@ -52,13 +55,10 @@ module Logicality
|
|
52
55
|
private
|
53
56
|
|
54
57
|
def resolve_value(value)
|
55
|
-
if resolver.nil?
|
56
|
-
raise ArgumentError, "No resolver function but trying to resolve: #{value}"
|
57
|
-
end
|
58
|
+
raise ArgumentError, "No resolver function: #{value}" if resolver.nil?
|
58
59
|
|
59
60
|
!!resolver.call(value)
|
60
61
|
end
|
61
|
-
|
62
62
|
end
|
63
63
|
end
|
64
64
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
#
|
2
4
|
# Copyright (c) 2018-present, Blue Marble Payroll, LLC
|
3
5
|
#
|
@@ -7,6 +9,7 @@
|
|
7
9
|
|
8
10
|
module Logicality
|
9
11
|
module Lexer
|
12
|
+
# Define the main regular expression matchers used by the lexer.
|
10
13
|
module Grammar
|
11
14
|
VALUE = /([a-zA-Z0-9_$@?\.]+)/
|
12
15
|
AND_OP = /(&&)/
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
#
|
2
4
|
# Copyright (c) 2018-present, Blue Marble Payroll, LLC
|
3
5
|
#
|
@@ -7,11 +9,11 @@
|
|
7
9
|
|
8
10
|
module Logicality
|
9
11
|
module Lexer
|
12
|
+
# This class is a simple lexical token analyzer based on regular expression grammer matchers.
|
10
13
|
class RegexpLexer
|
11
14
|
include Grammar
|
12
15
|
|
13
16
|
class << self
|
14
|
-
|
15
17
|
def invalid_pattern
|
16
18
|
"#{pattern}|(\\s*)"
|
17
19
|
end
|
@@ -21,24 +23,25 @@ module Logicality
|
|
21
23
|
end
|
22
24
|
|
23
25
|
def pattern
|
24
|
-
Grammar.constants
|
25
|
-
|
26
|
+
Grammar.constants
|
27
|
+
.map { |c| Grammar.const_get(c).source }
|
28
|
+
.join('|')
|
26
29
|
end
|
27
30
|
|
28
31
|
def regexp
|
29
32
|
Regexp.new(pattern)
|
30
33
|
end
|
31
|
-
|
32
34
|
end
|
33
35
|
|
34
36
|
attr_reader :expression
|
35
37
|
|
36
38
|
def initialize(expression)
|
37
|
-
raise ArgumentError, 'Expression is required' unless expression &&
|
39
|
+
raise ArgumentError, 'Expression is required' unless expression &&
|
40
|
+
expression.to_s.length.positive?
|
38
41
|
|
39
42
|
@expression = expression.to_s
|
40
43
|
|
41
|
-
if invalid_matches.length
|
44
|
+
if invalid_matches.length.positive?
|
42
45
|
raise ArgumentError, "Invalid syntax: #{invalid_matches}"
|
43
46
|
end
|
44
47
|
|
@@ -59,11 +62,9 @@ module Logicality
|
|
59
62
|
value ? Token.new(const, value) : nil
|
60
63
|
end.compact
|
61
64
|
|
62
|
-
if tokens.length > 1
|
63
|
-
|
64
|
-
|
65
|
-
raise ArgumentError, "Cannot tokenize: #{scan_array}"
|
66
|
-
end
|
65
|
+
raise ArgumentError, "Too many tokens found for: #{scan_array}" if tokens.length > 1
|
66
|
+
|
67
|
+
raise ArgumentError, "Cannot tokenize: #{scan_array}" if tokens.length.zero?
|
67
68
|
|
68
69
|
tokens.first
|
69
70
|
end
|
@@ -91,7 +92,6 @@ module Logicality
|
|
91
92
|
def matches
|
92
93
|
@matches ||= expression.scan(self.class.regexp)
|
93
94
|
end
|
94
|
-
|
95
95
|
end
|
96
96
|
end
|
97
97
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
#
|
2
4
|
# Copyright (c) 2018-present, Blue Marble Payroll, LLC
|
3
5
|
#
|
@@ -7,8 +9,9 @@
|
|
7
9
|
|
8
10
|
module Logicality
|
9
11
|
module Lexer
|
12
|
+
# Class that defines the main structure of a Token. A token is a parsed set of
|
13
|
+
# characters.
|
10
14
|
class Token
|
11
|
-
|
12
15
|
module Type
|
13
16
|
VALUE = :value
|
14
17
|
AND_OP = :and_op
|
@@ -21,8 +24,8 @@ module Logicality
|
|
21
24
|
attr_reader :type, :value
|
22
25
|
|
23
26
|
def initialize(type, value)
|
24
|
-
raise ArgumentError, 'type is required' unless type && type.to_s.length
|
25
|
-
raise ArgumentError, 'value is required' unless value && value.to_s.length
|
27
|
+
raise ArgumentError, 'type is required' unless type && type.to_s.length.positive?
|
28
|
+
raise ArgumentError, 'value is required' unless value && value.to_s.length.positive?
|
26
29
|
|
27
30
|
@type = Type.const_get(type.to_s.upcase.to_sym)
|
28
31
|
@value = value.to_s
|
@@ -31,7 +34,6 @@ module Logicality
|
|
31
34
|
def to_s
|
32
35
|
"#{type}::#{value}"
|
33
36
|
end
|
34
|
-
|
35
37
|
end
|
36
38
|
end
|
37
39
|
end
|
data/lib/logicality/logic.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
#
|
2
4
|
# Copyright (c) 2018-present, Blue Marble Payroll, LLC
|
3
5
|
#
|
@@ -6,9 +8,9 @@
|
|
6
8
|
#
|
7
9
|
|
8
10
|
module Logicality
|
11
|
+
# Class that defines the main class-level API for this library.
|
9
12
|
class Logic
|
10
13
|
class << self
|
11
|
-
|
12
14
|
def evaluate(expression, input = nil, resolver = nil)
|
13
15
|
node = get(expression)
|
14
16
|
wrapper = resolver_wrapper(input, resolver)
|
@@ -21,9 +23,9 @@ module Logicality
|
|
21
23
|
|
22
24
|
def resolver_wrapper(input, resolver)
|
23
25
|
if resolver
|
24
|
-
|
26
|
+
->(value) { resolver.call(value, input) }
|
25
27
|
else
|
26
|
-
|
28
|
+
->(value) { object_resolver.call(value, input) }
|
27
29
|
end
|
28
30
|
end
|
29
31
|
|
@@ -59,7 +61,6 @@ module Logicality
|
|
59
61
|
|
60
62
|
set(expression, parser.parse)
|
61
63
|
end
|
62
|
-
|
63
64
|
end
|
64
65
|
end
|
65
66
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
#
|
2
4
|
# Copyright (c) 2018-present, Blue Marble Payroll, LLC
|
3
5
|
#
|
@@ -8,8 +10,8 @@
|
|
8
10
|
module Logicality
|
9
11
|
module Parser
|
10
12
|
module Ast
|
13
|
+
# A binary operator contains two children (left and right) nodes.
|
11
14
|
class BinaryOperatorNode < Node
|
12
|
-
|
13
15
|
attr_reader :left, :right
|
14
16
|
|
15
17
|
def initialize(left, token, right)
|
@@ -19,7 +21,6 @@ module Logicality
|
|
19
21
|
@left = left
|
20
22
|
@right = right
|
21
23
|
end
|
22
|
-
|
23
24
|
end
|
24
25
|
end
|
25
26
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
#
|
2
4
|
# Copyright (c) 2018-present, Blue Marble Payroll, LLC
|
3
5
|
#
|
@@ -8,8 +10,8 @@
|
|
8
10
|
module Logicality
|
9
11
|
module Parser
|
10
12
|
module Ast
|
13
|
+
# Base construct defining all nodes.
|
11
14
|
class Node
|
12
|
-
|
13
15
|
attr_reader :token, :name
|
14
16
|
|
15
17
|
def initialize(token)
|
@@ -20,7 +22,6 @@ module Logicality
|
|
20
22
|
def to_s
|
21
23
|
"AstNode: #{self.class.name}::#{token}"
|
22
24
|
end
|
23
|
-
|
24
25
|
end
|
25
26
|
end
|
26
27
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
#
|
2
4
|
# Copyright (c) 2018-present, Blue Marble Payroll, LLC
|
3
5
|
#
|
@@ -8,8 +10,8 @@
|
|
8
10
|
module Logicality
|
9
11
|
module Parser
|
10
12
|
module Ast
|
13
|
+
# A unary operator node has just one child node.
|
11
14
|
class UnaryOperatorNode < Node
|
12
|
-
|
13
15
|
attr_reader :child
|
14
16
|
|
15
17
|
def initialize(child, token)
|
@@ -18,7 +20,6 @@ module Logicality
|
|
18
20
|
@name = 'unary_operator_node'
|
19
21
|
@child = child
|
20
22
|
end
|
21
|
-
|
22
23
|
end
|
23
24
|
end
|
24
25
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
#
|
2
4
|
# Copyright (c) 2018-present, Blue Marble Payroll, LLC
|
3
5
|
#
|
@@ -8,8 +10,8 @@
|
|
8
10
|
module Logicality
|
9
11
|
module Parser
|
10
12
|
module Ast
|
13
|
+
# A value operand node is a node with no children but holds a value instead.
|
11
14
|
class ValueOperandNode < Node
|
12
|
-
|
13
15
|
attr_reader :value
|
14
16
|
|
15
17
|
def initialize(token)
|
@@ -18,7 +20,6 @@ module Logicality
|
|
18
20
|
@name = 'value_operand_node'
|
19
21
|
@value = token.value
|
20
22
|
end
|
21
|
-
|
22
23
|
end
|
23
24
|
end
|
24
25
|
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
#
|
2
4
|
# Copyright (c) 2018-present, Blue Marble Payroll, LLC
|
3
5
|
#
|
@@ -7,8 +9,9 @@
|
|
7
9
|
|
8
10
|
module Logicality
|
9
11
|
module Parser
|
12
|
+
# Parser that takes in a lexer and can take its parsed grammar and turn it into an
|
13
|
+
# abstract syntax tree.
|
10
14
|
class SimpleParser
|
11
|
-
|
12
15
|
attr_reader :lexer
|
13
16
|
|
14
17
|
def initialize(lexer)
|
@@ -16,10 +19,7 @@ module Logicality
|
|
16
19
|
|
17
20
|
@current_token = lexer.next_token
|
18
21
|
|
19
|
-
if @current_token.nil?
|
20
|
-
raise ArgumentError, 'Lexer must contain at least one token'
|
21
|
-
end
|
22
|
-
|
22
|
+
raise ArgumentError, 'Lexer must contain at least one token' if @current_token.nil?
|
23
23
|
end
|
24
24
|
|
25
25
|
def parse
|
@@ -30,7 +30,7 @@ module Logicality
|
|
30
30
|
|
31
31
|
BINARY_TYPES = [
|
32
32
|
Lexer::Token::Type::AND_OP,
|
33
|
-
Lexer::Token::Type::OR_OP
|
33
|
+
Lexer::Token::Type::OR_OP
|
34
34
|
].freeze
|
35
35
|
|
36
36
|
attr_reader :current_token
|
@@ -91,7 +91,6 @@ module Logicality
|
|
91
91
|
|
92
92
|
node
|
93
93
|
end
|
94
|
-
|
95
94
|
end
|
96
95
|
end
|
97
96
|
end
|
data/lib/logicality/version.rb
CHANGED
data/lib/logicality.rb
CHANGED
data/logicality.gemspec
CHANGED
@@ -1,28 +1,29 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
3
|
+
require './lib/logicality/version'
|
4
4
|
|
5
|
+
Gem::Specification.new do |s|
|
5
6
|
s.name = 'logicality'
|
6
7
|
s.version = Logicality::VERSION
|
7
|
-
s.summary =
|
8
|
+
s.summary = 'String-based boolean expression evaluator'
|
8
9
|
|
9
|
-
s.description = <<-
|
10
|
+
s.description = <<-DESCRIPTION
|
10
11
|
A common problem that many frameworks have is the ability to give developers
|
11
12
|
an expressive intermediary scripting language or DSL.
|
12
13
|
Logicality helps solve this problem by providing a simple boolean
|
13
14
|
expression evaluator.
|
14
|
-
|
15
|
+
DESCRIPTION
|
15
16
|
|
16
|
-
s.authors = [
|
17
|
-
s.email = [
|
17
|
+
s.authors = ['Matthew Ruggio']
|
18
|
+
s.email = ['mruggio@bluemarblepayroll.com']
|
18
19
|
s.files = `git ls-files`.split("\n")
|
19
20
|
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
20
|
-
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
21
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map { |f| File.basename(f) }
|
21
22
|
s.homepage = 'https://github.com/bluemarblepayroll/logicality-rb'
|
22
23
|
s.license = 'MIT'
|
23
24
|
|
24
25
|
s.required_ruby_version = '>= 2.3.1'
|
25
26
|
|
26
27
|
s.add_development_dependency('rspec')
|
27
|
-
|
28
|
+
s.add_development_dependency('rubocop', '~> 0.59.2')
|
28
29
|
end
|
data/spec/logic_spec.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
#
|
2
4
|
# Copyright (c) 2018-present, Blue Marble Payroll, LLC
|
3
5
|
#
|
@@ -9,26 +11,24 @@ require './lib/logicality'
|
|
9
11
|
|
10
12
|
def run(tests)
|
11
13
|
tests.each do |x|
|
12
|
-
input = x[1] ? x[1].map { |k,v| [
|
14
|
+
input = x[1] ? x[1].map { |k, v| [k.to_s, v] }.to_h : nil
|
13
15
|
|
14
16
|
result = Logicality::Logic.evaluate(x[0], input)
|
15
17
|
|
16
|
-
expect(result).to eq(x[2]), "Failed
|
18
|
+
expect(result).to eq(x[2]), "Failed: #{x[0]} (input: #{input}): expected #{x[2]} got: #{result}"
|
17
19
|
end
|
18
20
|
|
19
21
|
nil
|
20
22
|
end
|
21
23
|
|
22
24
|
describe Logicality::Logic do
|
23
|
-
|
24
25
|
context 'when evaluating' do
|
25
|
-
|
26
26
|
it 'should evaluate boolean-only expressions' do
|
27
27
|
tests = [
|
28
|
-
[
|
29
|
-
[
|
30
|
-
[
|
31
|
-
[
|
28
|
+
['true', nil, true],
|
29
|
+
['false', nil, false],
|
30
|
+
['true && false', nil, false],
|
31
|
+
['true && true', nil, true]
|
32
32
|
]
|
33
33
|
|
34
34
|
run(tests)
|
@@ -36,12 +36,12 @@ describe Logicality::Logic do
|
|
36
36
|
|
37
37
|
it 'should evaluate and expressions' do
|
38
38
|
tests = [
|
39
|
-
[
|
40
|
-
[
|
41
|
-
[
|
42
|
-
[
|
43
|
-
[
|
44
|
-
[
|
39
|
+
['a && b', nil, false],
|
40
|
+
['a && b', {}, false],
|
41
|
+
['a && b', { a: true }, false],
|
42
|
+
['a && b', { a: true, b: false }, false],
|
43
|
+
['a && b', { a: false, b: false }, false],
|
44
|
+
['a && b', { a: true, b: true }, true]
|
45
45
|
]
|
46
46
|
|
47
47
|
run(tests)
|
@@ -49,11 +49,11 @@ describe Logicality::Logic do
|
|
49
49
|
|
50
50
|
it 'should evaluate and-or expressions' do
|
51
51
|
tests = [
|
52
|
-
[
|
53
|
-
[
|
54
|
-
[
|
55
|
-
[
|
56
|
-
[
|
52
|
+
['a && b || c', { a: false, b: false, c: true }, true],
|
53
|
+
['(a && b) || c', { a: false, b: false, c: true }, true],
|
54
|
+
['a || b && c', { a: false, b: false, c: true }, false],
|
55
|
+
['a || (b && c)', { a: false, b: false, c: true }, false],
|
56
|
+
['(a || b) && c', { a: false, b: false, c: true }, false]
|
57
57
|
]
|
58
58
|
|
59
59
|
run(tests)
|
@@ -61,11 +61,11 @@ describe Logicality::Logic do
|
|
61
61
|
|
62
62
|
it 'should evaluate not expressions' do
|
63
63
|
tests = [
|
64
|
-
[
|
65
|
-
[
|
66
|
-
[
|
67
|
-
[
|
68
|
-
[
|
64
|
+
['!a', { a: false }, true],
|
65
|
+
['!a && !b', { a: false, b: false }, true],
|
66
|
+
['!a && b', { a: false, b: false }, false],
|
67
|
+
['a && !b', { a: false, b: false }, false],
|
68
|
+
['!(a && b)', { a: false, b: false }, true]
|
69
69
|
]
|
70
70
|
|
71
71
|
run(tests)
|
@@ -73,15 +73,13 @@ describe Logicality::Logic do
|
|
73
73
|
|
74
74
|
it 'should treat question marks as a valid part of a value token' do
|
75
75
|
tests = [
|
76
|
-
[
|
77
|
-
[
|
78
|
-
[
|
79
|
-
[
|
76
|
+
['a?', { 'a?': true }, true],
|
77
|
+
['!a?', { 'a?': true }, false],
|
78
|
+
['a? && b?', { 'a?': true, 'b?': true }, true],
|
79
|
+
['a && b?', { a: true, 'b?': true }, true]
|
80
80
|
]
|
81
81
|
|
82
82
|
run(tests)
|
83
83
|
end
|
84
|
-
|
85
84
|
end
|
86
|
-
|
87
85
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: logicality
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.5
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Matthew Ruggio
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-09-
|
11
|
+
date: 2018-09-28 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rspec
|
@@ -24,6 +24,20 @@ dependencies:
|
|
24
24
|
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rubocop
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 0.59.2
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 0.59.2
|
27
41
|
description: |2
|
28
42
|
A common problem that many frameworks have is the ability to give developers
|
29
43
|
an expressive intermediary scripting language or DSL.
|
@@ -37,6 +51,8 @@ extra_rdoc_files: []
|
|
37
51
|
files:
|
38
52
|
- ".editorconfig"
|
39
53
|
- ".gitignore"
|
54
|
+
- ".rubocop.yml"
|
55
|
+
- ".rubocop_todo.yml"
|
40
56
|
- ".ruby-version"
|
41
57
|
- ".travis.yml"
|
42
58
|
- Gemfile
|