factbase 0.4.0 → 0.5.0

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.
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