File: rule_compiler_spec.rb

package info (click to toggle)
ruby-dry-logic 1.2.0-3
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, forky, sid, trixie
  • size: 728 kB
  • sloc: ruby: 4,929; makefile: 6
file content (129 lines) | stat: -rw-r--r-- 3,188 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
# frozen_string_literal: true

require "dry/logic/rule_compiler"

RSpec.describe Dry::Logic::RuleCompiler, "#call" do
  subject(:compiler) { described_class.new(predicates) }

  let(:predicates) {
    {key?: predicate,
     attr?: predicate,
     filled?: predicate,
     gt?: predicate,
     one: predicate}
  }

  let(:predicate) { double(:predicate, name: :test?, arity: 2).as_null_object }

  let(:rule) { Dry::Logic::Rule::Predicate.build(predicate) }
  let(:key_op) { Dry::Logic::Operations::Key.new(rule, name: :email) }
  let(:attr_op) { Dry::Logic::Operations::Attr.new(rule, name: :email) }
  let(:check_op) { Dry::Logic::Operations::Check.new(rule, keys: [:email]) }
  let(:not_key_op) { Dry::Logic::Operations::Negation.new(key_op) }
  let(:and_op) { key_op.curry(:email) & rule }
  let(:or_op) { key_op.curry(:email) | rule }
  let(:xor_op) { key_op.curry(:email) ^ rule }
  let(:set_op) { Dry::Logic::Operations::Set.new(rule) }
  let(:each_op) { Dry::Logic::Operations::Each.new(rule) }

  it "compiles key rules" do
    ast = [[:key, [:email, [:predicate, [:filled?, [[:input, undefined]]]]]]]

    rules = compiler.(ast)

    expect(rules).to eql([key_op])
  end

  it "compiles attr rules" do
    ast = [[:attr, [:email, [:predicate, [:filled?, [[:input, undefined]]]]]]]

    rules = compiler.(ast)

    expect(rules).to eql([attr_op])
  end

  it "compiles check rules" do
    ast = [[:check, [[:email], [:predicate, [:filled?, [[:input, undefined]]]]]]]

    rules = compiler.(ast)

    expect(rules).to eql([check_op])
  end

  it "compiles attr rules" do
    ast = [[:attr, [:email, [:predicate, [:filled?, [[:input, undefined]]]]]]]

    rules = compiler.(ast)

    expect(rules).to eql([attr_op])
  end

  it "compiles negated rules" do
    ast = [[:not, [:key, [:email, [:predicate, [:filled?, [[:input, undefined]]]]]]]]

    rules = compiler.(ast)

    expect(rules).to eql([not_key_op])
  end

  it "compiles and rules" do
    ast = [
      [
        :and, [
          [:key, [:email, [:predicate, [:key?, [[:name, :email], [:input, undefined]]]]]],
          [:predicate, [:filled?, [[:input, undefined]]]]
        ]
      ]
    ]

    rules = compiler.(ast)

    expect(rules).to eql([and_op])
  end

  it "compiles or rules" do
    ast = [
      [
        :or, [
          [:key, [:email, [:predicate, [:key?, [[:name, :email], [:input, undefined]]]]]],
          [:predicate, [:filled?, [[:input, undefined]]]]
        ]
      ]
    ]

    rules = compiler.(ast)

    expect(rules).to eql([or_op])
  end

  it "compiles exclusive or rules" do
    ast = [
      [
        :xor, [
          [:key, [:email, [:predicate, [:key?, [[:name, :email], [:input, undefined]]]]]],
          [:predicate, [:filled?, [[:input, undefined]]]]
        ]
      ]
    ]

    rules = compiler.(ast)

    expect(rules).to eql([xor_op])
  end

  it "compiles set rules" do
    ast = [[:set, [[:predicate, [:filled?, [[:input, nil]]]]]]]

    rules = compiler.(ast)

    expect(rules).to eql([set_op])
  end

  it "compiles each rules" do
    ast = [[:each, [:predicate, [:filled?, [[:input, nil]]]]]]

    rules = compiler.(ast)

    expect(rules).to eql([each_op])
  end
end