factbase 0.4.0 → 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.0pdd.yml +1 -1
- data/.github/workflows/actionlint.yml +1 -1
- data/.github/workflows/benchmark.yml +64 -0
- data/.github/workflows/codecov.yml +4 -2
- data/.github/workflows/copyrights.yml +2 -2
- data/.github/workflows/markdown-lint.yml +1 -1
- data/.github/workflows/pdd.yml +1 -1
- data/.github/workflows/rake.yml +2 -2
- data/.github/workflows/xcop.yml +1 -1
- data/.github/workflows/yamllint.yml +1 -1
- data/.gitignore +1 -1
- data/.rubocop.yml +6 -1
- data/.rultor.yml +2 -2
- data/.simplecov +1 -1
- data/.yamllint.yml +9 -4
- data/Gemfile +9 -7
- data/Gemfile.lock +99 -78
- data/LICENSE.txt +1 -1
- data/README.md +33 -0
- data/Rakefile +6 -1
- data/benchmarks/simple.rb +96 -0
- data/factbase.gemspec +1 -1
- data/lib/factbase/accum.rb +2 -2
- data/lib/factbase/fact.rb +6 -4
- data/lib/factbase/flatten.rb +2 -2
- data/lib/factbase/inv.rb +2 -2
- data/lib/factbase/looged.rb +6 -5
- data/lib/factbase/pre.rb +2 -2
- data/lib/factbase/query.rb +16 -8
- data/lib/factbase/query_once.rb +71 -0
- data/lib/factbase/rules.rb +3 -3
- data/lib/factbase/syntax.rb +13 -8
- data/lib/factbase/tee.rb +2 -2
- data/lib/factbase/term.rb +33 -5
- data/lib/factbase/term_once.rb +84 -0
- data/lib/factbase/terms/aggregates.rb +4 -4
- data/lib/factbase/terms/aliases.rb +5 -5
- data/lib/factbase/terms/casting.rb +2 -2
- data/lib/factbase/terms/debug.rb +2 -2
- data/lib/factbase/terms/defn.rb +2 -2
- data/lib/factbase/terms/logical.rb +3 -3
- data/lib/factbase/terms/math.rb +2 -2
- data/lib/factbase/terms/meta.rb +2 -2
- data/lib/factbase/terms/ordering.rb +2 -2
- data/lib/factbase/terms/strings.rb +2 -2
- data/lib/factbase/terms/system.rb +2 -2
- data/lib/factbase/to_json.rb +2 -2
- data/lib/factbase/to_xml.rb +2 -2
- data/lib/factbase/to_yaml.rb +2 -2
- data/lib/factbase.rb +16 -6
- data/test/factbase/terms/test_aggregates.rb +6 -6
- data/test/factbase/terms/test_aliases.rb +6 -6
- data/test/factbase/terms/test_casting.rb +6 -6
- data/test/factbase/terms/test_debug.rb +53 -0
- data/test/factbase/terms/test_defn.rb +15 -15
- data/test/factbase/terms/test_logical.rb +15 -13
- data/test/factbase/terms/test_math.rb +42 -42
- data/test/factbase/terms/test_meta.rb +87 -0
- data/test/factbase/terms/test_ordering.rb +45 -0
- data/test/factbase/terms/test_strings.rb +8 -8
- data/test/factbase/terms/test_system.rb +6 -6
- data/test/factbase/test_accum.rb +9 -9
- data/test/factbase/test_fact.rb +22 -22
- data/test/factbase/test_flatten.rb +6 -6
- data/test/factbase/test_inv.rb +3 -3
- data/test/factbase/test_looged.rb +13 -13
- data/test/factbase/test_pre.rb +2 -2
- data/test/factbase/test_query.rb +17 -17
- data/test/factbase/test_rules.rb +8 -8
- data/test/factbase/test_syntax.rb +29 -9
- data/test/factbase/test_tee.rb +11 -11
- data/test/factbase/test_term.rb +18 -18
- data/test/factbase/test_to_json.rb +4 -4
- data/test/factbase/test_to_xml.rb +12 -14
- data/test/factbase/test_to_yaml.rb +3 -3
- data/test/test__helper.rb +2 -2
- data/test/test_factbase.rb +198 -18
- metadata +12 -5
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
# Copyright (c) 2024 Yegor Bugayenko
|
3
|
+
# Copyright (c) 2024-2025 Yegor Bugayenko
|
4
4
|
#
|
5
5
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
6
|
# of this software and associated documentation files (the 'Software'), to deal
|
@@ -25,48 +25,50 @@ require_relative '../../../lib/factbase/term'
|
|
25
25
|
|
26
26
|
# Logical test.
|
27
27
|
# Author:: Yegor Bugayenko (yegor256@gmail.com)
|
28
|
-
# Copyright:: Copyright (c) 2024 Yegor Bugayenko
|
28
|
+
# Copyright:: Copyright (c) 2024-2025 Yegor Bugayenko
|
29
29
|
# License:: MIT
|
30
30
|
class TestLogical < Minitest::Test
|
31
31
|
def test_not_matching
|
32
|
-
t = Factbase::Term.new(:not, [Factbase::Term.new(:always, [])])
|
33
|
-
|
32
|
+
t = Factbase::Term.new(Factbase.new, :not, [Factbase::Term.new(Factbase.new, :always, [])])
|
33
|
+
refute(t.evaluate(fact('foo' => [100]), []))
|
34
34
|
end
|
35
35
|
|
36
36
|
def test_not_eq_matching
|
37
|
-
t = Factbase::Term.new(:not, [Factbase::Term.new(:eq, [:foo, 100])])
|
37
|
+
t = Factbase::Term.new(Factbase.new, :not, [Factbase::Term.new(Factbase.new, :eq, [:foo, 100])])
|
38
38
|
assert(t.evaluate(fact('foo' => [42, 12, -90]), []))
|
39
|
-
|
39
|
+
refute(t.evaluate(fact('foo' => 100), []))
|
40
40
|
end
|
41
41
|
|
42
42
|
def test_either
|
43
|
-
t = Factbase::Term.new(:either, [Factbase::Term.new(:at, [5, :foo]), 42])
|
43
|
+
t = Factbase::Term.new(Factbase.new, :either, [Factbase::Term.new(Factbase.new, :at, [5, :foo]), 42])
|
44
44
|
assert_equal([42], t.evaluate(fact('foo' => 4), []))
|
45
45
|
end
|
46
46
|
|
47
47
|
def test_or_matching
|
48
48
|
t = Factbase::Term.new(
|
49
|
+
Factbase.new,
|
49
50
|
:or,
|
50
51
|
[
|
51
|
-
Factbase::Term.new(:eq, [:foo, 4]),
|
52
|
-
Factbase::Term.new(:eq, [:bar, 5])
|
52
|
+
Factbase::Term.new(Factbase.new, :eq, [:foo, 4]),
|
53
|
+
Factbase::Term.new(Factbase.new, :eq, [:bar, 5])
|
53
54
|
]
|
54
55
|
)
|
55
56
|
assert(t.evaluate(fact('foo' => [4]), []))
|
56
57
|
assert(t.evaluate(fact('bar' => [5]), []))
|
57
|
-
|
58
|
+
refute(t.evaluate(fact('bar' => [42]), []))
|
58
59
|
end
|
59
60
|
|
60
61
|
def test_when_matching
|
61
62
|
t = Factbase::Term.new(
|
63
|
+
Factbase.new,
|
62
64
|
:when,
|
63
65
|
[
|
64
|
-
Factbase::Term.new(:eq, [:foo, 4]),
|
65
|
-
Factbase::Term.new(:eq, [:bar, 5])
|
66
|
+
Factbase::Term.new(Factbase.new, :eq, [:foo, 4]),
|
67
|
+
Factbase::Term.new(Factbase.new, :eq, [:bar, 5])
|
66
68
|
]
|
67
69
|
)
|
68
70
|
assert(t.evaluate(fact('foo' => 4, 'bar' => 5), []))
|
69
|
-
|
71
|
+
refute(t.evaluate(fact('foo' => 4), []))
|
70
72
|
assert(t.evaluate(fact('foo' => 5, 'bar' => 5), []))
|
71
73
|
end
|
72
74
|
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
# Copyright (c) 2024 Yegor Bugayenko
|
3
|
+
# Copyright (c) 2024-2025 Yegor Bugayenko
|
4
4
|
#
|
5
5
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
6
|
# of this software and associated documentation files (the 'Software'), to deal
|
@@ -26,113 +26,113 @@ require_relative '../../../lib/factbase/term'
|
|
26
26
|
|
27
27
|
# Math test.
|
28
28
|
# Author:: Yegor Bugayenko (yegor256@gmail.com)
|
29
|
-
# Copyright:: Copyright (c) 2024 Yegor Bugayenko
|
29
|
+
# Copyright:: Copyright (c) 2024-2025 Yegor Bugayenko
|
30
30
|
# License:: MIT
|
31
31
|
class TestMath < Minitest::Test
|
32
32
|
def test_simple
|
33
|
-
t = Factbase::Term.new(:eq, [:foo, 42])
|
33
|
+
t = Factbase::Term.new(Factbase.new, :eq, [:foo, 42])
|
34
34
|
assert(t.evaluate(fact('foo' => [42]), []))
|
35
|
-
|
36
|
-
|
35
|
+
refute(t.evaluate(fact('foo' => 'Hello!'), []))
|
36
|
+
refute(t.evaluate(fact('bar' => ['Hello!']), []))
|
37
37
|
end
|
38
38
|
|
39
39
|
def test_zero
|
40
|
-
t = Factbase::Term.new(:zero, [:foo])
|
40
|
+
t = Factbase::Term.new(Factbase.new, :zero, [:foo])
|
41
41
|
assert(t.evaluate(fact('foo' => [0]), []))
|
42
42
|
assert(t.evaluate(fact('foo' => [10, 5, 6, -8, 'hey', 0, 9, 'fdsf']), []))
|
43
|
-
|
44
|
-
|
45
|
-
|
43
|
+
refute(t.evaluate(fact('foo' => [100]), []))
|
44
|
+
refute(t.evaluate(fact('foo' => []), []))
|
45
|
+
refute(t.evaluate(fact('bar' => []), []))
|
46
46
|
end
|
47
47
|
|
48
48
|
def test_eq
|
49
|
-
t = Factbase::Term.new(:eq, [:foo, 42])
|
49
|
+
t = Factbase::Term.new(Factbase.new, :eq, [:foo, 42])
|
50
50
|
assert(t.evaluate(fact('foo' => 42), []))
|
51
51
|
assert(t.evaluate(fact('foo' => [10, 5, 6, -8, 'hey', 42, 9, 'fdsf']), []))
|
52
|
-
|
53
|
-
|
54
|
-
|
52
|
+
refute(t.evaluate(fact('foo' => [100]), []))
|
53
|
+
refute(t.evaluate(fact('foo' => []), []))
|
54
|
+
refute(t.evaluate(fact('bar' => []), []))
|
55
55
|
end
|
56
56
|
|
57
57
|
def test_eq_time
|
58
58
|
now = Time.now
|
59
|
-
t = Factbase::Term.new(:eq, [:foo, Time.parse(now.iso8601)])
|
59
|
+
t = Factbase::Term.new(Factbase.new, :eq, [:foo, Time.parse(now.iso8601)])
|
60
60
|
assert(t.evaluate(fact('foo' => now), []))
|
61
61
|
assert(t.evaluate(fact('foo' => [now, Time.now]), []))
|
62
62
|
end
|
63
63
|
|
64
64
|
def test_lt
|
65
|
-
t = Factbase::Term.new(:lt, [:foo, 42])
|
65
|
+
t = Factbase::Term.new(Factbase.new, :lt, [:foo, 42])
|
66
66
|
assert(t.evaluate(fact('foo' => [10]), []))
|
67
|
-
|
68
|
-
|
69
|
-
|
67
|
+
refute(t.evaluate(fact('foo' => [100]), []))
|
68
|
+
refute(t.evaluate(fact('foo' => 100), []))
|
69
|
+
refute(t.evaluate(fact('bar' => 100), []))
|
70
70
|
end
|
71
71
|
|
72
72
|
def test_gte
|
73
|
-
t = Factbase::Term.new(:gte, [:foo, 42])
|
73
|
+
t = Factbase::Term.new(Factbase.new, :gte, [:foo, 42])
|
74
74
|
assert(t.evaluate(fact('foo' => 100), []))
|
75
75
|
assert(t.evaluate(fact('foo' => 42), []))
|
76
|
-
|
76
|
+
refute(t.evaluate(fact('foo' => 41), []))
|
77
77
|
end
|
78
78
|
|
79
79
|
def test_lte
|
80
|
-
t = Factbase::Term.new(:lte, [:foo, 42])
|
80
|
+
t = Factbase::Term.new(Factbase.new, :lte, [:foo, 42])
|
81
81
|
assert(t.evaluate(fact('foo' => 41), []))
|
82
82
|
assert(t.evaluate(fact('foo' => 42), []))
|
83
|
-
|
83
|
+
refute(t.evaluate(fact('foo' => 100), []))
|
84
84
|
end
|
85
85
|
|
86
86
|
def test_gt
|
87
|
-
t = Factbase::Term.new(:gt, [:foo, 42])
|
87
|
+
t = Factbase::Term.new(Factbase.new, :gt, [:foo, 42])
|
88
88
|
assert(t.evaluate(fact('foo' => [100]), []))
|
89
89
|
assert(t.evaluate(fact('foo' => 100), []))
|
90
|
-
|
91
|
-
|
92
|
-
|
90
|
+
refute(t.evaluate(fact('foo' => [10]), []))
|
91
|
+
refute(t.evaluate(fact('foo' => 10), []))
|
92
|
+
refute(t.evaluate(fact('bar' => 10), []))
|
93
93
|
end
|
94
94
|
|
95
95
|
def test_lt_time
|
96
|
-
t = Factbase::Term.new(:lt, [:foo, Time.now])
|
96
|
+
t = Factbase::Term.new(Factbase.new, :lt, [:foo, Time.now])
|
97
97
|
assert(t.evaluate(fact('foo' => [Time.now - 100]), []))
|
98
|
-
|
99
|
-
|
98
|
+
refute(t.evaluate(fact('foo' => [Time.now + 100]), []))
|
99
|
+
refute(t.evaluate(fact('bar' => [100]), []))
|
100
100
|
end
|
101
101
|
|
102
102
|
def test_gt_time
|
103
|
-
t = Factbase::Term.new(:gt, [:foo, Time.now])
|
103
|
+
t = Factbase::Term.new(Factbase.new, :gt, [:foo, Time.now])
|
104
104
|
assert(t.evaluate(fact('foo' => [Time.now + 100]), []))
|
105
|
-
|
106
|
-
|
105
|
+
refute(t.evaluate(fact('foo' => [Time.now - 100]), []))
|
106
|
+
refute(t.evaluate(fact('bar' => [100]), []))
|
107
107
|
end
|
108
108
|
|
109
109
|
def test_plus
|
110
|
-
t = Factbase::Term.new(:plus, [:foo, 42])
|
110
|
+
t = Factbase::Term.new(Factbase.new, :plus, [:foo, 42])
|
111
111
|
assert_equal(46, t.evaluate(fact('foo' => 4), []))
|
112
|
-
|
112
|
+
assert_nil(t.evaluate(fact, []))
|
113
113
|
end
|
114
114
|
|
115
115
|
def test_plus_time
|
116
|
-
t = Factbase::Term.new(:plus, [:foo, '12 days'])
|
116
|
+
t = Factbase::Term.new(Factbase.new, :plus, [:foo, '12 days'])
|
117
117
|
assert_equal(Time.parse('2024-01-13'), t.evaluate(fact('foo' => Time.parse('2024-01-01')), []))
|
118
|
-
|
118
|
+
assert_nil(t.evaluate(fact, []))
|
119
119
|
end
|
120
120
|
|
121
121
|
def test_minus
|
122
|
-
t = Factbase::Term.new(:minus, [:foo, 42])
|
122
|
+
t = Factbase::Term.new(Factbase.new, :minus, [:foo, 42])
|
123
123
|
assert_equal(58, t.evaluate(fact('foo' => 100), []))
|
124
|
-
|
124
|
+
assert_nil(t.evaluate(fact, []))
|
125
125
|
end
|
126
126
|
|
127
127
|
def test_minus_time
|
128
|
-
t = Factbase::Term.new(:minus, [:foo, '4 hours'])
|
128
|
+
t = Factbase::Term.new(Factbase.new, :minus, [:foo, '4 hours'])
|
129
129
|
assert_equal(Time.parse('2024-01-01T06:04'), t.evaluate(fact('foo' => Time.parse('2024-01-01T10:04')), []))
|
130
|
-
|
130
|
+
assert_nil(t.evaluate(fact, []))
|
131
131
|
end
|
132
132
|
|
133
133
|
def test_minus_time_singular
|
134
|
-
t = Factbase::Term.new(:minus, [:foo, '1 hour'])
|
134
|
+
t = Factbase::Term.new(Factbase.new, :minus, [:foo, '1 hour'])
|
135
135
|
assert_equal(Time.parse('2024-01-01T09:04'), t.evaluate(fact('foo' => Time.parse('2024-01-01T10:04')), []))
|
136
|
-
|
136
|
+
assert_nil(t.evaluate(fact, []))
|
137
137
|
end
|
138
138
|
end
|
@@ -0,0 +1,87 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Copyright (c) 2024-2025 Yegor Bugayenko
|
4
|
+
#
|
5
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
# of this software and associated documentation files (the 'Software'), to deal
|
7
|
+
# in the Software without restriction, including without limitation the rights
|
8
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
# copies of the Software, and to permit persons to whom the Software is
|
10
|
+
# furnished to do so, subject to the following conditions:
|
11
|
+
#
|
12
|
+
# The above copyright notice and this permission notice shall be included in all
|
13
|
+
# copies or substantial portions of the Software.
|
14
|
+
#
|
15
|
+
# THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
21
|
+
# SOFTWARE.
|
22
|
+
|
23
|
+
require 'minitest/autorun'
|
24
|
+
require_relative '../../../lib/factbase/term'
|
25
|
+
|
26
|
+
# Meta test.
|
27
|
+
# Author:: Yegor Bugayenko (yegor256@gmail.com)
|
28
|
+
# Copyright:: Copyright (c) 2024-2025 Yegor Bugayenko
|
29
|
+
# License:: MIT
|
30
|
+
class TestMeta < Minitest::Test
|
31
|
+
def test_exists
|
32
|
+
t = Factbase::Term.new(Factbase.new, :exists, [:foo])
|
33
|
+
assert(t.evaluate(fact('foo' => 41), []))
|
34
|
+
refute(t.evaluate(fact('bar' => 41), []))
|
35
|
+
end
|
36
|
+
|
37
|
+
def test_absent
|
38
|
+
t = Factbase::Term.new(Factbase.new, :absent, [:foo])
|
39
|
+
refute(t.evaluate(fact('foo' => 41), []))
|
40
|
+
assert(t.evaluate(fact('bar' => 41), []))
|
41
|
+
end
|
42
|
+
|
43
|
+
def test_size
|
44
|
+
t = Factbase::Term.new(Factbase.new, :size, [:foo])
|
45
|
+
assert_equal(1, t.evaluate(fact('foo' => 41), []))
|
46
|
+
assert_equal(0, t.evaluate(fact('foo' => nil), []))
|
47
|
+
assert_equal(4, t.evaluate(fact('foo' => [1, 2, 3, 4]), []))
|
48
|
+
assert_equal(0, t.evaluate(fact('foo' => []), []))
|
49
|
+
assert_equal(1, t.evaluate(fact('foo' => ''), []))
|
50
|
+
end
|
51
|
+
|
52
|
+
def test_type
|
53
|
+
t = Factbase::Term.new(Factbase.new, :type, [:foo])
|
54
|
+
assert_equal('nil', t.evaluate(fact('foo' => nil), []))
|
55
|
+
assert_equal('Integer', t.evaluate(fact('foo' => [1]), []))
|
56
|
+
assert_equal('Array', t.evaluate(fact('foo' => [1, 2]), []))
|
57
|
+
assert_equal('String', t.evaluate(fact('foo' => 'bar'), []))
|
58
|
+
assert_equal('Float', t.evaluate(fact('foo' => 2.1), []))
|
59
|
+
assert_equal('Time', t.evaluate(fact('foo' => Time.now), []))
|
60
|
+
end
|
61
|
+
|
62
|
+
def test_nil
|
63
|
+
t = Factbase::Term.new(Factbase.new, :nil, [:foo])
|
64
|
+
assert(t.evaluate(fact('foo' => nil), []))
|
65
|
+
refute(t.evaluate(fact('foo' => true), []))
|
66
|
+
refute(t.evaluate(fact('foo' => 'bar'), []))
|
67
|
+
end
|
68
|
+
|
69
|
+
def test_many
|
70
|
+
t = Factbase::Term.new(Factbase.new, :many, [:foo])
|
71
|
+
refute(t.evaluate(fact('foo' => nil), []))
|
72
|
+
refute(t.evaluate(fact('foo' => 1), []))
|
73
|
+
refute(t.evaluate(fact('foo' => '1234'), []))
|
74
|
+
assert(t.evaluate(fact('foo' => [1, 3, 5]), []))
|
75
|
+
refute(t.evaluate(fact('foo' => []), []))
|
76
|
+
end
|
77
|
+
|
78
|
+
def test_one
|
79
|
+
t = Factbase::Term.new(Factbase.new, :one, [:foo])
|
80
|
+
assert(t.evaluate(fact('foo' => 1), []))
|
81
|
+
assert(t.evaluate(fact('foo' => '1234'), []))
|
82
|
+
assert(t.evaluate(fact('foo' => [1]), []))
|
83
|
+
refute(t.evaluate(fact('foo' => nil), []))
|
84
|
+
refute(t.evaluate(fact('foo' => [1, 3, 5]), []))
|
85
|
+
refute(t.evaluate(fact('foo' => []), []))
|
86
|
+
end
|
87
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Copyright (c) 2024-2025 Yegor Bugayenko
|
4
|
+
#
|
5
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
# of this software and associated documentation files (the 'Software'), to deal
|
7
|
+
# in the Software without restriction, including without limitation the rights
|
8
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
# copies of the Software, and to permit persons to whom the Software is
|
10
|
+
# furnished to do so, subject to the following conditions:
|
11
|
+
#
|
12
|
+
# The above copyright notice and this permission notice shall be included in all
|
13
|
+
# copies or substantial portions of the Software.
|
14
|
+
#
|
15
|
+
# THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
21
|
+
# SOFTWARE.
|
22
|
+
|
23
|
+
require 'minitest/autorun'
|
24
|
+
require_relative '../../../lib/factbase/term'
|
25
|
+
|
26
|
+
# Ordering test.
|
27
|
+
# Author:: Yegor Bugayenko (yegor256@gmail.com)
|
28
|
+
# Copyright:: Copyright (c) 2024-2025 Yegor Bugayenko
|
29
|
+
# License:: MIT
|
30
|
+
class TestOrdering < Minitest::Test
|
31
|
+
def test_prev
|
32
|
+
t = Factbase::Term.new(Factbase.new, :prev, [:foo])
|
33
|
+
assert_nil(t.evaluate(fact('foo' => 41), []))
|
34
|
+
assert_equal([41], t.evaluate(fact('foo' => 5), []))
|
35
|
+
assert_equal([5], t.evaluate(fact('foo' => 6), []))
|
36
|
+
end
|
37
|
+
|
38
|
+
def test_unique
|
39
|
+
t = Factbase::Term.new(Factbase.new, :unique, [:foo])
|
40
|
+
refute(t.evaluate(fact, []))
|
41
|
+
assert(t.evaluate(fact('foo' => 41), []))
|
42
|
+
refute(t.evaluate(fact('foo' => 41), []))
|
43
|
+
assert(t.evaluate(fact('foo' => 1), []))
|
44
|
+
end
|
45
|
+
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
# Copyright (c) 2024 Yegor Bugayenko
|
3
|
+
# Copyright (c) 2024-2025 Yegor Bugayenko
|
4
4
|
#
|
5
5
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
6
|
# of this software and associated documentation files (the 'Software'), to deal
|
@@ -25,29 +25,29 @@ require_relative '../../../lib/factbase/term'
|
|
25
25
|
|
26
26
|
# Strings test.
|
27
27
|
# Author:: Yegor Bugayenko (yegor256@gmail.com)
|
28
|
-
# Copyright:: Copyright (c) 2024 Yegor Bugayenko
|
28
|
+
# Copyright:: Copyright (c) 2024-2025 Yegor Bugayenko
|
29
29
|
# License:: MIT
|
30
30
|
class TestStrings < Minitest::Test
|
31
31
|
def test_regexp_matching
|
32
|
-
t = Factbase::Term.new(:matches, [:foo, '[a-z]+'])
|
32
|
+
t = Factbase::Term.new(Factbase.new, :matches, [:foo, '[a-z]+'])
|
33
33
|
assert(t.evaluate(fact('foo' => 'hello'), []))
|
34
34
|
assert(t.evaluate(fact('foo' => 'hello 42'), []))
|
35
|
-
|
35
|
+
refute(t.evaluate(fact('foo' => 42), []))
|
36
36
|
end
|
37
37
|
|
38
38
|
def test_concat
|
39
|
-
t = Factbase::Term.new(:concat, [42, 'hi', 3.14, :hey, Time.now])
|
39
|
+
t = Factbase::Term.new(Factbase.new, :concat, [42, 'hi', 3.14, :hey, Time.now])
|
40
40
|
s = t.evaluate(fact, [])
|
41
|
-
assert(s.start_with?('42hi3.14')
|
41
|
+
assert(s.start_with?('42hi3.14'))
|
42
42
|
end
|
43
43
|
|
44
44
|
def test_concat_empty
|
45
|
-
t = Factbase::Term.new(:concat, [])
|
45
|
+
t = Factbase::Term.new(Factbase.new, :concat, [])
|
46
46
|
assert_equal('', t.evaluate(fact, []))
|
47
47
|
end
|
48
48
|
|
49
49
|
def test_sprintf
|
50
|
-
t = Factbase::Term.new(:sprintf, ['hi, %s!', 'Jeff'])
|
50
|
+
t = Factbase::Term.new(Factbase.new, :sprintf, ['hi, %s!', 'Jeff'])
|
51
51
|
assert_equal('hi, Jeff!', t.evaluate(fact, []))
|
52
52
|
end
|
53
53
|
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
# Copyright (c) 2024 Yegor Bugayenko
|
3
|
+
# Copyright (c) 2024-2025 Yegor Bugayenko
|
4
4
|
#
|
5
5
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
6
|
# of this software and associated documentation files (the 'Software'), to deal
|
@@ -26,24 +26,24 @@ require_relative '../../../lib/factbase/term'
|
|
26
26
|
|
27
27
|
# System test.
|
28
28
|
# Author:: Yegor Bugayenko (yegor256@gmail.com)
|
29
|
-
# Copyright:: Copyright (c) 2024 Yegor Bugayenko
|
29
|
+
# Copyright:: Copyright (c) 2024-2025 Yegor Bugayenko
|
30
30
|
# License:: MIT
|
31
31
|
class TestSystem < Minitest::Test
|
32
32
|
def test_env
|
33
33
|
ENV.store('FOO', 'bar')
|
34
|
-
t = Factbase::Term.new(:env, ['FOO', ''])
|
34
|
+
t = Factbase::Term.new(Factbase.new, :env, ['FOO', ''])
|
35
35
|
assert_equal('bar', t.evaluate(fact, []))
|
36
36
|
end
|
37
37
|
|
38
38
|
def test_default
|
39
39
|
ENV.delete('FOO')
|
40
|
-
t = Factbase::Term.new(:env, ['FOO', 'мой друг'])
|
40
|
+
t = Factbase::Term.new(Factbase.new, :env, ['FOO', 'мой друг'])
|
41
41
|
assert_equal('мой друг', t.evaluate(fact, []))
|
42
42
|
end
|
43
43
|
|
44
44
|
def test_when_default_is_absent
|
45
45
|
ENV.delete('FOO')
|
46
|
-
t = Factbase::Term.new(:env, ['FOO'])
|
47
|
-
assert_raises { t.evaluate(fact, []) }
|
46
|
+
t = Factbase::Term.new(Factbase.new, :env, ['FOO'])
|
47
|
+
assert_raises(StandardError) { t.evaluate(fact, []) }
|
48
48
|
end
|
49
49
|
end
|
data/test/factbase/test_accum.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
# Copyright (c) 2024 Yegor Bugayenko
|
3
|
+
# Copyright (c) 2024-2025 Yegor Bugayenko
|
4
4
|
#
|
5
5
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
6
|
# of this software and associated documentation files (the 'Software'), to deal
|
@@ -27,23 +27,23 @@ require_relative '../../lib/factbase/fact'
|
|
27
27
|
|
28
28
|
# Accum test.
|
29
29
|
# Author:: Yegor Bugayenko (yegor256@gmail.com)
|
30
|
-
# Copyright:: Copyright (c) 2024 Yegor Bugayenko
|
30
|
+
# Copyright:: Copyright (c) 2024-2025 Yegor Bugayenko
|
31
31
|
# License:: MIT
|
32
32
|
class TestAccum < Minitest::Test
|
33
33
|
def test_holds_props
|
34
34
|
map = {}
|
35
|
-
f = Factbase::Fact.new(Mutex.new, map)
|
35
|
+
f = Factbase::Fact.new(Factbase.new, Mutex.new, map)
|
36
36
|
props = {}
|
37
37
|
a = Factbase::Accum.new(f, props, false)
|
38
38
|
a.foo = 42
|
39
|
-
assert_raises { f.foo }
|
39
|
+
assert_raises(StandardError) { f.foo }
|
40
40
|
assert_equal(42, a.foo)
|
41
41
|
assert_equal([42], props['foo'])
|
42
42
|
end
|
43
43
|
|
44
44
|
def test_passes_props
|
45
45
|
map = {}
|
46
|
-
f = Factbase::Fact.new(Mutex.new, map)
|
46
|
+
f = Factbase::Fact.new(Factbase.new, Mutex.new, map)
|
47
47
|
props = {}
|
48
48
|
a = Factbase::Accum.new(f, props, true)
|
49
49
|
a.foo = 42
|
@@ -54,7 +54,7 @@ class TestAccum < Minitest::Test
|
|
54
54
|
|
55
55
|
def test_appends_props
|
56
56
|
map = {}
|
57
|
-
f = Factbase::Fact.new(Mutex.new, map)
|
57
|
+
f = Factbase::Fact.new(Factbase.new, Mutex.new, map)
|
58
58
|
f.foo = 42
|
59
59
|
props = {}
|
60
60
|
a = Factbase::Accum.new(f, props, false)
|
@@ -63,14 +63,14 @@ class TestAccum < Minitest::Test
|
|
63
63
|
end
|
64
64
|
|
65
65
|
def test_empties
|
66
|
-
f = Factbase::Fact.new(Mutex.new, {})
|
66
|
+
f = Factbase::Fact.new(Factbase.new, Mutex.new, {})
|
67
67
|
a = Factbase::Accum.new(f, {}, false)
|
68
|
-
|
68
|
+
assert_nil(a['foo'])
|
69
69
|
end
|
70
70
|
|
71
71
|
def test_prints_to_string
|
72
72
|
map = {}
|
73
|
-
f = Factbase::Fact.new(Mutex.new, map)
|
73
|
+
f = Factbase::Fact.new(Factbase.new, Mutex.new, map)
|
74
74
|
props = {}
|
75
75
|
a = Factbase::Accum.new(f, props, true)
|
76
76
|
a.foo = 42
|
data/test/factbase/test_fact.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
# Copyright (c) 2024 Yegor Bugayenko
|
3
|
+
# Copyright (c) 2024-2025 Yegor Bugayenko
|
4
4
|
#
|
5
5
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
6
|
# of this software and associated documentation files (the 'Software'), to deal
|
@@ -26,12 +26,12 @@ require_relative '../../lib/factbase/fact'
|
|
26
26
|
|
27
27
|
# Fact test.
|
28
28
|
# Author:: Yegor Bugayenko (yegor256@gmail.com)
|
29
|
-
# Copyright:: Copyright (c) 2024 Yegor Bugayenko
|
29
|
+
# Copyright:: Copyright (c) 2024-2025 Yegor Bugayenko
|
30
30
|
# License:: MIT
|
31
31
|
class TestFact < Minitest::Test
|
32
32
|
def test_injects_data_correctly
|
33
33
|
map = {}
|
34
|
-
f = Factbase::Fact.new(Mutex.new, map)
|
34
|
+
f = Factbase::Fact.new(Factbase.new, Mutex.new, map)
|
35
35
|
f.foo = 1
|
36
36
|
f.bar = 2
|
37
37
|
f.bar = 3
|
@@ -42,7 +42,7 @@ class TestFact < Minitest::Test
|
|
42
42
|
|
43
43
|
def test_simple_resetting
|
44
44
|
map = {}
|
45
|
-
f = Factbase::Fact.new(Mutex.new, map)
|
45
|
+
f = Factbase::Fact.new(Factbase.new, Mutex.new, map)
|
46
46
|
f.foo = 42
|
47
47
|
assert_equal(42, f.foo, f.to_s)
|
48
48
|
f.foo = 256
|
@@ -52,7 +52,7 @@ class TestFact < Minitest::Test
|
|
52
52
|
|
53
53
|
def test_keeps_values_unique
|
54
54
|
map = {}
|
55
|
-
f = Factbase::Fact.new(Mutex.new, map)
|
55
|
+
f = Factbase::Fact.new(Factbase.new, Mutex.new, map)
|
56
56
|
f.foo = 42
|
57
57
|
f.foo = 'Hello'
|
58
58
|
assert_equal(2, map['foo'].size)
|
@@ -61,50 +61,50 @@ class TestFact < Minitest::Test
|
|
61
61
|
end
|
62
62
|
|
63
63
|
def test_fails_when_empty
|
64
|
-
f = Factbase::Fact.new(Mutex.new, {})
|
65
|
-
assert_raises do
|
64
|
+
f = Factbase::Fact.new(Factbase.new, Mutex.new, {})
|
65
|
+
assert_raises(StandardError) do
|
66
66
|
f.something
|
67
67
|
end
|
68
68
|
end
|
69
69
|
|
70
70
|
def test_fails_when_setting_nil
|
71
|
-
f = Factbase::Fact.new(Mutex.new, {})
|
72
|
-
assert_raises do
|
71
|
+
f = Factbase::Fact.new(Factbase.new, Mutex.new, {})
|
72
|
+
assert_raises(StandardError) do
|
73
73
|
f.foo = nil
|
74
74
|
end
|
75
75
|
end
|
76
76
|
|
77
77
|
def test_fails_when_setting_empty
|
78
|
-
f = Factbase::Fact.new(Mutex.new, {})
|
79
|
-
assert_raises do
|
78
|
+
f = Factbase::Fact.new(Factbase.new, Mutex.new, {})
|
79
|
+
assert_raises(StandardError) do
|
80
80
|
f.foo = ''
|
81
81
|
end
|
82
82
|
end
|
83
83
|
|
84
84
|
def test_fails_when_not_found
|
85
|
-
f = Factbase::Fact.new(Mutex.new, {})
|
85
|
+
f = Factbase::Fact.new(Factbase.new, Mutex.new, {})
|
86
86
|
f.first = 42
|
87
|
-
assert_raises do
|
87
|
+
assert_raises(StandardError) do
|
88
88
|
f.second
|
89
89
|
end
|
90
90
|
end
|
91
91
|
|
92
92
|
def test_set_by_name
|
93
|
-
f = Factbase::Fact.new(Mutex.new, {})
|
94
|
-
f.send(
|
93
|
+
f = Factbase::Fact.new(Factbase.new, Mutex.new, {})
|
94
|
+
f.send(:_foo_bar=, 42)
|
95
95
|
assert_equal(42, f._foo_bar, f.to_s)
|
96
96
|
end
|
97
97
|
|
98
98
|
def test_set_twice_same_value
|
99
99
|
map = {}
|
100
|
-
f = Factbase::Fact.new(Mutex.new, map)
|
100
|
+
f = Factbase::Fact.new(Factbase.new, Mutex.new, map)
|
101
101
|
f.foo = 42
|
102
102
|
f.foo = 42
|
103
103
|
assert_equal([42], map['foo'])
|
104
104
|
end
|
105
105
|
|
106
106
|
def test_time_in_utc
|
107
|
-
f = Factbase::Fact.new(Mutex.new, {})
|
107
|
+
f = Factbase::Fact.new(Factbase.new, Mutex.new, {})
|
108
108
|
t = Time.now
|
109
109
|
f.foo = t
|
110
110
|
assert_equal(t.utc, f.foo)
|
@@ -112,14 +112,14 @@ class TestFact < Minitest::Test
|
|
112
112
|
end
|
113
113
|
|
114
114
|
def test_some_names_are_prohibited
|
115
|
-
f = Factbase::Fact.new(Mutex.new, {})
|
116
|
-
assert_raises { f.to_s = 42 }
|
117
|
-
assert_raises { f.class = 42 }
|
115
|
+
f = Factbase::Fact.new(Factbase.new, Mutex.new, {})
|
116
|
+
assert_raises(StandardError) { f.to_s = 42 }
|
117
|
+
assert_raises(StandardError) { f.class = 42 }
|
118
118
|
end
|
119
119
|
|
120
120
|
def test_get_all_properties
|
121
|
-
f = Factbase::Fact.new(Mutex.new, {})
|
121
|
+
f = Factbase::Fact.new(Factbase.new, Mutex.new, {})
|
122
122
|
f.foo = 42
|
123
|
-
|
123
|
+
assert_includes(f.all_properties, 'foo')
|
124
124
|
end
|
125
125
|
end
|
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
# Copyright (c) 2024 Yegor Bugayenko
|
3
|
+
# Copyright (c) 2024-2025 Yegor Bugayenko
|
4
4
|
#
|
5
5
|
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
6
|
# of this software and associated documentation files (the 'Software'), to deal
|
@@ -26,20 +26,20 @@ require_relative '../../lib/factbase/flatten'
|
|
26
26
|
|
27
27
|
# Test.
|
28
28
|
# Author:: Yegor Bugayenko (yegor256@gmail.com)
|
29
|
-
# Copyright:: Copyright (c) 2024 Yegor Bugayenko
|
29
|
+
# Copyright:: Copyright (c) 2024-2025 Yegor Bugayenko
|
30
30
|
# License:: MIT
|
31
31
|
class TestFlatten < Minitest::Test
|
32
32
|
def test_mapping
|
33
33
|
maps = [{ 'b' => [42], 'i' => 1 }, { 'a' => 33, 'i' => 0 }, { 'c' => %w[hey you], 'i' => 2 }]
|
34
34
|
to = Factbase::Flatten.new(maps, 'i').it
|
35
|
-
|
36
|
-
|
37
|
-
|
35
|
+
assert_equal(33, to[0]['a'])
|
36
|
+
assert_equal(42, to[1]['b'])
|
37
|
+
assert_equal(2, to[2]['c'].size)
|
38
38
|
end
|
39
39
|
|
40
40
|
def test_without_sorter
|
41
41
|
maps = [{ 'b' => [42], 'i' => [44] }, { 'a' => 33 }]
|
42
42
|
to = Factbase::Flatten.new(maps, 'i').it
|
43
|
-
|
43
|
+
assert_equal(33, to[0]['a'])
|
44
44
|
end
|
45
45
|
end
|