logicality 1.0.4 → 1.0.5
Sign up to get free protection for your applications and to get access to all the features.
- 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
|