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
@@ -28,7 +28,7 @@ require_relative '../../lib/factbase/pre'
28
28
 
29
29
  # Test.
30
30
  # Author:: Yegor Bugayenko (yegor256@gmail.com)
31
- # Copyright:: Copyright (c) 2024 Yegor Bugayenko
31
+ # Copyright:: Copyright (c) 2024-2025 Yegor Bugayenko
32
32
  # License:: MIT
33
33
  class TestInv < Minitest::Test
34
34
  def test_simple_checking
@@ -38,7 +38,7 @@ class TestInv < Minitest::Test
38
38
  end
39
39
  f = fb.insert
40
40
  f.a = 42
41
- assert_raises do
41
+ assert_raises(StandardError) do
42
42
  f.b = 'here we should crash'
43
43
  end
44
44
  f.c = 256
@@ -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,7 +27,7 @@ require_relative '../../lib/factbase/looged'
27
27
 
28
28
  # 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 TestLooged < Minitest::Test
33
33
  def test_simple_setting
@@ -36,7 +36,7 @@ class TestLooged < Minitest::Test
36
36
  fb.insert.bar = 3
37
37
  found = 0
38
38
  fb.query('(exists bar)').each do |f|
39
- assert(42, f.bar.positive?)
39
+ assert_predicate(f.bar, :positive?)
40
40
  f.foo = 42
41
41
  assert_equal(42, f.foo)
42
42
  found += 1
@@ -62,32 +62,32 @@ class TestLooged < Minitest::Test
62
62
  end
63
63
  )
64
64
  assert_equal(1, fb.size)
65
- assert(log.to_s.include?('modified'), log)
65
+ assert_includes(log.to_s, 'modified', log)
66
66
  end
67
67
 
68
68
  def test_with_txn_rollback
69
69
  log = Loog::Buffer.new
70
70
  fb = Factbase::Looged.new(Factbase.new, log)
71
- assert(!fb.txn { raise Factbase::Rollback })
71
+ refute(fb.txn { raise Factbase::Rollback })
72
72
  assert_equal(0, fb.size)
73
- assert(log.to_s.include?('rolled back'), log)
74
- assert(!log.to_s.include?('didn\'t touch'), log)
73
+ assert_includes(log.to_s, 'rolled back', log)
74
+ refute_includes(log.to_s, 'didn\'t touch', log)
75
75
  end
76
76
 
77
77
  def test_with_modifying_txn
78
78
  log = Loog::Buffer.new
79
79
  fb = Factbase::Looged.new(Factbase.new, log)
80
80
  fb.insert.foo = 1
81
- assert(!fb.txn { |fbt| fbt.query('(always)').each.to_a }, log)
82
- assert(fb.txn { |fbt| fbt.query('(always)').each.to_a[0].foo = 42 }, log)
83
- assert(log.to_s.include?('modified'), log)
81
+ refute(fb.txn { |fbt| fbt.query('(always)').each.to_a }, log)
82
+ assert(fb.txn { |fbt| fbt.query('(always)').each.to_a[0].foo = 42 })
83
+ assert_includes(log.to_s, 'modified', log)
84
84
  end
85
85
 
86
86
  def test_with_empty_txn
87
87
  log = Loog::Buffer.new
88
88
  fb = Factbase::Looged.new(Factbase.new, log)
89
- assert(!fb.txn { |fbt| fbt.query('(always)').each.to_a })
90
- assert(log.to_s.include?('didn\'t touch'), log)
89
+ refute(fb.txn { |fbt| fbt.query('(always)').each.to_a })
90
+ assert_includes(log.to_s, 'didn\'t touch', log)
91
91
  end
92
92
 
93
93
  def test_returns_int
@@ -140,7 +140,7 @@ class TestLooged < Minitest::Test
140
140
  'Found 1 fact(s) by \'(exists bar)\'',
141
141
  'Deleted 3 fact(s) out of 4 by \'(not (exists bar))\''
142
142
  ].each do |s|
143
- assert(log.to_s.include?(s), "#{log}\n")
143
+ assert_includes(log.to_s, s, "#{log}\n")
144
144
  end
145
145
  end
146
146
  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,7 +26,7 @@ require_relative '../../lib/factbase/pre'
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 TestPre < Minitest::Test
32
32
  def test_simple_setting
@@ -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,13 +27,13 @@ require_relative '../../lib/factbase/query'
27
27
 
28
28
  # Query 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 TestQuery < Minitest::Test
33
33
  def test_simple_parsing
34
34
  maps = []
35
35
  maps << { 'foo' => [42] }
36
- q = Factbase::Query.new(maps, Mutex.new, '(eq foo 42)')
36
+ q = Factbase::Query.new(Factbase.new, maps, Mutex.new, '(eq foo 42)')
37
37
  assert_equal(
38
38
  1,
39
39
  q.each do |f|
@@ -88,7 +88,7 @@ class TestQuery < Minitest::Test
88
88
  "(or (eq num +66) (lt time #{(Time.now - 200).utc.iso8601}))" => 1,
89
89
  '(eq 3 (agg (eq num $num) (count)))' => 1
90
90
  }.each do |q, r|
91
- assert_equal(r, Factbase::Query.new(maps, Mutex.new, q).each.to_a.size, q)
91
+ assert_equal(r, Factbase::Query.new(Factbase.new, maps, Mutex.new, q).each.to_a.size, q)
92
92
  end
93
93
  end
94
94
 
@@ -96,7 +96,7 @@ class TestQuery < Minitest::Test
96
96
  maps = []
97
97
  now = Time.now.utc
98
98
  maps << { 'foo' => [now] }
99
- q = Factbase::Query.new(maps, Mutex.new, "(eq foo #{now.iso8601})")
99
+ q = Factbase::Query.new(Factbase.new, maps, Mutex.new, "(eq foo #{now.iso8601})")
100
100
  assert_equal(1, q.each.to_a.size)
101
101
  end
102
102
 
@@ -105,7 +105,7 @@ class TestQuery < Minitest::Test
105
105
  maps << { 'foo' => [42] }
106
106
  maps << { 'bar' => [4, 5] }
107
107
  maps << { 'bar' => [5] }
108
- q = Factbase::Query.new(maps, Mutex.new, '(eq bar 5)')
108
+ q = Factbase::Query.new(Factbase.new, maps, Mutex.new, '(eq bar 5)')
109
109
  assert_equal(2, q.delete!)
110
110
  assert_equal(1, maps.size)
111
111
  end
@@ -121,7 +121,7 @@ class TestQuery < Minitest::Test
121
121
  '(agg (eq bar $v) (count))' => 1,
122
122
  '(agg (eq z 40) (count))' => 0
123
123
  }.each do |q, expected|
124
- result = Factbase::Query.new(maps, Mutex.new, q).one(v: 4)
124
+ result = Factbase::Query.new(Factbase.new, maps, Mutex.new, q).one(v: 4)
125
125
  if expected.nil?
126
126
  assert_nil(result, "#{q} -> nil")
127
127
  else
@@ -135,7 +135,7 @@ class TestQuery < Minitest::Test
135
135
  maps << { 'foo' => [42] }
136
136
  maps << { 'bar' => [4, 5] }
137
137
  maps << { 'bar' => [5] }
138
- q = Factbase::Query.new(maps, Mutex.new, '(never)')
138
+ q = Factbase::Query.new(Factbase.new, maps, Mutex.new, '(never)')
139
139
  assert_equal(0, q.delete!)
140
140
  assert_equal(3, maps.size)
141
141
  end
@@ -143,20 +143,20 @@ class TestQuery < Minitest::Test
143
143
  def test_to_array
144
144
  maps = []
145
145
  maps << { 'foo' => [42] }
146
- assert_equal(1, Factbase::Query.new(maps, Mutex.new, '(eq foo 42)').each.to_a.size)
146
+ assert_equal(1, Factbase::Query.new(Factbase.new, maps, Mutex.new, '(eq foo 42)').each.to_a.size)
147
147
  end
148
148
 
149
149
  def test_returns_int
150
150
  maps = []
151
151
  maps << { 'foo' => [1] }
152
- q = Factbase::Query.new(maps, Mutex.new, '(eq foo 1)')
152
+ q = Factbase::Query.new(Factbase.new, maps, Mutex.new, '(eq foo 1)')
153
153
  assert_equal(1, q.each(&:to_s))
154
154
  end
155
155
 
156
156
  def test_with_aliases
157
157
  maps = []
158
158
  maps << { 'foo' => [42] }
159
- assert_equal(45, Factbase::Query.new(maps, Mutex.new, '(as bar (plus foo 3))').each.to_a[0].bar)
159
+ assert_equal(45, Factbase::Query.new(Factbase.new, maps, Mutex.new, '(as bar (plus foo 3))').each.to_a[0].bar)
160
160
  assert_equal(1, maps[0].size)
161
161
  end
162
162
 
@@ -165,24 +165,24 @@ class TestQuery < Minitest::Test
165
165
  maps << { 'foo' => [42] }
166
166
  maps << { 'foo' => [17] }
167
167
  found = 0
168
- Factbase::Query.new(maps, Mutex.new, '(eq foo $bar)').each(bar: [42]) do
168
+ Factbase::Query.new(Factbase.new, maps, Mutex.new, '(eq foo $bar)').each(bar: [42]) do
169
169
  found += 1
170
170
  end
171
171
  assert_equal(1, found)
172
- assert_equal(1, Factbase::Query.new(maps, Mutex.new, '(eq foo $bar)').each(bar: 42).to_a.size)
173
- assert_equal(0, Factbase::Query.new(maps, Mutex.new, '(eq foo $bar)').each(bar: 555).to_a.size)
172
+ assert_equal(1, Factbase::Query.new(Factbase.new, maps, Mutex.new, '(eq foo $bar)').each(bar: 42).to_a.size)
173
+ assert_equal(0, Factbase::Query.new(Factbase.new, maps, Mutex.new, '(eq foo $bar)').each(bar: 555).to_a.size)
174
174
  end
175
175
 
176
176
  def test_with_nil_alias
177
177
  maps = []
178
178
  maps << { 'foo' => [42] }
179
- assert(Factbase::Query.new(maps, Mutex.new, '(as bar (plus xxx 3))').each.to_a[0]['bar'].nil?)
179
+ assert_nil(Factbase::Query.new(Factbase.new, maps, Mutex.new, '(as bar (plus xxx 3))').each.to_a[0]['bar'])
180
180
  end
181
181
 
182
182
  def test_get_all_properties
183
183
  maps = []
184
184
  maps << { 'foo' => [42] }
185
- f = Factbase::Query.new(maps, Mutex.new, '(always)').each.to_a[0]
186
- assert(f.all_properties.include?('foo'))
185
+ f = Factbase::Query.new(Factbase.new, maps, Mutex.new, '(always)').each.to_a[0]
186
+ assert_includes(f.all_properties, 'foo')
187
187
  end
188
188
  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,7 +27,7 @@ require_relative '../../lib/factbase/pre'
27
27
 
28
28
  # 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 TestRules < Minitest::Test
33
33
  def test_simple_checking
@@ -38,8 +38,8 @@ class TestRules < Minitest::Test
38
38
  f1 = fb.insert
39
39
  f1.second = 2
40
40
  f1.first = 1
41
- assert_raises do
42
- f2 = fb.insert
41
+ f2 = fb.insert
42
+ assert_raises(StandardError) do
43
43
  f2.first = 1
44
44
  end
45
45
  end
@@ -60,7 +60,7 @@ class TestRules < Minitest::Test
60
60
  f = fb.insert
61
61
  f.foo = 42
62
62
  s = f.to_s
63
- assert(s.length.positive?, s)
63
+ assert_predicate(s.length, :positive?, s)
64
64
  assert_equal('[ foo: [42] ]', s)
65
65
  end
66
66
 
@@ -74,7 +74,7 @@ class TestRules < Minitest::Test
74
74
  def test_check_only_when_txn_is_closed
75
75
  fb = Factbase::Rules.new(Factbase.new, '(when (exists a) (exists b))')
76
76
  ok = false
77
- assert_raises do
77
+ assert_raises(StandardError) do
78
78
  fb.txn do |fbt|
79
79
  f = fbt.insert
80
80
  f.a = 1
@@ -87,7 +87,7 @@ class TestRules < Minitest::Test
87
87
 
88
88
  def test_rollback_on_violation
89
89
  fb = Factbase::Rules.new(Factbase.new, '(when (exists a) (exists b))')
90
- assert_raises do
90
+ assert_raises(StandardError) do
91
91
  fb.txn do |fbt|
92
92
  f = fbt.insert
93
93
  f.a = 1
@@ -104,7 +104,7 @@ class TestRules < Minitest::Test
104
104
  f.hello = 42
105
105
  end
106
106
  ok = false
107
- assert_raises do
107
+ assert_raises(StandardError) do
108
108
  fb.txn do |fbt|
109
109
  f = fbt.insert
110
110
  f.a = 1
@@ -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,7 +25,7 @@ require_relative '../../lib/factbase/syntax'
25
25
 
26
26
  # Syntax 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 TestSyntax < Minitest::Test
31
31
  def test_parses_string_right
@@ -35,7 +35,27 @@ class TestSyntax < Minitest::Test
35
35
  "(foo 'one two three ')",
36
36
  "(foo 'one two three ' 'tail tail')"
37
37
  ].each do |q|
38
- assert_equal(q, Factbase::Syntax.new(q).to_term.to_s, q)
38
+ assert_equal(q, Factbase::Syntax.new(Factbase.new, q).to_term.to_s, q)
39
+ end
40
+ end
41
+
42
+ def test_makes_abstract_terms
43
+ {
44
+ '(foo $bar)' => true,
45
+ '(foo (bar (a (b c (f $bar)))))' => true,
46
+ '(foo (bar (a (b c (f bar)))))' => false
47
+ }.each do |q, a|
48
+ assert_equal(a, Factbase::Syntax.new(Factbase.new, q).to_term.abstract?)
49
+ end
50
+ end
51
+
52
+ def test_makes_static_terms
53
+ {
54
+ '(foo bar)' => false,
55
+ '(foo "bar")' => true,
56
+ '(agg (always) (max id))' => true
57
+ }.each do |q, a|
58
+ assert_equal(a, Factbase::Syntax.new(Factbase.new, q).to_term.static?)
39
59
  end
40
60
  end
41
61
 
@@ -50,7 +70,7 @@ class TestSyntax < Minitest::Test
50
70
  "(foo 'Hello,\n\nworld!\r\t\n')\n",
51
71
  "(or ( a 4) (b 5) (always) (and (always) (c 5) \t\t(r 7 w8s w8is 'Foo')))"
52
72
  ].each do |q|
53
- assert(!Factbase::Syntax.new(q).to_term.nil?)
73
+ refute_nil(Factbase::Syntax.new(Factbase.new, q).to_term)
54
74
  end
55
75
  end
56
76
 
@@ -70,7 +90,7 @@ class TestSyntax < Minitest::Test
70
90
  '(eq t 3.0e+21)',
71
91
  "(foo (x (f (t (y 42 'Hey you'))) (never) (r 3)) y z)"
72
92
  ].each do |q|
73
- assert_equal(q, Factbase::Syntax.new(q).to_term.to_s, q)
93
+ assert_equal(q, Factbase::Syntax.new(Factbase.new, q).to_term.to_s, q)
74
94
  end
75
95
  end
76
96
 
@@ -85,7 +105,7 @@ class TestSyntax < Minitest::Test
85
105
  '(or (eq bar 888) (eq z 1))' => true,
86
106
  "(or (gt bar 100) (eq foo 'Hello, world!'))" => true
87
107
  }.each do |k, v|
88
- assert_equal(v, Factbase::Syntax.new(k).to_term.evaluate(m, []), k)
108
+ assert_equal(v, Factbase::Syntax.new(Factbase.new, k).to_term.evaluate(m, []), k)
89
109
  end
90
110
  end
91
111
 
@@ -109,9 +129,9 @@ class TestSyntax < Minitest::Test
109
129
  '"'
110
130
  ].each do |q|
111
131
  msg = assert_raises(q) do
112
- Factbase::Syntax.new(q).to_term
132
+ Factbase::Syntax.new(Factbase.new, q).to_term
113
133
  end.message
114
- assert(msg.include?(q), msg)
134
+ assert_includes(msg, q, msg)
115
135
  end
116
136
  end
117
137
 
@@ -121,7 +141,7 @@ class TestSyntax < Minitest::Test
121
141
  '(and (foo) (foo))' => '(foo)',
122
142
  '(and (foo) (or (and (eq a 1))) (eq a 1) (foo))' => '(and (foo) (eq a 1))'
123
143
  }.each do |s, t|
124
- assert_equal(t, Factbase::Syntax.new(s).to_term.to_s)
144
+ assert_equal(t, Factbase::Syntax.new(Factbase.new, s).to_term.to_s)
125
145
  end
126
146
  end
127
147
  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,13 +27,13 @@ require_relative '../../lib/factbase/fact'
27
27
 
28
28
  # Tee 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 TestTee < Minitest::Test
33
33
  def test_two_facts
34
- prim = Factbase::Fact.new(Mutex.new, {})
34
+ prim = Factbase::Fact.new(Factbase.new, Mutex.new, {})
35
35
  prim.foo = 42
36
- upper = Factbase::Fact.new(Mutex.new, {})
36
+ upper = Factbase::Fact.new(Factbase.new, Mutex.new, {})
37
37
  upper.bar = 13
38
38
  t = Factbase::Tee.new(prim, upper)
39
39
  assert_equal(42, t.foo)
@@ -41,18 +41,18 @@ class TestTee < Minitest::Test
41
41
  end
42
42
 
43
43
  def test_all_properties
44
- prim = Factbase::Fact.new(Mutex.new, {})
44
+ prim = Factbase::Fact.new(Factbase.new, Mutex.new, {})
45
45
  prim.foo = 42
46
- upper = Factbase::Fact.new(Mutex.new, {})
46
+ upper = Factbase::Fact.new(Factbase.new, Mutex.new, {})
47
47
  upper.bar = 13
48
48
  t = Factbase::Tee.new(prim, upper)
49
- assert(t.all_properties.include?('foo'))
50
- assert(t.all_properties.include?('bar'))
49
+ assert_includes(t.all_properties, 'foo')
50
+ assert_includes(t.all_properties, 'bar')
51
51
  end
52
52
 
53
53
  def test_recursively
54
54
  map = {}
55
- prim = Factbase::Fact.new(Mutex.new, map)
55
+ prim = Factbase::Fact.new(Factbase.new, Mutex.new, map)
56
56
  prim.foo = 42
57
57
  t = Factbase::Tee.new(nil, { 'bar' => 7 })
58
58
  assert_equal(7, t['$bar'])
@@ -61,9 +61,9 @@ class TestTee < Minitest::Test
61
61
  end
62
62
 
63
63
  def test_prints_to_string
64
- prim = Factbase::Fact.new(Mutex.new, {})
64
+ prim = Factbase::Fact.new(Factbase.new, Mutex.new, {})
65
65
  prim.foo = 42
66
- upper = Factbase::Fact.new(Mutex.new, {})
66
+ upper = Factbase::Fact.new(Factbase.new, Mutex.new, {})
67
67
  upper.bar = 13
68
68
  t = Factbase::Tee.new(prim, upper)
69
69
  assert_equal('[ foo: [42] ]', t.to_s)
@@ -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,34 +25,34 @@ require_relative '../../lib/factbase/term'
25
25
 
26
26
  # Term 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 TestTerm < Minitest::Test
31
31
  def test_false_matching
32
- t = Factbase::Term.new(:never, [])
33
- assert(!t.evaluate(fact('foo' => [100]), []))
32
+ t = Factbase::Term.new(Factbase.new, :never, [])
33
+ refute(t.evaluate(fact('foo' => [100]), []))
34
34
  end
35
35
 
36
36
  def test_size_matching
37
- t = Factbase::Term.new(:size, [:foo])
37
+ t = Factbase::Term.new(Factbase.new, :size, [:foo])
38
38
  assert_equal(3, t.evaluate(fact('foo' => [42, 12, -90]), []))
39
39
  assert_equal(0, t.evaluate(fact('bar' => 100), []))
40
40
  end
41
41
 
42
42
  def test_exists_matching
43
- t = Factbase::Term.new(:exists, [:foo])
43
+ t = Factbase::Term.new(Factbase.new, :exists, [:foo])
44
44
  assert(t.evaluate(fact('foo' => [42, 12, -90]), []))
45
- assert(!t.evaluate(fact('bar' => 100), []))
45
+ refute(t.evaluate(fact('bar' => 100), []))
46
46
  end
47
47
 
48
48
  def test_absent_matching
49
- t = Factbase::Term.new(:absent, [:foo])
49
+ t = Factbase::Term.new(Factbase.new, :absent, [:foo])
50
50
  assert(t.evaluate(fact('z' => [42, 12, -90]), []))
51
- assert(!t.evaluate(fact('foo' => 100), []))
51
+ refute(t.evaluate(fact('foo' => 100), []))
52
52
  end
53
53
 
54
54
  def test_type_matching
55
- t = Factbase::Term.new(:type, [:foo])
55
+ t = Factbase::Term.new(Factbase.new, :type, [:foo])
56
56
  assert_equal('Integer', t.evaluate(fact('foo' => 42), []))
57
57
  assert_equal('Integer', t.evaluate(fact('foo' => [42]), []))
58
58
  assert_equal('Array', t.evaluate(fact('foo' => [1, 2, 3]), []))
@@ -64,30 +64,30 @@ class TestTerm < Minitest::Test
64
64
  end
65
65
 
66
66
  def test_past
67
- t = Factbase::Term.new(:prev, [:foo])
67
+ t = Factbase::Term.new(Factbase.new, :prev, [:foo])
68
68
  assert_nil(t.evaluate(fact('foo' => 4), []))
69
69
  assert_equal([4], t.evaluate(fact('foo' => 5), []))
70
70
  end
71
71
 
72
72
  def test_at
73
- t = Factbase::Term.new(:at, [1, :foo])
73
+ t = Factbase::Term.new(Factbase.new, :at, [1, :foo])
74
74
  assert_nil(t.evaluate(fact('foo' => 4), []))
75
75
  assert_equal(5, t.evaluate(fact('foo' => [4, 5]), []))
76
76
  end
77
77
 
78
78
  def test_report_missing_term
79
- t = Factbase::Term.new(:something, [])
80
- msg = assert_raises do
79
+ t = Factbase::Term.new(Factbase.new, :something, [])
80
+ msg = assert_raises(StandardError) do
81
81
  t.evaluate(fact, [])
82
82
  end.message
83
- assert(msg.include?('not defined at (something)'), msg)
83
+ assert_includes(msg, 'not defined at (something)', msg)
84
84
  end
85
85
 
86
86
  def test_report_other_error
87
- t = Factbase::Term.new(:at, [])
88
- msg = assert_raises do
87
+ t = Factbase::Term.new(Factbase.new, :at, [])
88
+ msg = assert_raises(StandardError) do
89
89
  t.evaluate(fact, [])
90
90
  end.message
91
- assert(msg.include?('at (at)'), msg)
91
+ assert_includes(msg, 'at (at)', msg)
92
92
  end
93
93
  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,7 +27,7 @@ require_relative '../../lib/factbase/to_json'
27
27
 
28
28
  # 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 TestToJSON < Minitest::Test
33
33
  def test_simple_rendering
@@ -37,7 +37,7 @@ class TestToJSON < Minitest::Test
37
37
  f.foo = 256
38
38
  to = Factbase::ToJSON.new(fb)
39
39
  json = JSON.parse(to.json)
40
- assert(42, json[0]['foo'][1])
40
+ assert_equal(256, json[0]['foo'][1])
41
41
  end
42
42
 
43
43
  def test_sort_keys
@@ -47,6 +47,6 @@ class TestToJSON < Minitest::Test
47
47
  f.b = 1
48
48
  f.a = 256
49
49
  json = Factbase::ToJSON.new(fb).json
50
- assert(json.include?('{"a":256,"b":1,"c":42}'), json)
50
+ assert_includes(json, '{"a":256,"b":1,"c":42}', json)
51
51
  end
52
52
  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,7 +27,7 @@ require_relative '../../lib/factbase/to_xml'
27
27
 
28
28
  # 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 TestToXML < Minitest::Test
33
33
  def test_simple_rendering
@@ -35,11 +35,9 @@ class TestToXML < Minitest::Test
35
35
  fb.insert.t = Time.now
36
36
  to = Factbase::ToXML.new(fb)
37
37
  xml = Nokogiri::XML.parse(to.xml)
38
- assert(!xml.xpath('/fb/f[t]').empty?)
39
- assert(
40
- xml.xpath('/fb/f/t/text()').text.match?(
41
- /^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}Z$/
42
- )
38
+ refute_empty(xml.xpath('/fb/f[t]'))
39
+ assert_match(
40
+ /^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}Z$/, xml.xpath('/fb/f/t/text()').text
43
41
  )
44
42
  end
45
43
 
@@ -48,7 +46,7 @@ class TestToXML < Minitest::Test
48
46
  fb.insert.t = "\uffff < > & ' \""
49
47
  to = Factbase::ToXML.new(fb)
50
48
  xml = Nokogiri::XML.parse(to.xml)
51
- assert(!xml.xpath('/fb/f[t]').empty?)
49
+ refute_empty(xml.xpath('/fb/f[t]'))
52
50
  end
53
51
 
54
52
  def test_meta_data_presence
@@ -56,8 +54,8 @@ class TestToXML < Minitest::Test
56
54
  fb.insert.x = 42
57
55
  to = Factbase::ToXML.new(fb)
58
56
  xml = Nokogiri::XML.parse(to.xml)
59
- assert(!xml.xpath('/fb[@version]').empty?)
60
- assert(!xml.xpath('/fb[@size]').empty?)
57
+ refute_empty(xml.xpath('/fb[@version]'))
58
+ refute_empty(xml.xpath('/fb[@size]'))
61
59
  end
62
60
 
63
61
  def test_to_xml_with_short_names
@@ -67,8 +65,8 @@ class TestToXML < Minitest::Test
67
65
  f.f = 2
68
66
  to = Factbase::ToXML.new(fb)
69
67
  xml = Nokogiri::XML.parse(to.xml)
70
- assert(!xml.xpath('/fb/f/type').empty?)
71
- assert(!xml.xpath('/fb/f/f').empty?)
68
+ refute_empty(xml.xpath('/fb/f/type'))
69
+ refute_empty(xml.xpath('/fb/f/f'))
72
70
  end
73
71
 
74
72
  def test_show_types_as_attributes
@@ -89,7 +87,7 @@ class TestToXML < Minitest::Test
89
87
  '/fb/f/d[@t="T"]',
90
88
  '/fb/f/e/v[@t="S"]',
91
89
  '/fb/f/e/v[@t="I"]'
92
- ].each { |x| assert(!xml.xpath(x).empty?, out) }
90
+ ].each { |x| refute_empty(xml.xpath(x), out) }
93
91
  end
94
92
 
95
93
  def test_sorts_keys
@@ -102,7 +100,7 @@ class TestToXML < Minitest::Test
102
100
  to = Factbase::ToXML.new(fb)
103
101
  xml = Nokogiri::XML.parse(to.xml)
104
102
  %w[a c t x].each_with_index do |e, i|
105
- assert(!xml.xpath("/fb/f/#{e}[count(preceding-sibling::*) = #{i}]").empty?, e)
103
+ refute_empty(xml.xpath("/fb/f/#{e}[count(preceding-sibling::*) = #{i}]"), e)
106
104
  end
107
105
  end
108
106
  end