dmn 0.0.1 → 0.0.3

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.
@@ -1,12 +1,12 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module SpotFeel
3
+ module DMN
4
4
  class Node < Treetop::Runtime::SyntaxNode
5
5
  #
6
6
  # Takes a context hash and returns an array of qualified names
7
7
  # { "person": { "name": { "first": "Eric", "last": "Carlson" }, "age": 60 } } => ["person", "person.name.first", "person.name.last", "person.age"]
8
8
  #
9
- def qualified_names_in_context(hash = {}, prefix = '', qualified_names = Set.new)
9
+ def qualified_names_in_context(hash = {}, prefix = "", qualified_names = Set.new)
10
10
  hash.each do |key, value|
11
11
  new_prefix = prefix.empty? ? "#{key}" : "#{prefix}.#{key}"
12
12
  if value.is_a?(Hash)
@@ -114,13 +114,13 @@ module SpotFeel
114
114
  second_val = second.eval(context)
115
115
 
116
116
  case [start, finish]
117
- when ['(', ')']
117
+ when ["(", ")"]
118
118
  ->(input) { first_val < input && input < second_val }
119
- when ['[', ']']
119
+ when ["[", "]"]
120
120
  ->(input) { first_val <= input && input <= second_val }
121
- when ['(', ']']
121
+ when ["(", "]"]
122
122
  ->(input) { first_val < input && input <= second_val }
123
- when ['[', ')']
123
+ when ["[", ")"]
124
124
  ->(input) { first_val <= input && input < second_val }
125
125
  end
126
126
  end
@@ -225,11 +225,11 @@ module SpotFeel
225
225
  class QualifiedName < Node
226
226
  def eval(context = {})
227
227
  if tail.empty?
228
- raise_evaluation_error(head.text_value, context) if SpotFeel.config.strict && !context.key?(head.text_value.to_sym)
228
+ raise_evaluation_error(head.text_value, context) if DMN.config.strict && !context.key?(head.text_value.to_sym)
229
229
  context[head.text_value.to_sym]
230
230
  else
231
- tail.elements.flat_map { |element| element.name.text_value.split('.') }.inject(context[head.text_value.to_sym]) do |hash, key|
232
- raise_evaluation_error("#{head.text_value}#{tail.text_value}", context) if SpotFeel.config.strict && (hash.blank? || !hash.key?(key.to_sym))
231
+ tail.elements.flat_map { |element| element.name.text_value.split(".") }.inject(context[head.text_value.to_sym]) do |hash, key|
232
+ raise_evaluation_error("#{head.text_value}#{tail.text_value}", context) if DMN.config.strict && (hash.blank? || !hash.key?(key.to_sym))
233
233
  return nil unless hash
234
234
  hash[key.to_sym]
235
235
  end
@@ -385,7 +385,7 @@ module SpotFeel
385
385
  fn = context[fn_name.text_value.to_sym]
386
386
 
387
387
  unless fn
388
- raise_evaluation_error(fn_name.text_value, context) if SpotFeel.config.strict
388
+ raise_evaluation_error(fn_name.text_value, context) if DMN.config.strict
389
389
  return nil
390
390
  end
391
391
 
@@ -492,12 +492,12 @@ module SpotFeel
492
492
  class Comparison < Node
493
493
  def eval(context = {})
494
494
  case operator.text_value
495
- when '<' then left.eval(context) < right.eval(context)
496
- when '<=' then left.eval(context) <= right.eval(context)
497
- when '>=' then left.eval(context) >= right.eval(context)
498
- when '>' then left.eval(context) > right.eval(context)
499
- when '!=' then left.eval(context) != right.eval(context)
500
- when '=' then left.eval(context) == right.eval(context)
495
+ when "<" then left.eval(context) < right.eval(context)
496
+ when "<=" then left.eval(context) <= right.eval(context)
497
+ when ">=" then left.eval(context) >= right.eval(context)
498
+ when ">" then left.eval(context) > right.eval(context)
499
+ when "!=" then left.eval(context) != right.eval(context)
500
+ when "=" then left.eval(context) == right.eval(context)
501
501
  end
502
502
  end
503
503
  end
@@ -522,7 +522,7 @@ module SpotFeel
522
522
  # 53. instance of = expression , "instance" , "of" , type ;
523
523
  #
524
524
  class InstanceOf < Node
525
- def eval(context = {})
525
+ def eval(_context = {})
526
526
  case type.text_value
527
527
  when "string"
528
528
  ->(input) { input.is_a?(String) }
@@ -556,8 +556,6 @@ module SpotFeel
556
556
  ->(input) { input.is_a?(ActiveSupport::Duration) && input.parts.keys.sort == [:seconds] }
557
557
  when "time duration"
558
558
  ->(input) { input.is_a?(ActiveSupport::Duration) && input.parts.keys.sort == [:hours, :minutes, :seconds] }
559
- when "years and months duration"
560
- ->(input) { input.is_a?(ActiveSupport::Duration) && input.parts.keys.sort == [:months, :years] }
561
559
  when "list"
562
560
  ->(input) { input.is_a?(Array) }
563
561
  when "interval"
data/lib/dmn/output.rb ADDED
@@ -0,0 +1,27 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DMN
4
+ class Output
5
+ attr_reader :id, :label, :name, :type_ref
6
+
7
+ def self.from_json(json)
8
+ Output.new(id: json[:id], label: json[:label], name: json[:name], type_ref: json[:type_ref])
9
+ end
10
+
11
+ def initialize(id:, label:, name:, type_ref:)
12
+ @id = id
13
+ @label = label
14
+ @name = name
15
+ @type_ref = type_ref
16
+ end
17
+
18
+ def as_json
19
+ {
20
+ id: id,
21
+ label: label,
22
+ name: name,
23
+ type_ref: type_ref,
24
+ }
25
+ end
26
+ end
27
+ end
@@ -1,12 +1,12 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module SpotFeel
3
+ module DMN
4
4
  class Parser
5
- # Load the Treetop grammar from the 'spot_feel' file, and create a new
5
+ # Load the Treetop grammar from the 'feel' file, and create a new
6
6
  # instance of that parser as a class variable so we don't have to re-create
7
7
  # it every time we need to parse a string
8
- Treetop.load(File.expand_path(File.join(File.dirname(__FILE__), 'spot_feel.treetop')))
9
- @@parser = SpotFeelParser.new
8
+ Treetop.load(File.expand_path(File.join(File.dirname(__FILE__), "dmn.treetop")))
9
+ @@parser = DMNParser.new
10
10
 
11
11
  def self.parse(expression, root: nil)
12
12
  @@parser.parse(expression, root:).tap do |ast|
@@ -15,15 +15,15 @@ module SpotFeel
15
15
  end
16
16
 
17
17
  def self.parse_test(expression)
18
- @@parser.parse(expression || '-', root: :simple_unary_tests).tap do |ast|
18
+ @@parser.parse(expression || "-", root: :simple_unary_tests).tap do |ast|
19
19
  raise SyntaxError, "Invalid unary test: #{expression.inspect}" unless ast
20
20
  end
21
21
  end
22
22
 
23
23
  def self.clean_tree(root_node)
24
24
  return if(root_node.elements.nil?)
25
- root_node.elements.delete_if{|node| node.class.name == "Treetop::Runtime::SyntaxNode" }
26
- root_node.elements.each {|node| self.clean_tree(node) }
25
+ root_node.elements.delete_if{ |node| node.class.name == "Treetop::Runtime::SyntaxNode" }
26
+ root_node.elements.each { |node| self.clean_tree(node) }
27
27
  end
28
28
  end
29
29
  end
data/lib/dmn/rule.rb ADDED
@@ -0,0 +1,61 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DMN
4
+ class Rule
5
+ attr_accessor :id, :input_entries, :output_entries, :description
6
+
7
+ def self.from_json(json)
8
+ input_entries = Array.wrap(json[:input_entry]).map { |input_entry| UnaryTests.from_json(input_entry) }
9
+ output_entries = Array.wrap(json[:output_entry]).map { |output_entry| LiteralExpression.from_json(output_entry) }
10
+ Rule.new(id: json[:id], input_entries:, output_entries:, description: json[:description])
11
+ end
12
+
13
+ def initialize(id:, input_entries:, output_entries:, description: nil)
14
+ @id = id
15
+ @input_entries = input_entries
16
+ @output_entries = output_entries
17
+ @description = description
18
+ end
19
+
20
+ def evaluate(input_values = [], variables = {})
21
+ [].tap do |test_results|
22
+ input_entries.each_with_index do |input_entry, index|
23
+ test_results.push input_entry.test(input_values[index], variables)
24
+ end
25
+ end
26
+ end
27
+
28
+ def as_json
29
+ {
30
+ id: id,
31
+ input_entries: input_entries.map(&:as_json),
32
+ output_entries: output_entries.map(&:as_json),
33
+ description: description,
34
+ }
35
+ end
36
+
37
+ def output_value(outputs, variables)
38
+ HashWithIndifferentAccess.new.tap do |ov|
39
+ output_entries.each_with_index do |output_entry, index|
40
+ if output_entry.valid?
41
+ val = output_entry.evaluate(variables)
42
+ nested_hash_value(ov, outputs[index].name, val)
43
+ end
44
+ end
45
+ end
46
+ end
47
+
48
+ private
49
+
50
+ def nested_hash_value(hash, key_string, value)
51
+ keys = key_string.split(".")
52
+ current = hash
53
+ keys[0...-1].each do |key|
54
+ current[key] ||= {}
55
+ current = current[key]
56
+ end
57
+ current[keys.last] = value
58
+ hash
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DMN
4
+ class UnaryTests < LiteralExpression
5
+ attr_reader :id, :text
6
+
7
+ def self.from_json(json)
8
+ UnaryTests.new(id: json[:id], text: json[:text])
9
+ end
10
+
11
+ def tree
12
+ @tree ||= Parser.parse_test(text)
13
+ end
14
+
15
+ def valid?
16
+ return true if text.nil? || text == "-"
17
+ tree.present?
18
+ end
19
+
20
+ def test(input, variables = {})
21
+ return true if text.nil? || text == "-"
22
+ tree.eval(functions.merge(variables)).call(input)
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DMN
4
+ class Variable
5
+ attr_reader :id, :name, :type_ref
6
+
7
+ def self.from_json(json)
8
+ Variable.new(id: json[:id], name: json[:name], type_ref: json[:type_ref])
9
+ end
10
+
11
+ def initialize(id:, name:, type_ref:)
12
+ @id = id
13
+ @name = name
14
+ @type_ref = type_ref
15
+ end
16
+
17
+ def as_json
18
+ {
19
+ id: id,
20
+ name: name,
21
+ type_ref: type_ref,
22
+ }
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DMN
4
+ VERSION = "0.0.3"
5
+ end
@@ -1,56 +1,61 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative "spot_feel/version"
4
-
5
- require "awesome_print"
3
+ require_relative "dmn/version"
6
4
 
7
5
  require "active_support"
8
- require "active_support/duration"
9
6
  require "active_support/time"
10
7
  require "active_support/core_ext/hash"
11
- require "active_support/core_ext/object/json"
12
- require "active_support/configurable"
13
8
 
14
9
  require "treetop"
15
10
  require "xmlhasher"
16
11
 
17
- require "spot_feel/configuration"
18
- require "spot_feel/nodes"
19
- require "spot_feel/parser"
12
+ require "dmn/configuration"
13
+ require "dmn/nodes"
14
+ require "dmn/parser"
15
+
16
+ require "dmn/variable"
17
+ require "dmn/literal_expression"
18
+ require "dmn/unary_tests"
19
+ require "dmn/input"
20
+ require "dmn/output"
21
+ require "dmn/rule"
22
+ require "dmn/decision_table"
23
+ require "dmn/information_requirement"
24
+ require "dmn/decision"
25
+ require "dmn/definitions"
20
26
 
21
- require "spot_feel/dmn"
22
27
 
23
- module SpotFeel
28
+ module DMN
24
29
  class SyntaxError < StandardError; end
25
30
  class EvaluationError < StandardError; end
26
31
 
27
32
  def self.evaluate(expression_text, variables: {})
28
- literal_expression = Dmn::LiteralExpression.new(text: expression_text)
33
+ literal_expression = DMN::LiteralExpression.new(text: expression_text)
29
34
  raise SyntaxError, "Expression is not valid" unless literal_expression.valid?
30
35
  literal_expression.evaluate(variables)
31
36
  end
32
37
 
33
38
  def self.test(input, unary_tests_text, variables: {})
34
- unary_tests = Dmn::UnaryTests.new(text: unary_tests_text)
39
+ unary_tests = DMN::UnaryTests.new(text: unary_tests_text)
35
40
  raise SyntaxError, "Unary tests are not valid" unless unary_tests.valid?
36
41
  unary_tests.test(input, variables)
37
42
  end
38
43
 
39
44
  def self.decide(decision_id, definitions: nil, definitions_json: nil, definitions_xml: nil, variables: {})
40
45
  if definitions_xml.present?
41
- definitions = Dmn::Definitions.from_xml(definitions_xml)
46
+ definitions = DMN::Definitions.from_xml(definitions_xml)
42
47
  elsif definitions_json.present?
43
- definitions = Dmn::Definitions.from_json(definitions_json)
48
+ definitions = DMN::Definitions.from_json(definitions_json)
44
49
  end
45
50
  definitions.evaluate(decision_id, variables: variables)
46
51
  end
47
52
 
48
53
  def self.definitions_from_xml(xml)
49
- Dmn::Definitions.from_xml(xml)
54
+ DMN::Definitions.from_xml(xml)
50
55
  end
51
56
 
52
57
  def self.definitions_from_json(json)
53
- Dmn::Definitions.from_json(json)
58
+ DMN::Definitions.from_json(json)
54
59
  end
55
60
 
56
61
  def self.config
metadata CHANGED
@@ -1,14 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dmn
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Connected Bits
8
- autorequire:
9
8
  bindir: bin
10
9
  cert_chain: []
11
- date: 2024-12-30 00:00:00.000000000 Z
10
+ date: 2025-03-03 00:00:00.000000000 Z
12
11
  dependencies:
13
12
  - !ruby/object:Gem::Dependency
14
13
  name: activemodel
@@ -39,33 +38,33 @@ dependencies:
39
38
  - !ruby/object:Gem::Version
40
39
  version: 7.0.2.3
41
40
  - !ruby/object:Gem::Dependency
42
- name: awesome_print
41
+ name: ostruct
43
42
  requirement: !ruby/object:Gem::Requirement
44
43
  requirements:
45
- - - "~>"
44
+ - - ">="
46
45
  - !ruby/object:Gem::Version
47
- version: '1.9'
46
+ version: '0'
48
47
  type: :runtime
49
48
  prerelease: false
50
49
  version_requirements: !ruby/object:Gem::Requirement
51
50
  requirements:
52
- - - "~>"
51
+ - - ">="
53
52
  - !ruby/object:Gem::Version
54
- version: '1.9'
53
+ version: '0'
55
54
  - !ruby/object:Gem::Dependency
56
55
  name: treetop
57
56
  requirement: !ruby/object:Gem::Requirement
58
57
  requirements:
59
- - - ">="
58
+ - - '='
60
59
  - !ruby/object:Gem::Version
61
- version: '0'
60
+ version: 1.6.12
62
61
  type: :runtime
63
62
  prerelease: false
64
63
  version_requirements: !ruby/object:Gem::Requirement
65
64
  requirements:
66
- - - ">="
65
+ - - '='
67
66
  - !ruby/object:Gem::Version
68
- version: '0'
67
+ version: 1.6.12
69
68
  - !ruby/object:Gem::Dependency
70
69
  name: xmlhasher
71
70
  requirement: !ruby/object:Gem::Requirement
@@ -271,30 +270,28 @@ extra_rdoc_files: []
271
270
  files:
272
271
  - README.md
273
272
  - Rakefile
274
- - lib/spot_feel.rb
275
- - lib/spot_feel/configuration.rb
276
- - lib/spot_feel/dmn.rb
277
- - lib/spot_feel/dmn/decision.rb
278
- - lib/spot_feel/dmn/decision_table.rb
279
- - lib/spot_feel/dmn/definitions.rb
280
- - lib/spot_feel/dmn/information_requirement.rb
281
- - lib/spot_feel/dmn/input.rb
282
- - lib/spot_feel/dmn/literal_expression.rb
283
- - lib/spot_feel/dmn/output.rb
284
- - lib/spot_feel/dmn/rule.rb
285
- - lib/spot_feel/dmn/unary_tests.rb
286
- - lib/spot_feel/dmn/variable.rb
287
- - lib/spot_feel/nodes.rb
288
- - lib/spot_feel/parser.rb
289
- - lib/spot_feel/spot_feel.treetop
290
- - lib/spot_feel/version.rb
273
+ - lib/dmn.rb
274
+ - lib/dmn/configuration.rb
275
+ - lib/dmn/decision.rb
276
+ - lib/dmn/decision_table.rb
277
+ - lib/dmn/definitions.rb
278
+ - lib/dmn/dmn.treetop
279
+ - lib/dmn/information_requirement.rb
280
+ - lib/dmn/input.rb
281
+ - lib/dmn/literal_expression.rb
282
+ - lib/dmn/nodes.rb
283
+ - lib/dmn/output.rb
284
+ - lib/dmn/parser.rb
285
+ - lib/dmn/rule.rb
286
+ - lib/dmn/unary_tests.rb
287
+ - lib/dmn/variable.rb
288
+ - lib/dmn/version.rb
291
289
  homepage: https://www.connectedbits.com
292
290
  licenses:
293
291
  - MIT
294
292
  metadata:
295
293
  homepage_uri: https://www.connectedbits.com
296
- source_code_uri: https://github.com/connectedbits/feel
297
- post_install_message:
294
+ source_code_uri: https://github.com/connectedbits/bpmn/feel
298
295
  rdoc_options: []
299
296
  require_paths:
300
297
  - lib
@@ -309,8 +306,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
309
306
  - !ruby/object:Gem::Version
310
307
  version: '0'
311
308
  requirements: []
312
- rubygems_version: 3.4.19
313
- signing_key:
309
+ rubygems_version: 3.6.5
314
310
  specification_version: 4
315
311
  summary: A light-weight DMN FEEL expression evaluator and business rule engine in
316
312
  Ruby.
@@ -1,50 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module SpotFeel
4
- module Dmn
5
- class Decision
6
- attr_reader :id, :name, :decision_table, :variable, :literal_expression, :information_requirements
7
-
8
- def self.from_json(json)
9
- information_requirements = Array.wrap(json[:information_requirement]).map { |ir| InformationRequirement.from_json(ir) } if json[:information_requirement]
10
- decision_table = DecisionTable.from_json(json[:decision_table]) if json[:decision_table]
11
- literal_expression = LiteralExpression.from_json(json[:literal_expression]) if json[:literal_expression]
12
- variable = Variable.from_json(json[:variable]) if json[:variable]
13
- Decision.new(id: json[:id], name: json[:name], decision_table:, variable:, literal_expression:, information_requirements:)
14
- end
15
-
16
- def initialize(id:, name:, decision_table:, variable:, literal_expression:, information_requirements:)
17
- @id = id
18
- @name = name
19
- @decision_table = decision_table
20
- @variable = variable
21
- @literal_expression = literal_expression
22
- @information_requirements = information_requirements
23
- end
24
-
25
- def evaluate(variables = {})
26
- if literal_expression.present?
27
- result = literal_expression.evaluate(variables)
28
- variable.present? ? { variable.name => result } : result
29
- elsif decision_table.present?
30
- decision_table.evaluate(variables)
31
- end
32
- end
33
-
34
- def required_decision_ids
35
- information_requirements&.map(&:required_decision_id)
36
- end
37
-
38
- def as_json
39
- {
40
- id: id,
41
- name: name,
42
- decision_table: decision_table.as_json,
43
- variable: variable.as_json,
44
- literal_expression: literal_expression.as_json,
45
- information_requirements: information_requirements&.map(&:as_json),
46
- }
47
- end
48
- end
49
- end
50
- end
@@ -1,53 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module SpotFeel
4
- module Dmn
5
- class DecisionTable
6
- attr_reader :id, :hit_policy, :inputs, :outputs, :rules
7
-
8
- def self.from_json(json)
9
- inputs = Array.wrap(json[:input]).map { |input| Input.from_json(input) }
10
- outputs = Array.wrap(json[:output]).map { |output| Output.from_json(output) }
11
- rules = Array.wrap(json[:rule]).map { |rule| Rule.from_json(rule) }
12
- DecisionTable.new(id: json[:id], hit_policy: json[:hit_policy], inputs: inputs, outputs: outputs, rules: rules)
13
- end
14
-
15
- def initialize(id:, hit_policy:, inputs:, outputs:, rules:)
16
- @id = id
17
- @hit_policy = hit_policy&.downcase&.to_sym || :unique
18
- @inputs = inputs
19
- @outputs = outputs
20
- @rules = rules
21
- end
22
-
23
- def evaluate(variables = {})
24
- output_values = []
25
-
26
- input_values = inputs.map do |input|
27
- input.input_expression.evaluate(variables)
28
- end
29
-
30
- rules.each do |rule|
31
- results = rule.evaluate(input_values, variables)
32
- if results.all?
33
- output_value = rule.output_value(outputs, variables)
34
- return output_value if hit_policy == :first || hit_policy == :unique
35
- output_values << output_value
36
- end
37
- end
38
-
39
- output_values.empty? ? nil : output_values
40
- end
41
-
42
- def as_json
43
- {
44
- id: id,
45
- hit_policy: hit_policy,
46
- inputs: inputs.map(&:as_json),
47
- outputs: outputs.map(&:as_json),
48
- rules: rules.map(&:as_json),
49
- }
50
- end
51
- end
52
- end
53
- end
@@ -1,68 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module SpotFeel
4
- module Dmn
5
- class Definitions
6
- attr_reader :id, :name, :namespace, :exporter, :exporter_version, :execution_platform, :execution_platform_version
7
- attr_reader :decisions
8
-
9
- def self.from_xml(xml)
10
- XmlHasher.configure do |config|
11
- config.snakecase = true
12
- config.ignore_namespaces = true
13
- config.string_keys = false
14
- end
15
- json = XmlHasher.parse(xml)
16
- Definitions.from_json(json[:definitions])
17
- end
18
-
19
- def self.from_json(json)
20
- decisions = Array.wrap(json[:decision]).map { |decision| Decision.from_json(decision) }
21
- Definitions.new(id: json[:id], name: json[:name], namespace: json[:namespace], exporter: json[:exporter], exporter_version: json[:exporter_version], execution_platform: json[:execution_platform], execution_platform_version: json[:execution_platform_version], decisions: decisions)
22
- end
23
-
24
- def initialize(id:, name:, namespace:, exporter:, exporter_version:, execution_platform:, execution_platform_version:, decisions:)
25
- @id = id
26
- @name = name
27
- @namespace = namespace
28
- @exporter = exporter
29
- @exporter_version = exporter_version
30
- @execution_platform = execution_platform
31
- @execution_platform_version = execution_platform_version
32
- @decisions = decisions
33
- end
34
-
35
- def evaluate(decision_id, variables: {}, already_evaluated_decisions: {})
36
- decision = decisions.find { |d| d.id == decision_id }
37
- raise EvaluationError, "Decision #{decision_id} not found" unless decision
38
-
39
- # Evaluate required decisions recursively
40
- decision.required_decision_ids&.each do |required_decision_id|
41
- next if already_evaluated_decisions[required_decision_id]
42
- next if decisions.find { |d| d.id == required_decision_id }.nil?
43
-
44
- result = evaluate(required_decision_id, variables:, already_evaluated_decisions:)
45
-
46
- variables.merge!(result) if result.is_a?(Hash)
47
-
48
- already_evaluated_decisions[required_decision_id] = true
49
- end
50
-
51
- decision.evaluate(variables)
52
- end
53
-
54
- def as_json
55
- {
56
- id: id,
57
- name: name,
58
- namespace: namespace,
59
- exporter: exporter,
60
- exporter_version: exporter_version,
61
- execution_platform: execution_platform,
62
- execution_platform_version: execution_platform_version,
63
- decisions: decisions.map(&:as_json),
64
- }
65
- end
66
- end
67
- end
68
- end
@@ -1,29 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module SpotFeel
4
- module Dmn
5
- class InformationRequirement
6
- attr_reader :id, :required_input_id, :required_decision_id
7
-
8
- def self.from_json(json)
9
- required_input_id = json[:required_input][:href].delete_prefix("#") if json[:required_input]
10
- required_decision_id = json[:required_decision][:href].delete_prefix("#") if json[:required_decision]
11
- InformationRequirement.new(id: json[:id], required_input_id: required_input_id, required_decision_id: required_decision_id)
12
- end
13
-
14
- def initialize(id:, required_input_id:, required_decision_id:)
15
- @id = id
16
- @required_input_id = required_input_id
17
- @required_decision_id = required_decision_id
18
- end
19
-
20
- def as_json
21
- {
22
- id: id,
23
- required_decision_id: required_decision_id,
24
- required_input_id: required_input_id,
25
- }
26
- end
27
- end
28
- end
29
- end