rast 0.19.1 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5bab01b930678511296037271c46292a6e20b25feaed071a4a534ef245fc08a1
4
- data.tar.gz: db9953c5986a4e992cbab5760a2390262bfbd587aaec3cd6e7affaff237525e2
3
+ metadata.gz: db0077928a7df4dcd98e98737660be491b8eb5aaad2ed6f9e3015ed26d2b703e
4
+ data.tar.gz: 75c49f92fed7ac16e1490a531c3bf87fec92e6c26e20f466c92cde3c2f0c3d66
5
5
  SHA512:
6
- metadata.gz: 1150f55a0bf914f74d66f48c2fc97398e5baf67855b44da1ed71b20bf86eb72c7f2f2a8fad7b654cfa6375ed925f98236f2ac9d16bdcd17d9ec9fc1da9c324b4
7
- data.tar.gz: 4b560dd86ce4227ff43fa0a7cb035443a8ea793893c979b8dd5e67d4b50954bc714e96e3c17c8530d900ddf6593b05956d4dd7f9b812dc252b488d69b14d8bd7
6
+ metadata.gz: 74101d1f6227851cab7d263e6750df4aae5a9f70dbf868c9a3925646f1781406edca38f35b214ad54e4917035ba6d779bd80a18f30fd8c2ffee903b02a4c4889
7
+ data.tar.gz: 1a41f4db833451dffe2ff219d2acd009426f1ebe6685db335ff44371a22acbb6c6bd76c53edefe19e52a1f884bb19a0587b9041d38539f9431b8b88bb0530fc2
data/.rubocop.yml CHANGED
@@ -1,3 +1,3 @@
1
1
  ---
2
2
  AllCops:
3
- TargetRubyVersion: 2.6
3
+ TargetRubyVersion: 3.2
data/.ruby-version ADDED
@@ -0,0 +1 @@
1
+ 3.2
data/CHANGELOG.md CHANGED
@@ -1,12 +1,17 @@
1
- # Change log
1
+ # Change logs
2
2
 
3
3
  ## Unreleased
4
4
 
5
5
 
6
6
  ## Released
7
7
 
8
- - 0.19.1 - [bug] nil as configured outcome
9
- - [bug] nil showing in the report as empty string.
8
+ - 1.00.0
9
+ - [maint] Updated for Ruby 3.0, updated Gemfiles.
10
+
11
+ - 0.19.1
12
+
13
+ - [bug] nil as configured outcome
14
+ - [bug] nil showing in the report as empty string.
10
15
 
11
16
  - 0.19.0 - [feature] boolean in variables definition to automatically infer
12
17
  false and true
@@ -56,4 +61,4 @@ the prepare block now runs under the context of RSpec.
56
61
  - 0.3.0.pre - Support factory methods in execute block.
57
62
  - 0.2.0.pre - Support module subjects.
58
63
  - 0.1.2.pre - Fixed exclusions.
59
- - 0.1.1.pre - Pre release version compatible with Ruby 2.0.0-p247
64
+ - 0.1.1.pre - Pre release version compatible with Ruby 2.0.0-p247
data/Documentation.md CHANGED
@@ -5,6 +5,7 @@
5
5
  YAML is the preferred because it simplifies the content of the spec file. YAML contains the variables that affect the outcome, and the expected outcome based on rules that involve the said variables.
6
6
 
7
7
  ```yaml
8
+ ---
8
9
  specs:
9
10
  # spec key uniquely identifies a spec. It has to match the ID when the spec
10
11
  # block is invoked in the ruby spec file. Usually the method name.
@@ -28,6 +29,7 @@ In the example below, the left variable has the subscript of `0`, and the right
28
29
  [logic_checker_spec.yml](./spec/examples/rast/logic_checker_spec.yml)
29
30
 
30
31
  ```yaml
32
+ ---
31
33
  specs:
32
34
  Logical AND:
33
35
  variables:
@@ -75,8 +77,8 @@ Finished in 0.00292 seconds (files took 0.26024 seconds to load)
75
77
  ### Filtering Out Invalid Cases
76
78
 
77
79
  In a prior example `HotelFinder`, some cases are invalid. For example, if an
78
- aircon is not available, then it makes to sense to check if it is operational
79
- not. In such case, we should limit the scenarios with `exclude` clause.
80
+ aircon is not available, then it makes no sense to check if it is operational
81
+ not. In such case, we can limit the scenarios with `exclude` clause.
80
82
 
81
83
  ```yaml
82
84
  # double_example_spec.yml
@@ -191,12 +193,12 @@ specs:
191
193
  - "Will this work?"
192
194
  - "Let's make a statement"
193
195
  ...
194
-
195
196
  ```
196
197
 
197
198
  The rules must then be written in a different way, as arrays.
198
199
 
199
200
  ```yaml
201
+ ---
200
202
  ...
201
203
  outcomes:
202
204
  exclamation: ["Let's do it!"]
@@ -207,6 +209,7 @@ The rules must then be written in a different way, as arrays.
207
209
  If an operation is involved:
208
210
 
209
211
  ```yaml
212
+ ---
210
213
  outcomes:
211
214
  non-question: ["Let's do it!", '|', "Let's make a statement"]
212
215
  ```
@@ -257,7 +260,7 @@ Suppose we have a HotelFinder class that has a dependency to air conditioning
257
260
  and security
258
261
 
259
262
  ```ruby
260
- rast HotelFinder do
263
+ rast DiplomatHotelFinder do
261
264
  spec '#applicable?' do
262
265
  prepare do |with_ac, is_opererational, with_security, security_grade|
263
266
  if with_ac
@@ -277,7 +280,7 @@ Suppose we have a HotelFinder class that has a dependency to air conditioning
277
280
 
278
281
  ```
279
282
 
280
- ### Spec file without yaml
283
+ ### Spec file without YAML
281
284
 
282
285
  If a single spec is preferred, like in cases where it's much simplier,
283
286
  the required configuration can be written with similar name except for the
data/Gemfile CHANGED
@@ -5,7 +5,7 @@ source 'https://rubygems.org'
5
5
  git_source(:github) { |repo_name| "https://github.com/#{repo_name}" }
6
6
 
7
7
  group :development, :test do
8
- gem 'factory_girl', '~> 4.7'
8
+ gem 'factory_bot'
9
9
  end
10
10
 
11
11
  group :test do
@@ -14,5 +14,5 @@ group :test do
14
14
  gem 'rb-inotify', '~> 0.9.10'
15
15
 
16
16
  gem 'rspec'
17
- gem 'simplecov', '~> 0.8.2'
17
+ gem 'simplecov'
18
18
  end
data/Gemfile.lock CHANGED
@@ -1,60 +1,59 @@
1
1
  GEM
2
2
  remote: https://rubygems.org/
3
3
  specs:
4
- activesupport (4.2.11.1)
5
- i18n (~> 0.7)
6
- minitest (~> 5.1)
7
- thread_safe (~> 0.3, >= 0.3.4)
8
- tzinfo (~> 1.1)
9
- concurrent-ruby (1.1.6)
10
- diff-lcs (1.3)
11
- docile (1.1.5)
12
- factory_girl (4.9.0)
13
- activesupport (>= 3.0.0)
14
- ffi (1.12.2)
15
- i18n (0.9.5)
4
+ activesupport (7.0.7)
5
+ concurrent-ruby (~> 1.0, >= 1.0.2)
6
+ i18n (>= 1.6, < 2)
7
+ minitest (>= 5.1)
8
+ tzinfo (~> 2.0)
9
+ concurrent-ruby (1.2.2)
10
+ diff-lcs (1.5.0)
11
+ docile (1.4.0)
12
+ factory_bot (6.2.1)
13
+ activesupport (>= 5.0.0)
14
+ ffi (1.15.5)
15
+ i18n (1.14.1)
16
16
  concurrent-ruby (~> 1.0)
17
- listen (3.0.8)
18
- rb-fsevent (~> 0.9, >= 0.9.4)
19
- rb-inotify (~> 0.9, >= 0.9.7)
20
- lumberjack (1.0.13)
21
- minitest (5.12.0)
22
- multi_json (1.14.1)
23
- rb-fsevent (0.10.3)
17
+ listen (3.8.0)
18
+ rb-fsevent (~> 0.10, >= 0.10.3)
19
+ rb-inotify (~> 0.9, >= 0.9.10)
20
+ lumberjack (1.2.9)
21
+ minitest (5.19.0)
22
+ rb-fsevent (0.11.2)
24
23
  rb-inotify (0.9.10)
25
24
  ffi (>= 0.5.0, < 2)
26
- rspec (3.9.0)
27
- rspec-core (~> 3.9.0)
28
- rspec-expectations (~> 3.9.0)
29
- rspec-mocks (~> 3.9.0)
30
- rspec-core (3.9.1)
31
- rspec-support (~> 3.9.1)
32
- rspec-expectations (3.9.1)
25
+ rspec (3.12.0)
26
+ rspec-core (~> 3.12.0)
27
+ rspec-expectations (~> 3.12.0)
28
+ rspec-mocks (~> 3.12.0)
29
+ rspec-core (3.12.2)
30
+ rspec-support (~> 3.12.0)
31
+ rspec-expectations (3.12.3)
33
32
  diff-lcs (>= 1.2.0, < 2.0)
34
- rspec-support (~> 3.9.0)
35
- rspec-mocks (3.9.1)
33
+ rspec-support (~> 3.12.0)
34
+ rspec-mocks (3.12.6)
36
35
  diff-lcs (>= 1.2.0, < 2.0)
37
- rspec-support (~> 3.9.0)
38
- rspec-support (3.9.2)
39
- simplecov (0.8.2)
40
- docile (~> 1.1.0)
41
- multi_json
42
- simplecov-html (~> 0.8.0)
43
- simplecov-html (0.8.0)
44
- thread_safe (0.3.6)
45
- tzinfo (1.2.7)
46
- thread_safe (~> 0.1)
36
+ rspec-support (~> 3.12.0)
37
+ rspec-support (3.12.1)
38
+ simplecov (0.22.0)
39
+ docile (~> 1.1)
40
+ simplecov-html (~> 0.11)
41
+ simplecov_json_formatter (~> 0.1)
42
+ simplecov-html (0.12.3)
43
+ simplecov_json_formatter (0.1.4)
44
+ tzinfo (2.0.6)
45
+ concurrent-ruby (~> 1.0)
47
46
 
48
47
  PLATFORMS
49
- ruby
48
+ arm64-darwin-21
50
49
 
51
50
  DEPENDENCIES
52
- factory_girl (~> 4.7)
51
+ factory_bot
53
52
  listen (>= 3.0.8)
54
53
  lumberjack (~> 1.0, >= 1.0.13)
55
54
  rb-inotify (~> 0.9.10)
56
55
  rspec
57
- simplecov (~> 0.8.2)
56
+ simplecov
58
57
 
59
58
  BUNDLED WITH
60
- 1.17.3
59
+ 2.4.18
@@ -57,8 +57,8 @@ accepting a parameter.
57
57
 
58
58
  #### Step 2: Defining outcomes and the variables that affects the test.
59
59
 
60
- For the sake of simplicity, we will define the variables and outcomes in a separate yaml file, mainly because the next
61
- steps are purely configurations. Using yaml is completely optional.
60
+ For the sake of simplicity, we will define the variables and outcomes in a separate YAML file, mainly because the next
61
+ steps are purely configurations. Using YAML is completely optional.
62
62
 
63
63
  Create a folder `rast` in the same level as the spec file:
64
64
 
@@ -70,8 +70,9 @@ Create a yaml file with the same name as the spec, but with `.yml` extension.
70
70
  `spec/rast/positive_spec.yml` would contain:
71
71
 
72
72
  ```yaml
73
+ ---
73
74
  specs:
74
- Is Positive Exaple:
75
+ Is Positive Example:
75
76
  variables: {number: [-1, 0, 1]}
76
77
  outcomes: {true: 1}
77
78
  ```
data/README.md CHANGED
@@ -9,11 +9,11 @@ RSpec All Scenario Testing
9
9
 
10
10
  This library runs on top of RSpec to provide basically a parameterized unit testing pattern. It follows a specific pattern of writing unit tests, enabling a predictable, complete and outputs a result that is simple to analyze.
11
11
 
12
- ### A Basic Example
12
+ ## A Basic Example
13
13
 
14
- Suppose we want to create a class that checks if a number is a positive number or not.
14
+ Suppose we want to create a class that checks if a number is a positive or a negative number.
15
15
 
16
- #### Create a spec file `spec/positive_spec.rb`
16
+ ### Create a spec file `spec/positive_spec.rb`
17
17
 
18
18
  ```ruby
19
19
  require 'rast'
@@ -25,11 +25,12 @@ rast Positive do
25
25
  end
26
26
  ```
27
27
 
28
- #### Create a spec configuration `spec/rast/positive_spec.yml`
28
+ ### Create a spec configuration `spec/rast/positive_spec.yml`
29
29
 
30
30
  ```yaml
31
+ ---
31
32
  specs:
32
- Is Positive Exaple:
33
+ Is Positive Example:
33
34
  variables: {number: [-1, 0, 1]}
34
35
  outcomes: {true: 1}
35
36
  ```
@@ -61,38 +62,46 @@ Finished in 0.00471 seconds (files took 0.47065 seconds to load)
61
62
  3 examples, 0 failures
62
63
  ```
63
64
 
64
- Read the [documentation](./Documentation.md) for more examples.
65
+ See the [documentation](./Documentation.md) for more examples.
66
+
67
+ ## How to use this project
68
+ 1. Run `$ bundle install`
69
+ 2. Run `$ bundle exec rspec`
70
+
71
+ ### Troubleshooting
72
+ * Delete the Gemfile.lock and reinstall.
73
+
65
74
 
66
75
  ## Contributing
67
76
 
68
77
  ### Definition of terms
69
78
 
70
- - `spec` - as defined in the yaml file, the individual elements under `specs`
79
+ - `spec` - as defined in the YAML file, the individual elements under `specs`.
71
80
  - `scenario` - a specific combination of tokens from vars, it can uniquely identify a fixture.
72
81
  - `token` - used loosely to denote the individual variable in a rule. e.g. `true: you & me`, `you` and `me` are tokens.
73
- - `fixture` - a hash containing a scenario, reference back to the spec, and the expected result for the given scenario.
82
+ - `fixture` - a hash containing a scenario, references back to the spec, and the expected result for the given scenario.
74
83
  - `variables` - raw list of variables to be combined into multiple fixtures.
75
- - `rule` - set of outcomes, each paired with rule clause.
76
- - `exclusions` - rule defining variable combinations to be excluded from the test.
84
+ - `rule` - set of outcomes, each paired with a rule clause.
85
+ - `exclusions` - rule defining the variable combinations to be excluded from the test.
77
86
  - `inclusions` - rule that limits the scenarios to be included. Useful for isolating test cases.
78
- - `outcome` - the left portion `us` of a rule e.g. `us: you&me`
79
- - `clause` - the right portion `you&me` of a rule e.g. `us: you&me`
87
+ - `outcome` - the left portion `us` of a rule, e.g. `us: you&me`
88
+ - `clause` - the right portion `you&me` of a rule, e.g. `us: you&me`
80
89
 
81
90
  ## Notes to author
82
91
 
83
- When running the tests, the execution starts at the spec file, then invoking the
92
+ When running the tests, the execution starts at the spec file, then invokes the
84
93
  DSL. The DSL will then invoke the parameter generator to generate the scenarios.
85
94
 
86
95
  ### Releasing new features/bugfix
87
96
 
88
- - Increment the .gemspec
89
- - Modify the CHANGELOG.md
97
+ - Increment the [.gemspec](./rast.gemspec)
98
+ - Modify the [CHANGELOG.md](./CHANGELOG.md)
90
99
 
91
- ### Releasing GEM
100
+ ### Releasing the GEM
92
101
 
93
102
  - Build gem with `gem build rast.gemspec`
94
103
  - Publish with `gem push <gem-filename>`
95
104
 
96
105
  ## References
97
106
 
98
- [Semantic Versioning](https://semver.org)
107
+ * [Semantic Versioning](https://semver.org)
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  # Example
4
- class HotelFinder
4
+ class DiplomatHotelFinder
5
5
  def aircon; end
6
6
 
7
7
  def security; end
@@ -1,10 +1,12 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'yaml'
4
- require 'rast/rast_spec'
4
+
5
5
  require 'rast/rules/rule'
6
6
  require 'rast/rules/rule_evaluator'
7
- require 'rast/rules/rule_validator'
7
+
8
+ require 'rast/rast_spec'
9
+ require 'rast/rule_validator'
8
10
 
9
11
  # Generates the test parameters.
10
12
  class ParameterGenerator
@@ -36,6 +38,9 @@ class ParameterGenerator
36
38
  list = []
37
39
 
38
40
  variables = spec.variables
41
+ # dict.first method returns the first key and value as an array, so invoking
42
+ # .first, then . last would return the
43
+ # first value.
39
44
  var_first = variables.first
40
45
  multipliers = []
41
46
 
@@ -67,12 +72,12 @@ class ParameterGenerator
67
72
 
68
73
  include_result = true
69
74
  unless spec.exclude_clause.nil?
70
- include_result = qualify_secario?(spec, scenario, false)
75
+ include_result = qualify_scenario?(spec, scenario, false)
71
76
  end
72
77
 
73
78
  return include_result if no_include_or_dont_include?(spec, include_result)
74
79
 
75
- qualify_secario?(spec, scenario, true)
80
+ qualify_scenario?(spec, scenario, true)
76
81
  end
77
82
 
78
83
  # blech!
@@ -80,14 +85,13 @@ class ParameterGenerator
80
85
  spec.include_clause.nil? || !include_result
81
86
  end
82
87
 
83
- def qualify_secario?(spec, scenario, is_included)
88
+ def qualify_scenario?(spec, scenario, is_included)
84
89
  action = is_included ? 'include' : 'exclude'
85
- rule_evaluator = RuleEvaluator.new(converters: spec.converters)
90
+ rule_evaluator = RuleEvaluator.new(token_converters: spec.token_converter)
86
91
  clause = Rule.sanitize(clause: spec.send("#{action}_clause"))
87
92
  rule_evaluator.parse(expression: clause)
88
93
  rule_evaluator.evaluate(
89
- scenario: scenario,
90
- rule_token_convert: spec.token_converter
94
+ scenario: scenario
91
95
  ) == is_included.to_s
92
96
  end
93
97
 
@@ -14,7 +14,7 @@ class RastSpec
14
14
 
15
15
  def initialize(
16
16
  description: '',
17
- variables: [][],
17
+ variables: {},
18
18
  rule: nil,
19
19
  default_outcome: ''
20
20
  )
@@ -5,17 +5,21 @@ require 'rast/rules/rule_processor'
5
5
  # Validates rules
6
6
  class RuleValidator
7
7
  def validate(scenario: [], fixture: {})
8
- rule_result = RuleProcessor.new.evaluate(
9
- scenario: scenario,
10
- fixture: fixture
8
+ spec = fixture[:spec]
9
+ rule_processor = RuleProcessor.new(
10
+ rule: spec.rule,
11
+ token_converters: spec.token_converter
11
12
  )
12
13
 
14
+ rule_result = rule_processor.evaluate(scenario: scenario)
15
+
13
16
  spec = fixture[:spec]
14
17
  validate_results(scenario, rule_result, spec)
15
18
  end
16
19
 
17
20
  private
18
21
 
22
+ # @returns string
19
23
  def validate_results(scenario, rule_result, spec)
20
24
  rule = spec.rule
21
25
  single_result = rule.size == 1
@@ -32,7 +36,7 @@ class RuleValidator
32
36
  matched_outputs = []
33
37
  match_count = 0
34
38
 
35
- rule_result.map { |result| result.to_s == 'true' }.each_with_index do |result, i|
39
+ to_boolean(string_list: rule_result).each_with_index do |result, i|
36
40
  next unless result
37
41
 
38
42
  match_count += 1
@@ -44,6 +48,13 @@ class RuleValidator
44
48
  matched_outputs.first || spec.default_outcome
45
49
  end
46
50
 
51
+ # @returns array of boolean from array of strings. 'true' becomes true.
52
+ def to_boolean(string_list: [])
53
+ string_list.map do |result|
54
+ result.to_s == 'true'
55
+ end
56
+ end
57
+
47
58
  def verify_results(spec, scenario, matched_outputs, match_count)
48
59
  Rast.assert("#{spec.description} #{scenario} must fall into a unique rule" \
49
60
  " outcome/clause, matched: #{matched_outputs}") do
@@ -51,7 +62,7 @@ class RuleValidator
51
62
  end
52
63
  end
53
64
 
54
- def binary_outcome(outcome: '', spec: nil, expected: false)
65
+ def binary_outcome(outcome: '', spec: nil, expected: 'false')
55
66
  if expected == 'true'
56
67
  outcome
57
68
  else
@@ -26,9 +26,10 @@ module LogicHelper
26
26
  # * @left left left token object.
27
27
  # * @right right right token object.
28
28
  # * @operation :and or :or.
29
+ # * @returns String boolean value, can be internal, thus it is string.
29
30
  # */
30
31
  def perform_logical(scenario: [], left: {}, right: {}, operation: :nil)
31
- evaluated = send(:both_internal?, left, right, operation)
32
+ evaluated = both_internal?(left, right, operation)
32
33
  return evaluated if evaluated
33
34
 
34
35
  default = operation == :and ? TRUE : FALSE
@@ -83,8 +84,7 @@ module LogicHelper
83
84
 
84
85
  return false unless left_eval
85
86
 
86
- right_eval = present?(scenario, right)
87
- left_eval && right_eval
87
+ present?(scenario, right)
88
88
  end
89
89
 
90
90
  def evaluate_or(scenario, left, right)
@@ -92,8 +92,7 @@ module LogicHelper
92
92
 
93
93
  return true if left_eval
94
94
 
95
- right_eval = present?(scenario, right)
96
- left_eval || right_eval
95
+ present?(scenario, right)
97
96
  end
98
97
 
99
98
  # /**
@@ -10,25 +10,12 @@ class Rule
10
10
  # * <b>Parameter Example:</b><br/>
11
11
  # * Visible:Proposed|Approved<br/>
12
12
  # * <br/>
13
- # * Peace:Friendly|Indifferent\<br/>
14
- # * ~War:Angry\<br/>
15
- # * ~Neutral:Play safe
16
13
  # */
17
14
  def initialize(rules: {})
18
15
  raise 'Must not have empty rules' if rules.empty?
19
16
 
20
17
  @outcome_clause_hash = {}
21
- # should have array of the rule pairs
22
- # rules = pActRuleSrc.split("~");
23
- duplicates = []
24
-
25
18
  rules.each do |outcome, clause|
26
- # if duplicates.include?(outcome)
27
- # raise "#{outcome} matched multiple clauses"
28
- # end
29
-
30
- # duplicates << outcome
31
-
32
19
  @outcome_clause_hash[outcome.to_s] = Rule.sanitize(clause: clause)
33
20
  end
34
21
  end
@@ -31,7 +31,6 @@ class RuleEvaluator
31
31
  DEFAULT_CONVERT_HASH = {
32
32
  Integer => IntConverter.new,
33
33
  Float => FloatConverter.new,
34
- Fixnum => IntConverter.new,
35
34
  Array => DefaultConverter.new,
36
35
  TrueClass => BoolConverter.new,
37
36
  FalseClass => BoolConverter.new,
@@ -39,9 +38,9 @@ class RuleEvaluator
39
38
  NilClass => DefaultConverter.new
40
39
  }.freeze
41
40
 
42
- # /** @param pConverterList list of rule token converters. */
43
- def initialize(converters: [])
44
- @converters = converters
41
+ # /** @param token_converters token to converter mapping */
42
+ def initialize(token_converters: {})
43
+ @token_converters = token_converters
45
44
 
46
45
  @stack_operations = []
47
46
  @stack_rpn = []
@@ -53,6 +52,7 @@ class RuleEvaluator
53
52
  # *
54
53
  # * @param pExpression <code>String</code> input expression (logical
55
54
  # * expression formula)
55
+ # * @return void.
56
56
  # * @since 0.3.0
57
57
  # */
58
58
  def parse(expression: '')
@@ -86,13 +86,13 @@ class RuleEvaluator
86
86
  # * @param rule_token_convert mapping of rule tokens to converter.
87
87
  # * @return <code>String</code> representation of the result
88
88
  # */
89
- def evaluate(scenario: [], rule_token_convert: {})
89
+ def evaluate(scenario: [])
90
90
  if @stack_rpn.size == 1
91
91
  evaluate_one_rpn(scenario: scenario).to_s
92
92
  else
93
93
  evaluate_multi_rpn(
94
94
  scenario: scenario,
95
- rule_token_convert: rule_token_convert
95
+ rule_token_convert: @token_converters
96
96
  )
97
97
  end
98
98
  end
@@ -110,19 +110,19 @@ class RuleEvaluator
110
110
 
111
111
  return default if token.is_a?(Array) || [TRUE, FALSE].include?(token)
112
112
 
113
- next_value_default(rule_token_convert, token)
113
+ next_value_default(token)
114
114
  end
115
115
 
116
116
  # private
117
- def next_value_default(rule_token_convert, token)
117
+ def next_value_default(token)
118
118
  token_cleaned = token.to_s.strip
119
119
  subscript = TokenUtil.extract_subscript(token: token_cleaned)
120
120
  token_body = subscript > -1 ? token_cleaned[/^.+(?=\[)/] : token_cleaned
121
121
 
122
- raise "Config Error: Outcome clause token: '#{token}' not found in variables" if rule_token_convert[token_body].nil?
122
+ raise "Config Error: Outcome clause token: '#{token}' not found in variables" if @token_converters[token_body].nil?
123
123
 
124
124
  {
125
- value: rule_token_convert[token_body].convert(token_body),
125
+ value: @token_converters[token_body].convert(token_body),
126
126
  subscript: subscript
127
127
  }
128
128
  end
@@ -4,20 +4,21 @@ require 'rast/rules/rule_evaluator'
4
4
 
5
5
  # undoc
6
6
  class RuleProcessor
7
+ def initialize(rule: nil, token_converters: {})
8
+ @rule = rule
9
+ @token_converters = token_converters
10
+ end
11
+
7
12
  # /**
8
13
  # * @param scenario current scenario.
9
- # * @param caseFixture current test case fixture.
14
+ # *
15
+ # * @return the outcome results against the given scenario.
10
16
  # */
11
- def evaluate(scenario: [], fixture: nil)
12
- # if scenario.empty? || fixture.nil?
13
- # raise 'Scenario or fixture cannot be nil.'
14
- # end
15
-
16
- fixture[:spec].rule.outcomes.inject([]) do |retval, outcome|
17
+ def evaluate(scenario: [])
18
+ @rule.outcomes.inject([]) do |retval, outcome|
17
19
  process_outcome(
18
- scenario: scenario,
19
- fixture: fixture,
20
20
  list: retval,
21
+ scenario: scenario,
21
22
  outcome: outcome
22
23
  )
23
24
  end
@@ -25,17 +26,12 @@ class RuleProcessor
25
26
 
26
27
  private
27
28
 
28
- def process_outcome(scenario: [], fixture: nil, list: [], outcome: '')
29
- spec = fixture[:spec]
30
-
31
- clause = spec.rule.clause(outcome: outcome)
32
- rule_evaluator = RuleEvaluator.new(converters: spec.converters)
33
-
29
+ # @returns the list argument with the new result.
30
+ def process_outcome(list: [], scenario: [], outcome: '')
31
+ clause = @rule.clause(outcome: outcome)
32
+ rule_evaluator = RuleEvaluator.new(token_converters: @token_converters)
34
33
  rule_evaluator.parse(expression: clause)
35
34
 
36
- list << rule_evaluator.evaluate(
37
- scenario: scenario,
38
- rule_token_convert: spec.token_converter
39
- )
35
+ list << rule_evaluator.evaluate(scenario: scenario)
40
36
  end
41
37
  end
data/lib/rast/spec_dsl.rb CHANGED
@@ -1,11 +1,11 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'factory_girl'
3
+ require 'factory_bot'
4
4
  require 'rast/parameter_generator'
5
5
 
6
6
  # Main DSL. This is the entry point of the test when running a spec.
7
7
  class SpecDSL
8
- include FactoryGirl::Syntax::Methods
8
+ include FactoryBot::Syntax::Methods
9
9
 
10
10
  attr_accessor :subject, :execute_block,
11
11
  :prepare_block, :outcomes, :fixtures, :spec_id
@@ -144,13 +144,16 @@ def generate_rspec(scope: nil, scenario: {}, expected: '')
144
144
  instance_exec(*block_params, &scope.prepare_block)
145
145
  end
146
146
 
147
- actual = scope.execute_block.call(*block_params)
148
- actual = actual.nil? ? 'nil' : actual.to_s
149
-
147
+ actual = execute_and_format_result(scope, block_params)
150
148
  expect(actual).to eq(expected)
151
149
  end
152
150
  end
153
151
 
152
+ def execute_and_format_result(scope, block_params)
153
+ actual = scope.execute_block.call(*block_params)
154
+ actual.nil? ? 'nil' : actual.to_s
155
+ end
156
+
154
157
  def _it_title(expected, scenario)
155
158
  spec_params = scenario.keys.inject('') do |output, key|
156
159
  build_it(scenario, output, key)
data/rast.gemspec CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  Gem::Specification.new do |spec|
4
4
  spec.name = 'rast'
5
- spec.version = '0.19.1'
5
+ spec.version = '1.0.0'
6
6
  spec.authors = ['Royce Remulla']
7
7
  spec.email = ['royce.com@gmail.com']
8
8
 
@@ -10,9 +10,9 @@ Gem::Specification.new do |spec|
10
10
  spec.description = 'Extends RSpec functionality by using the catch-all-scenario testing (CAST) principle.'
11
11
  spec.homepage = 'https://github.com/roycetech/rast'
12
12
  spec.license = 'MIT'
13
- spec.required_ruby_version = Gem::Requirement.new('~> 2.0')
13
+ spec.required_ruby_version = Gem::Requirement.new('~> 3.2')
14
14
 
15
- spec.add_runtime_dependency 'factory_girl', '~> 4.7'
15
+ spec.add_runtime_dependency 'factory_bot', '~> 6.2'
16
16
 
17
17
  # spec.metadata['allowed_push_host'] = "TODO: Set to 'http://mygemserver.com'"
18
18
  spec.metadata['homepage_uri'] = spec.homepage
metadata CHANGED
@@ -1,29 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rast
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.19.1
4
+ version: 1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Royce Remulla
8
- autorequire:
8
+ autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-05-22 00:00:00.000000000 Z
11
+ date: 2023-08-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: factory_girl
14
+ name: factory_bot
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: '4.7'
19
+ version: '6.2'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: '4.7'
26
+ version: '6.2'
27
27
  description: Extends RSpec functionality by using the catch-all-scenario testing (CAST)
28
28
  principle.
29
29
  email:
@@ -35,6 +35,7 @@ files:
35
35
  - ".gitignore"
36
36
  - ".rspec"
37
37
  - ".rubocop.yml"
38
+ - ".ruby-version"
38
39
  - ".travis.yml"
39
40
  - CHANGELOG.md
40
41
  - Documentation.md
@@ -43,9 +44,9 @@ files:
43
44
  - Getting-Started-Detailed.md
44
45
  - Getting-Started.md
45
46
  - README.md
47
+ - examples/diplomat_hotel_finder.rb
46
48
  - examples/enum_module.rb
47
49
  - examples/factory_example.rb
48
- - examples/hotel_finder.rb
49
50
  - examples/logic_checker.rb
50
51
  - examples/person.rb
51
52
  - examples/positive.rb
@@ -62,12 +63,12 @@ files:
62
63
  - lib/rast/converters/str_converter.rb
63
64
  - lib/rast/parameter_generator.rb
64
65
  - lib/rast/rast_spec.rb
66
+ - lib/rast/rule_validator.rb
65
67
  - lib/rast/rules/logic_helper.rb
66
68
  - lib/rast/rules/operator.rb
67
69
  - lib/rast/rules/rule.rb
68
70
  - lib/rast/rules/rule_evaluator.rb
69
71
  - lib/rast/rules/rule_processor.rb
70
- - lib/rast/rules/rule_validator.rb
71
72
  - lib/rast/rules/token_util.rb
72
73
  - lib/rast/spec_dsl.rb
73
74
  - lib/template_spec.yml
@@ -79,7 +80,7 @@ metadata:
79
80
  homepage_uri: https://github.com/roycetech/rast
80
81
  source_code_uri: https://github.com/roycetech/rast
81
82
  changelog_uri: https://github.com/roycetech/rast/blob/feature/ruby-2.0.0-support/CHANGELOG.md
82
- post_install_message:
83
+ post_install_message:
83
84
  rdoc_options: []
84
85
  require_paths:
85
86
  - lib
@@ -87,15 +88,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
87
88
  requirements:
88
89
  - - "~>"
89
90
  - !ruby/object:Gem::Version
90
- version: '2.0'
91
+ version: '3.2'
91
92
  required_rubygems_version: !ruby/object:Gem::Requirement
92
93
  requirements:
93
94
  - - ">="
94
95
  - !ruby/object:Gem::Version
95
96
  version: '0'
96
97
  requirements: []
97
- rubygems_version: 3.1.2
98
- signing_key:
98
+ rubygems_version: 3.4.18
99
+ signing_key:
99
100
  specification_version: 4
100
101
  summary: RSpec AST - All Scenario Testing
101
102
  test_files: []