factbase 0.4.0 → 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (79) hide show
  1. checksums.yaml +4 -4
  2. data/.0pdd.yml +1 -1
  3. data/.github/workflows/actionlint.yml +1 -1
  4. data/.github/workflows/benchmark.yml +64 -0
  5. data/.github/workflows/codecov.yml +4 -2
  6. data/.github/workflows/copyrights.yml +2 -2
  7. data/.github/workflows/markdown-lint.yml +1 -1
  8. data/.github/workflows/pdd.yml +1 -1
  9. data/.github/workflows/rake.yml +2 -2
  10. data/.github/workflows/xcop.yml +1 -1
  11. data/.github/workflows/yamllint.yml +1 -1
  12. data/.gitignore +1 -1
  13. data/.rubocop.yml +6 -1
  14. data/.rultor.yml +2 -2
  15. data/.simplecov +1 -1
  16. data/.yamllint.yml +9 -4
  17. data/Gemfile +9 -7
  18. data/Gemfile.lock +99 -78
  19. data/LICENSE.txt +1 -1
  20. data/README.md +33 -0
  21. data/Rakefile +6 -1
  22. data/benchmarks/simple.rb +96 -0
  23. data/factbase.gemspec +1 -1
  24. data/lib/factbase/accum.rb +2 -2
  25. data/lib/factbase/fact.rb +6 -4
  26. data/lib/factbase/flatten.rb +2 -2
  27. data/lib/factbase/inv.rb +2 -2
  28. data/lib/factbase/looged.rb +6 -5
  29. data/lib/factbase/pre.rb +2 -2
  30. data/lib/factbase/query.rb +16 -8
  31. data/lib/factbase/query_once.rb +71 -0
  32. data/lib/factbase/rules.rb +3 -3
  33. data/lib/factbase/syntax.rb +13 -8
  34. data/lib/factbase/tee.rb +2 -2
  35. data/lib/factbase/term.rb +33 -5
  36. data/lib/factbase/term_once.rb +84 -0
  37. data/lib/factbase/terms/aggregates.rb +4 -4
  38. data/lib/factbase/terms/aliases.rb +5 -5
  39. data/lib/factbase/terms/casting.rb +2 -2
  40. data/lib/factbase/terms/debug.rb +2 -2
  41. data/lib/factbase/terms/defn.rb +2 -2
  42. data/lib/factbase/terms/logical.rb +3 -3
  43. data/lib/factbase/terms/math.rb +2 -2
  44. data/lib/factbase/terms/meta.rb +2 -2
  45. data/lib/factbase/terms/ordering.rb +2 -2
  46. data/lib/factbase/terms/strings.rb +2 -2
  47. data/lib/factbase/terms/system.rb +2 -2
  48. data/lib/factbase/to_json.rb +2 -2
  49. data/lib/factbase/to_xml.rb +2 -2
  50. data/lib/factbase/to_yaml.rb +2 -2
  51. data/lib/factbase.rb +16 -6
  52. data/test/factbase/terms/test_aggregates.rb +6 -6
  53. data/test/factbase/terms/test_aliases.rb +6 -6
  54. data/test/factbase/terms/test_casting.rb +6 -6
  55. data/test/factbase/terms/test_debug.rb +53 -0
  56. data/test/factbase/terms/test_defn.rb +15 -15
  57. data/test/factbase/terms/test_logical.rb +15 -13
  58. data/test/factbase/terms/test_math.rb +42 -42
  59. data/test/factbase/terms/test_meta.rb +87 -0
  60. data/test/factbase/terms/test_ordering.rb +45 -0
  61. data/test/factbase/terms/test_strings.rb +8 -8
  62. data/test/factbase/terms/test_system.rb +6 -6
  63. data/test/factbase/test_accum.rb +9 -9
  64. data/test/factbase/test_fact.rb +22 -22
  65. data/test/factbase/test_flatten.rb +6 -6
  66. data/test/factbase/test_inv.rb +3 -3
  67. data/test/factbase/test_looged.rb +13 -13
  68. data/test/factbase/test_pre.rb +2 -2
  69. data/test/factbase/test_query.rb +17 -17
  70. data/test/factbase/test_rules.rb +8 -8
  71. data/test/factbase/test_syntax.rb +29 -9
  72. data/test/factbase/test_tee.rb +11 -11
  73. data/test/factbase/test_term.rb +18 -18
  74. data/test/factbase/test_to_json.rb +4 -4
  75. data/test/factbase/test_to_xml.rb +12 -14
  76. data/test/factbase/test_to_yaml.rb +3 -3
  77. data/test/test__helper.rb +2 -2
  78. data/test/test_factbase.rb +198 -18
  79. 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
- assert(!t.evaluate(fact('foo' => [100]), []))
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
- assert(!t.evaluate(fact('foo' => 100), []))
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
- assert(!t.evaluate(fact('bar' => [42]), []))
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
- assert(!t.evaluate(fact('foo' => 4), []))
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
- assert(!t.evaluate(fact('foo' => 'Hello!'), []))
36
- assert(!t.evaluate(fact('bar' => ['Hello!']), []))
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
- assert(!t.evaluate(fact('foo' => [100]), []))
44
- assert(!t.evaluate(fact('foo' => []), []))
45
- assert(!t.evaluate(fact('bar' => []), []))
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
- assert(!t.evaluate(fact('foo' => [100]), []))
53
- assert(!t.evaluate(fact('foo' => []), []))
54
- assert(!t.evaluate(fact('bar' => []), []))
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
- assert(!t.evaluate(fact('foo' => [100]), []))
68
- assert(!t.evaluate(fact('foo' => 100), []))
69
- assert(!t.evaluate(fact('bar' => 100), []))
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
- assert(!t.evaluate(fact('foo' => 41), []))
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
- assert(!t.evaluate(fact('foo' => 100), []))
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
- assert(!t.evaluate(fact('foo' => [10]), []))
91
- assert(!t.evaluate(fact('foo' => 10), []))
92
- assert(!t.evaluate(fact('bar' => 10), []))
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
- assert(!t.evaluate(fact('foo' => [Time.now + 100]), []))
99
- assert(!t.evaluate(fact('bar' => [100]), []))
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
- assert(!t.evaluate(fact('foo' => [Time.now - 100]), []))
106
- assert(!t.evaluate(fact('bar' => [100]), []))
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
- assert(t.evaluate(fact, []).nil?)
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
- assert(t.evaluate(fact, []).nil?)
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
- assert(t.evaluate(fact, []).nil?)
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
- assert(t.evaluate(fact, []).nil?)
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
- assert(t.evaluate(fact, []).nil?)
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
- assert(!t.evaluate(fact('foo' => 42), []))
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'), s)
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
@@ -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
- assert(a['foo'].nil?)
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
@@ -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('_foo_bar=', 42)
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
- assert(f.all_properties.include?('foo'))
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
- assert(33, to[0]['a'])
36
- assert(42, to[1]['b'])
37
- assert(2, to[2]['c'].size)
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
- assert(33, to[0]['a'])
43
+ assert_equal(33, to[0]['a'])
44
44
  end
45
45
  end