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