rast 0.18.0 → 0.19.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 +4 -4
- data/.travis.yml +15 -0
- data/CHANGELOG.md +14 -0
- data/Documentation.md +297 -0
- data/Gemfile +0 -2
- data/Getting-Started-Detailed.md +122 -0
- data/Getting-Started.md +19 -102
- data/README.md +80 -16
- data/examples/enum_module.rb +20 -6
- data/examples/factory_example.rb +4 -4
- data/examples/hotel_finder.rb +14 -0
- data/examples/person.rb +6 -0
- data/examples/prime_number.rb +13 -8
- data/lib/rast/parameter_generator.rb +107 -53
- data/lib/rast/rast_spec.rb +8 -2
- data/lib/rast/rules/logic_helper.rb +76 -95
- data/lib/rast/rules/rule_evaluator.rb +100 -98
- data/lib/rast/rules/rule_validator.rb +14 -7
- data/lib/rast/rules/token_util.rb +17 -0
- data/lib/rast/spec_dsl.rb +57 -35
- data/lib/rast.rb +5 -1
- data/lib/template_spec.yml +5 -7
- data/rast.gemspec +1 -1
- metadata +8 -9
- data/examples/arithmetic_module.rb +0 -8
- data/examples/double_example.rb +0 -14
- data/examples/logic_four.rb +0 -15
- data/examples/lohika.rb +0 -27
- data/examples/phone.rb +0 -6
- data/examples/quiz_module.rb +0 -34
- data/examples/triple.rb +0 -15
data/lib/rast/spec_dsl.rb
CHANGED
@@ -7,11 +7,12 @@ require 'rast/parameter_generator'
|
|
7
7
|
class SpecDSL
|
8
8
|
include FactoryGirl::Syntax::Methods
|
9
9
|
|
10
|
-
attr_accessor :subject, :
|
11
|
-
:prepare_block, :
|
10
|
+
attr_accessor :subject, :execute_block,
|
11
|
+
:prepare_block, :outcomes, :fixtures, :spec_id
|
12
12
|
|
13
13
|
# # yaml-less
|
14
|
-
attr_writer :variables, :exclude, :include, :converters, :rules, :pair,
|
14
|
+
attr_writer :variables, :exclude, :include, :converters, :rules, :pair,
|
15
|
+
:default_outcome
|
15
16
|
|
16
17
|
# @subject the sut instance
|
17
18
|
# @name the sut name to be displayed with -fd
|
@@ -23,9 +24,6 @@ class SpecDSL
|
|
23
24
|
@subject_name = name || subject.class
|
24
25
|
@fixtures = fixtures
|
25
26
|
|
26
|
-
@transients = []
|
27
|
-
@rspec_methods = []
|
28
|
-
|
29
27
|
instance_eval(&block)
|
30
28
|
end
|
31
29
|
|
@@ -34,10 +32,14 @@ class SpecDSL
|
|
34
32
|
@variables = vars
|
35
33
|
end
|
36
34
|
|
37
|
-
def
|
35
|
+
def exclusion(clause)
|
38
36
|
@exclude = clause
|
39
37
|
end
|
40
38
|
|
39
|
+
def inclusion(clause)
|
40
|
+
@include = clause
|
41
|
+
end
|
42
|
+
|
41
43
|
def rules(rules)
|
42
44
|
@rules = {}
|
43
45
|
|
@@ -52,11 +54,14 @@ class SpecDSL
|
|
52
54
|
rules(outcomes)
|
53
55
|
end
|
54
56
|
|
57
|
+
def default(default)
|
58
|
+
@default_outcome = default
|
59
|
+
end
|
60
|
+
|
55
61
|
# yaml-less end
|
56
62
|
|
57
63
|
def prepare(&block)
|
58
64
|
@prepare_block = block
|
59
|
-
@transients
|
60
65
|
end
|
61
66
|
|
62
67
|
def execute(&block)
|
@@ -69,24 +74,23 @@ class SpecDSL
|
|
69
74
|
'pair' => @pair,
|
70
75
|
'converters' => @converters,
|
71
76
|
'rules' => @rules,
|
72
|
-
'exclude' => @exclude
|
77
|
+
'exclude' => @exclude,
|
78
|
+
'include' => @include,
|
79
|
+
'default' => @default_outcome
|
73
80
|
} }
|
74
81
|
|
75
82
|
@fixtures = parameter_generator.generate_fixtures(spec_id: @spec_id)
|
76
83
|
end
|
77
84
|
|
78
85
|
@fixtures.sort_by! do |fixture|
|
79
|
-
|
80
|
-
|
81
|
-
|
86
|
+
if fixture[:expected].nil?
|
87
|
+
raise "Expected outcome not found for #{fixture[:scenario]}, check" \
|
88
|
+
' your single rule/else/default configuration'
|
82
89
|
end
|
83
90
|
|
84
|
-
fixture[:
|
85
|
-
# fixture[:scenario].to_s + fixture[:expected_outcome]
|
91
|
+
fixture[:expected] + fixture[:scenario].to_s
|
86
92
|
end
|
87
93
|
|
88
|
-
# @fixtures.reverse!
|
89
|
-
|
90
94
|
generate_rspecs
|
91
95
|
end
|
92
96
|
|
@@ -95,35 +99,39 @@ class SpecDSL
|
|
95
99
|
def generate_rspecs
|
96
100
|
main_scope = self
|
97
101
|
|
98
|
-
|
99
|
-
|
100
|
-
exclusion = fixtures.first[:spec].exclude_clause
|
101
|
-
exclusion = exclusion.join if exclusion.is_a? Array
|
102
|
-
title += ", EXCLUDE: '#{exclusion}'" if exclusion
|
103
|
-
inclusion = fixtures.first[:spec].include_clause
|
104
|
-
inclusion = inclusion.join if inclusion.is_a? Array
|
105
|
-
title += ", ONLY: '#{inclusion}'" if inclusion
|
106
|
-
|
107
|
-
RSpec.describe title do
|
102
|
+
RSpec.describe build_title do
|
108
103
|
main_scope.fixtures.each do |fixture|
|
109
104
|
generate_rspec(
|
110
105
|
scope: main_scope,
|
111
106
|
scenario: fixture[:scenario],
|
112
|
-
expected: fixture[:
|
107
|
+
expected: fixture[:expected]
|
113
108
|
)
|
114
109
|
end
|
115
110
|
end
|
116
111
|
end
|
117
112
|
end
|
118
113
|
|
119
|
-
def
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
114
|
+
def build_title
|
115
|
+
title = "#{@subject_name}: #{@fixtures.first[:spec].description}"
|
116
|
+
title += append_exclusion_title
|
117
|
+
title += append_inclusion_title
|
118
|
+
title
|
119
|
+
end
|
125
120
|
|
126
|
-
|
121
|
+
def append_exclusion_title
|
122
|
+
exclusion = @fixtures.first[:spec].exclude_clause
|
123
|
+
exclusion = exclusion.join if exclusion.is_a? Array
|
124
|
+
exclusion ? ", EXCLUDE: '#{exclusion}'" : ''
|
125
|
+
end
|
126
|
+
|
127
|
+
def append_inclusion_title
|
128
|
+
inclusion = @fixtures.first[:spec].include_clause
|
129
|
+
inclusion = inclusion.join if inclusion.is_a? Array
|
130
|
+
inclusion ? ", ONLY: '#{inclusion}'" : ''
|
131
|
+
end
|
132
|
+
|
133
|
+
def generate_rspec(scope: nil, scenario: {}, expected: '')
|
134
|
+
it _it_title(expected, scenario) do
|
127
135
|
block_params = scenario.values
|
128
136
|
|
129
137
|
@mysubject = scope.subject
|
@@ -132,7 +140,7 @@ def generate_rspec(scope: nil, scenario: {}, expected: '')
|
|
132
140
|
define_method(:subject) { @mysubject }
|
133
141
|
end
|
134
142
|
|
135
|
-
|
143
|
+
unless scope.prepare_block.nil?
|
136
144
|
instance_exec(*block_params, &scope.prepare_block)
|
137
145
|
end
|
138
146
|
|
@@ -142,6 +150,20 @@ def generate_rspec(scope: nil, scenario: {}, expected: '')
|
|
142
150
|
end
|
143
151
|
end
|
144
152
|
|
153
|
+
def _it_title(expected, scenario)
|
154
|
+
spec_params = scenario.keys.inject('') do |output, key|
|
155
|
+
build_it(scenario, output, key)
|
156
|
+
end
|
157
|
+
|
158
|
+
"[#{expected}]=[#{spec_params}]"
|
159
|
+
end
|
160
|
+
|
161
|
+
def build_it(scenario, output, key)
|
162
|
+
output += ', ' unless output == ''
|
163
|
+
calc_key = scenario[key].nil? ? nil : scenario[key]
|
164
|
+
output + "#{key}: #{calc_key}"
|
165
|
+
end
|
166
|
+
|
145
167
|
# DSL Entry Point
|
146
168
|
def spec(subject: nil, name: '', fixtures: [], spec_id: '', &block)
|
147
169
|
SpecDSL.new(
|
data/lib/rast.rb
CHANGED
@@ -34,7 +34,7 @@ class Rast
|
|
34
34
|
raise message unless yield
|
35
35
|
end
|
36
36
|
|
37
|
-
def xspec(id
|
37
|
+
def xspec(id)
|
38
38
|
p "xspec skipped #{id}"
|
39
39
|
end
|
40
40
|
|
@@ -53,3 +53,7 @@ end
|
|
53
53
|
def rast(rasted_subject, &block)
|
54
54
|
Rast.new(rasted_subject, &block)
|
55
55
|
end
|
56
|
+
|
57
|
+
def xrast(rasted_subject)
|
58
|
+
p "xrast skipped #{rasted_subject}"
|
59
|
+
end
|
data/lib/template_spec.yml
CHANGED
@@ -1,16 +1,14 @@
|
|
1
1
|
---
|
2
2
|
specs:
|
3
|
+
# spec key uniquely identifies a spec. It has to match the ID when the spec
|
4
|
+
# block is invoked in the ruby spec file. Usually the method name.
|
3
5
|
spec_key:
|
4
6
|
description: Spec Description
|
5
7
|
|
6
8
|
variables:
|
7
|
-
param1:
|
8
|
-
- one
|
9
|
-
- two
|
9
|
+
param1: [one, two]
|
10
10
|
|
11
11
|
outcomes: # required (dictionary)
|
12
|
-
true:
|
12
|
+
true: one[0] # sample outcome.
|
13
13
|
|
14
|
-
|
15
|
-
|
16
|
-
default: DEFAULT # optional (scalar) fall off value, or the else result of the `pair` config.
|
14
|
+
default: DEFAULT # optional (scalar) fall off value.
|
data/rast.gemspec
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rast
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.19.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Royce Remulla
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-05-
|
11
|
+
date: 2020-05-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: factory_girl
|
@@ -35,26 +35,24 @@ files:
|
|
35
35
|
- ".gitignore"
|
36
36
|
- ".rspec"
|
37
37
|
- ".rubocop.yml"
|
38
|
+
- ".travis.yml"
|
38
39
|
- CHANGELOG.md
|
40
|
+
- Documentation.md
|
39
41
|
- Gemfile
|
40
42
|
- Gemfile.lock
|
43
|
+
- Getting-Started-Detailed.md
|
41
44
|
- Getting-Started.md
|
42
45
|
- README.md
|
43
|
-
- examples/arithmetic_module.rb
|
44
|
-
- examples/double_example.rb
|
45
46
|
- examples/enum_module.rb
|
46
47
|
- examples/factory_example.rb
|
48
|
+
- examples/hotel_finder.rb
|
47
49
|
- examples/logic_checker.rb
|
48
|
-
- examples/
|
49
|
-
- examples/lohika.rb
|
50
|
-
- examples/phone.rb
|
50
|
+
- examples/person.rb
|
51
51
|
- examples/positive.rb
|
52
52
|
- examples/positive2.rb
|
53
53
|
- examples/prime_number.rb
|
54
|
-
- examples/quiz_module.rb
|
55
54
|
- examples/quoted.rb
|
56
55
|
- examples/recruiter.rb
|
57
|
-
- examples/triple.rb
|
58
56
|
- examples/worker.rb
|
59
57
|
- lib/rast.rb
|
60
58
|
- lib/rast/converters/bool_converter.rb
|
@@ -70,6 +68,7 @@ files:
|
|
70
68
|
- lib/rast/rules/rule_evaluator.rb
|
71
69
|
- lib/rast/rules/rule_processor.rb
|
72
70
|
- lib/rast/rules/rule_validator.rb
|
71
|
+
- lib/rast/rules/token_util.rb
|
73
72
|
- lib/rast/spec_dsl.rb
|
74
73
|
- lib/template_spec.yml
|
75
74
|
- rast.gemspec
|
data/examples/double_example.rb
DELETED
data/examples/logic_four.rb
DELETED
@@ -1,15 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
# Checks bug introduced when converters are combined with token converter.
|
4
|
-
#
|
5
|
-
# @author Royce Remulla
|
6
|
-
#
|
7
|
-
class LogicFour
|
8
|
-
# Perform logical AND operation on two arguments.
|
9
|
-
#
|
10
|
-
# @param argument1 first argument of Boolean type.
|
11
|
-
# @param argument2 second argument of Boolean type.
|
12
|
-
def process(argument1, argument2, argument3, argument4)
|
13
|
-
!argument1 && !argument2 && !argument3 && argument4 == 'a'
|
14
|
-
end
|
15
|
-
end
|
data/examples/lohika.rb
DELETED
@@ -1,27 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
# LogicChecker ported from Java
|
4
|
-
#
|
5
|
-
# @author Royce Remulla
|
6
|
-
#
|
7
|
-
class Lohika
|
8
|
-
# Perform logical AND operation on two arguments.
|
9
|
-
#
|
10
|
-
# @param argument1 first argument of Boolean type.
|
11
|
-
# @param argument2 second argument of Boolean type.
|
12
|
-
def at(argument1, argument2)
|
13
|
-
return :oo if argument1 == 'oo' && argument2 == 'oo'
|
14
|
-
|
15
|
-
:hindi
|
16
|
-
end
|
17
|
-
|
18
|
-
# Perform logical OR operation on two arguments.
|
19
|
-
#
|
20
|
-
# @param argument1 first argument of Boolean type.
|
21
|
-
# @param argument2 second argument of Boolean type.
|
22
|
-
def o(argument1, argument2)
|
23
|
-
return :oo if argument1 == 'oo' || argument2 == 'oo'
|
24
|
-
|
25
|
-
:hindi
|
26
|
-
end
|
27
|
-
end
|
data/examples/phone.rb
DELETED
data/examples/quiz_module.rb
DELETED
@@ -1,34 +0,0 @@
|
|
1
|
-
# Used to determine if cards form quiz type
|
2
|
-
# S postfix means Single option, M postfix means Multiple options
|
3
|
-
module QuizModule
|
4
|
-
RE_SELECTED = /(?<=\([*x]\)\s).*/.freeze
|
5
|
-
RE_CHECKED = /(?<=\[[*x]\]\s).*/.freeze
|
6
|
-
RE_WRONG_OPT_S = /(?<=\(\)\s).*/.freeze
|
7
|
-
RE_WRONG_OPT_M = /(?<=\[\]\s).*/.freeze
|
8
|
-
|
9
|
-
RE_QUIZ_OPTION_S = Regexp.new(
|
10
|
-
"#{RE_WRONG_OPT_S}|#{RE_SELECTED}",
|
11
|
-
Regexp::IGNORECASE
|
12
|
-
)
|
13
|
-
|
14
|
-
RE_QUIZ_OPTION_M = Regexp.new(
|
15
|
-
"#{RE_WRONG_OPT_M}|#{RE_CHECKED}",
|
16
|
-
Regexp::IGNORECASE
|
17
|
-
)
|
18
|
-
|
19
|
-
def quiz_multi_choice?(back)
|
20
|
-
if back.is_a?(Array) && back.any?
|
21
|
-
back.each { |element| return false unless element[RE_QUIZ_OPTION_M] }
|
22
|
-
|
23
|
-
# Find at least 1 checked answer
|
24
|
-
return false unless back.find do |element|
|
25
|
-
true if element[RE_CHECKED]
|
26
|
-
end
|
27
|
-
|
28
|
-
@quiz = true
|
29
|
-
@front_only = true
|
30
|
-
return true
|
31
|
-
end
|
32
|
-
false
|
33
|
-
end
|
34
|
-
end
|
data/examples/triple.rb
DELETED
@@ -1,15 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
# Triple. This example is used to test automatic detection of variable data type in yaml.
|
4
|
-
#
|
5
|
-
# @author Royce Remulla
|
6
|
-
#
|
7
|
-
class Triple
|
8
|
-
# Perform logical AND operation on two arguments.
|
9
|
-
#
|
10
|
-
# @param argument1 first argument of Boolean type.
|
11
|
-
# @param argument2 second argument of Boolean type.
|
12
|
-
def triple(argument1, argument2, _argument3)
|
13
|
-
argument1 && argument2
|
14
|
-
end
|
15
|
-
end
|