rulezilla 0.1.4 → 0.1.5

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
  SHA1:
3
- metadata.gz: 0a5437383cf683007f42c90a096f3428103cdc46
4
- data.tar.gz: 0e3366b7fee344c1d5c1958ee1f8ffd54a2b402b
3
+ metadata.gz: 8de468c7423c8fb95e879491361d8587ced03b28
4
+ data.tar.gz: 9cbbd613deab120d67a6da93e81a4e7fc360ec38
5
5
  SHA512:
6
- metadata.gz: abb77e8d80423a511e1ea78a0c4600bb103f628879268033e653573c5e264840aaacebe52512334597853991b9aee9e66b51ea49511c8cb4f7e2e65d58cd4271
7
- data.tar.gz: 2c0100529a1032e5b02b12c522effc33d44cd8753cdfbd3541b9f1d83ab197e5864a098f44eab8238c9347f3657d1e0601d12dc2bf2ea17554b70f1d63fc034d
6
+ metadata.gz: 52adab9a3346e9cfb20b58a7197c2a724f823f04d647f2dc313f07cb01ed169c59c5a10c708fe2581a6c7914da33e88a3641f04b02ce337f8d2207dad181df51
7
+ data.tar.gz: 9fdf3bb8bf2b3366fec2e7d140ade30020113f8e3ef80bdd198720139152e6b3c81a3b816a2c292dcc315e01ed0b26a96687beccfbe25cb848569db8d3d47965
data/.gitignore CHANGED
@@ -1 +1,5 @@
1
1
  .bundle
2
+ Gemfile.lock
3
+ .ruby-version
4
+ .ruby-gemset
5
+ .idea/
data/Gemfile CHANGED
@@ -1,6 +1,2 @@
1
1
  source 'https://rubygems.org'
2
2
  gemspec
3
-
4
- gem 'rspec'
5
- gem 'turnip'
6
- gem 'pry'
data/README.md CHANGED
@@ -1,43 +1,61 @@
1
- [![Semaphore](https://semaphoreapp.com/api/v1/projects/e488365d-9c57-4431-916a-72aea091d1b5/229083/shields_badge.png)](https://semaphoreapp.com/simplybusiness/rulezilla)
1
+ [![Build Status](https://semaphoreci.com/api/v1/projects/e488365d-9c57-4431-916a-72aea091d1b5/229083/shields_badge.svg)](https://semaphoreci.com/simplybusiness/rulezilla)
2
2
  [![Code Climate](https://codeclimate.com/repos/53ecc0416956800c1d01f6bf/badges/76b47eaeffc33e312508/gpa.svg)](https://codeclimate.com/repos/53ecc0416956800c1d01f6bf/feed)
3
-
3
+ [![Gem Version](https://badge.fury.io/rb/rulezilla.svg)](http://badge.fury.io/rb/rulezilla)
4
4
 
5
5
  rulezilla
6
6
  =========
7
7
 
8
- This provide a DSL to implement rules for various tasks. In the current version we are still rely user to have a certain level of Ruby knowledge to be able to use this DSL. The ultimate goal is for people without prior Ruby knowledge can change and even write the Rule.
8
+ This provides a DSL to implement rules for various tasks. In the current version we are still relying on user to have a certain level of Ruby knowledge
9
+ in order to be able to use this DSL. The ultimate goal is for people without prior Ruby knowledge to be able to change and even write the Rule.
9
10
 
10
11
 
11
12
  # Installation
12
13
 
13
- gem 'rulezilla', git: 'git@github.com:simplybusiness/rulezilla.git'
14
+ ## Using `Gemfile`
15
+
16
+ Add the following line to your `Gemfile`:
17
+
18
+ gem 'rulezilla'
19
+
20
+ Then run:
21
+
22
+ bundle install
23
+
24
+ ## Without `Gemfile`
14
25
 
15
- ## Implementation
26
+ On your command line run the following:
27
+
28
+ gem install 'rulezilla'
29
+
30
+ ## Usage
16
31
 
17
32
  ### Rules
18
33
 
34
+ Rules can be defined either using `Gherkin` or pure Ruby. In either case, rules are classes that include the `Rulezilla::DSL`.
35
+
19
36
  #### Gherkin (Beta)
20
37
 
21
- rulezilla Gherkin has only very limited support now
38
+ > *Note:* Currently, rulezilla Gherkin has only very limited support.
22
39
 
23
- First set the path of which rulezilla can load the feature files from:
40
+ Rules are defined inside `.feature` files which should be organized under a specific directory. In order to be able to use these rules, you need to first
41
+ set the path that rulezilla can use in order to load them.
24
42
 
25
- Rulezilla.gherkin_rules_path = 'absolute path'
43
+ Rulezilla.gherkin_rules_path = 'absolute path to folder holding your feature files'
26
44
 
27
- The filename will then converted to the name of the class, e.g. `invalid_number_rule.feature` will generate `Rulezilla::InvalidNumberRule` class
45
+ Rulezilla will load all the feature files and for each one will create a rule class. The filename will be used to build the name of the rule class. For example,
46
+ the file with name `invalid_number_rule.feature` will generate rule class `Rulezilla::InvalidNumberRule`.
28
47
 
29
- We currently only support a very limited steps, please refer to:
48
+ We currently support a very limited type of steps. Please refer to:
30
49
 
31
50
  [True / False](spec/features/gherkin_rules/animal_rule.feature)
32
51
 
33
52
  [Duration](spec/features/gherkin_rules/duration_rule.feature)
34
53
 
35
-
36
54
  #### Ruby
37
55
 
38
- Please refer to the [feature](spec/features/rulezilla_dsl_framwork.feature) for further details
56
+ You can use plain Ruby to define the rule classes. But you will need to include the `Rulezilla::DSL` module. That will give you access to the DSL used to define rules.
39
57
 
40
- To use rulezilla, please include `Rulezilla::DSL` in your class:
58
+ Here is an example:
41
59
 
42
60
  class RoboticsRule
43
61
  include Rulezilla::DSL
@@ -59,6 +77,8 @@ To use rulezilla, please include `Rulezilla::DSL` in your class:
59
77
 
60
78
  end
61
79
 
80
+ Please refer to the [feature](spec/features/rulezilla_dsl_framework.feature) for further details of the DSL.
81
+
62
82
  ### Support Module
63
83
 
64
84
  The support module will be automatically included if its name is `"#{rule_class_name}Support"`
@@ -73,24 +93,28 @@ e.g. if the rule class name is `RoboticsRule`, then the support would be `Roboti
73
93
 
74
94
  ### How to execute the rule
75
95
 
76
- if the entity is:
96
+ If the entity is:
77
97
 
78
- {
79
- not_injure_human?: true,
80
- do_as_human_told?: true,
81
- in_danger?: true,
98
+ entity = {
99
+ not_injure_human?: true,
100
+ do_as_human_told?: true,
101
+ in_danger?: true,
82
102
  not_letting_itself_be_detroyed?: true
83
103
  }
84
104
 
85
- #### To get the first matching result
105
+ #### To get the first matching result output
86
106
 
87
107
  RoboticsRule.apply(entity) #=> true
88
108
 
89
- #### To get all matching results
109
+ #### To get all matching result outputs
90
110
 
91
- RoboticsRule.all(entity) #=> [true]
111
+ RoboticsRule.all(entity) #=> [true, false]
112
+
113
+ Note that `false` is the result outcome coming out from `default(false)` on top level, which is also called `root node`. The `root` node does not have any condition and hence
114
+ it is considered to be matching. This means, by consequence, that its result (`default(false)`) is included in the list of matching result outputs which `#all(entity)` above
115
+ returns.
92
116
 
93
- #### To get the trace of all node
117
+ #### To get the trace of all nodes
94
118
 
95
119
  RoboticsRule.trace(entity)
96
120
  #=> all the nodes instance: [root, may_not_injure_human, obey_human, protect_its_own_existence] in sequence order.
@@ -100,10 +124,10 @@ if the entity is:
100
124
  RoboticsRule.results #=> [true, false]
101
125
 
102
126
 
103
- # Syntax
127
+ ### Syntax
104
128
 
105
129
  Please refer to the features for DSL syntax:
106
130
 
107
- [DSL Feature](spec/features/rulezilla_dsl_framwork.feature),
131
+ [DSL Feature](spec/features/rulezilla_dsl_framework.feature),
108
132
 
109
133
  [Default Support Methods Feature](spec/features/default_support_methods.feature)
@@ -1,7 +1,11 @@
1
1
  module Rulezilla
2
2
  class Node
3
- attr_accessor :parent, :children
4
- attr_reader :condition, :default, :name
3
+ attr_accessor :children,
4
+ :condition,
5
+ :parent
6
+
7
+ attr_reader :default, :name
8
+ attr_writer :result
5
9
 
6
10
  def initialize
7
11
  @children = []
@@ -17,25 +21,17 @@ module Rulezilla
17
21
 
18
22
  def applies?(record)
19
23
  return true if condition.nil?
20
- record.instance_eval(&condition)
24
+ !!record.instance_eval(&condition)
21
25
  end
22
26
 
23
27
  def result(record)
24
28
  @result.is_a?(Proc) ? record.instance_eval(&@result) : @result
25
29
  end
26
30
 
27
- def condition=(block)
28
- @condition = block
29
- end
30
-
31
31
  def name=(value)
32
32
  @name = value.to_s
33
33
  end
34
34
 
35
- def result=(block)
36
- @result = block
37
- end
38
-
39
35
  def add_child(node)
40
36
  node.parent = self
41
37
  children << node
@@ -12,6 +12,8 @@ module Rulezilla
12
12
  @current_node = is_root? ? @root_node : @current_node.parent
13
13
  end
14
14
 
15
+ # Returns all the result outcomes of all the matching nodes.
16
+ #
15
17
  def find_all(record, node=@root_node)
16
18
  array = []
17
19
  if node.applies?(record)
@@ -21,7 +23,7 @@ module Rulezilla
21
23
 
22
24
  return node.has_result? ? array + [node] : array
23
25
  end
24
- return array
26
+ array
25
27
  end
26
28
 
27
29
  def trace(record, node=@root_node)
@@ -1,3 +1,3 @@
1
1
  module Rulezilla
2
- VERSION = '0.1.4'
2
+ VERSION = '0.1.5'
3
3
  end
@@ -14,5 +14,9 @@ Gem::Specification.new do |gem|
14
14
  gem.version = Rulezilla::VERSION
15
15
  gem.license = 'MIT'
16
16
 
17
- gem.add_runtime_dependency('gherkin')
17
+ gem.add_runtime_dependency('gherkin', '~> 2.5')
18
+ gem.add_runtime_dependency('rspec')
19
+ gem.add_runtime_dependency('turnip')
20
+ gem.add_development_dependency('pry')
21
+ gem.add_development_dependency('pry-doc')
18
22
  end
@@ -85,7 +85,7 @@ Scenario: If nothing is matched in a group, it will fall to default value of the
85
85
  Then the result is "It is alright"
86
86
 
87
87
 
88
- Scenario: If nothing is matched, and no default is define in the group, it will fall to the next default
88
+ Scenario: If nothing is matched, and no default is defined in the group, it will fall to the next default
89
89
  Given the rule is:
90
90
  """
91
91
  group :group_1 do
@@ -126,7 +126,7 @@ Scenario: If nothing is matched, it will continue to evaluate the next group
126
126
  Then the result is "Bad"
127
127
 
128
128
 
129
- Scenario Outline: It evaluate the rule against a record
129
+ Scenario Outline: It evaluates the rule against a record
130
130
  Given the rule is:
131
131
  """
132
132
  define :fruit do
@@ -185,6 +185,53 @@ Scenario: To get all matching outcomes from a rule
185
185
  """
186
186
  Then all the matching outcomes are "B, C, D, F"
187
187
 
188
+ Scenario: To get all matching outcomes from a rule with root node default result
189
+ Given the rule is:
190
+ """
191
+ group :may_not_injure_human do
192
+ condition { not_injure_human? }
193
+
194
+ group :obey_human do
195
+ condition { do_as_human_told? }
196
+ result(true)
197
+
198
+ define :protect_its_own_existence do
199
+ condition { in_danger? && not_letting_itself_be_detroyed? }
200
+ result(true)
201
+ end
202
+ end
203
+ end
204
+
205
+ default(false)
206
+ """
207
+ When the record has attribute "not_injure_human?" and returns "true"
208
+ When the record has attribute "do_as_human_told?" and returns "true"
209
+ When the record has attribute "in_dangert?" and returns "true"
210
+ When the record has attribute "not_letting_itself_be_detroyed?" and returns "true"
211
+ Then all the matching outcomes are "true, false"
212
+
213
+ Scenario: To get all matching outcomes from a rule without root node default result
214
+ Given the rule is:
215
+ """
216
+ group :may_not_injure_human do
217
+ condition { not_injure_human? }
218
+
219
+ group :obey_human do
220
+ condition { do_as_human_told? }
221
+ result(true)
222
+
223
+ define :protect_its_own_existence do
224
+ condition { in_danger? && not_letting_itself_be_detroyed? }
225
+ result(true)
226
+ end
227
+ end
228
+ end
229
+ """
230
+ When the record has attribute "not_injure_human?" and returns "true"
231
+ When the record has attribute "do_as_human_told?" and returns "true"
232
+ When the record has attribute "in_dangert?" and returns "true"
233
+ When the record has attribute "not_letting_itself_be_detroyed?" and returns "true"
234
+ Then all the matching outcomes are "true"
188
235
 
189
236
  Scenario: Support Module
190
237
  Given the rule class name is "FruitRule"
@@ -227,7 +274,7 @@ Scenario Outline: Validate the presence of attributes
227
274
  | apple, orange | does not | |
228
275
 
229
276
 
230
- Scenario: Rule return nil if no rule is defined Given the rule is:
277
+ Scenario: Rule return nil if no rule is defined
231
278
  Given the rule is:
232
279
  """
233
280
  """
@@ -90,7 +90,7 @@ step 'all the outcomes are :outcomes' do |outcomes|
90
90
  end
91
91
 
92
92
  step 'all the matching outcomes are :outcomes' do |outcomes|
93
- outcomes = outcomes.split(',').map(&:strip)
93
+ outcomes = outcomes.split(',').map(&:strip).map {|o| o == 'true' ? true : (o == 'false' ? false : o)}
94
94
  expect(@rule_klass.all(@record)).to match_array outcomes
95
95
  end
96
96
 
metadata CHANGED
@@ -1,17 +1,31 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rulezilla
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.4
4
+ version: 0.1.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Peter Wu
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-01-19 00:00:00.000000000 Z
11
+ date: 2016-02-17 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: gherkin
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '2.5'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '2.5'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rspec
15
29
  requirement: !ruby/object:Gem::Requirement
16
30
  requirements:
17
31
  - - ">="
@@ -24,6 +38,48 @@ dependencies:
24
38
  - - ">="
25
39
  - !ruby/object:Gem::Version
26
40
  version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: turnip
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: pry
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - ">="
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - ">="
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: pry-doc
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ">="
74
+ - !ruby/object:Gem::Version
75
+ version: '0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ">="
81
+ - !ruby/object:Gem::Version
82
+ version: '0'
27
83
  description: Rules DSL
28
84
  email:
29
85
  - peter.wu@simplybusiness.com
@@ -34,7 +90,6 @@ files:
34
90
  - ".gitignore"
35
91
  - ".rspec"
36
92
  - Gemfile
37
- - Gemfile.lock
38
93
  - README.md
39
94
  - lib/rulezilla.rb
40
95
  - lib/rulezilla/basic_support.rb
@@ -50,7 +105,7 @@ files:
50
105
  - spec/features/gherkin_dsl_framework.feature
51
106
  - spec/features/gherkin_rules/animal_rule.feature
52
107
  - spec/features/gherkin_rules/duration_rule.feature
53
- - spec/features/rulezilla_dsl_framwork.feature
108
+ - spec/features/rulezilla_dsl_framework.feature
54
109
  - spec/features/step_definitions/rule_steps.rb
55
110
  - spec/features/step_definitions/rulezilla_dsl_framework_steps.rb
56
111
  - spec/spec_helper.rb
@@ -1,44 +0,0 @@
1
- PATH
2
- remote: .
3
- specs:
4
- rulezilla (0.1.4)
5
- gherkin
6
-
7
- GEM
8
- remote: https://rubygems.org/
9
- specs:
10
- coderay (1.1.0)
11
- diff-lcs (1.2.5)
12
- gherkin (2.12.2)
13
- multi_json (~> 1.3)
14
- method_source (0.8.2)
15
- multi_json (1.10.1)
16
- pry (0.9.12.6)
17
- coderay (~> 1.0)
18
- method_source (~> 0.8)
19
- slop (~> 3.4)
20
- rspec (3.0.0)
21
- rspec-core (~> 3.0.0)
22
- rspec-expectations (~> 3.0.0)
23
- rspec-mocks (~> 3.0.0)
24
- rspec-core (3.0.3)
25
- rspec-support (~> 3.0.0)
26
- rspec-expectations (3.0.3)
27
- diff-lcs (>= 1.2.0, < 2.0)
28
- rspec-support (~> 3.0.0)
29
- rspec-mocks (3.0.3)
30
- rspec-support (~> 3.0.0)
31
- rspec-support (3.0.3)
32
- slop (3.5.0)
33
- turnip (1.2.2)
34
- gherkin (>= 2.5)
35
- rspec (>= 2.0, < 4.0)
36
-
37
- PLATFORMS
38
- ruby
39
-
40
- DEPENDENCIES
41
- pry
42
- rspec
43
- rulezilla!
44
- turnip