factbase 0.3.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 +3 -3
  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 +15 -4
  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 +17 -8
  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 +16 -2
  69. data/test/factbase/test_query.rb +17 -17
  70. data/test/factbase/test_rules.rb +11 -8
  71. data/test/factbase/test_syntax.rb +29 -9
  72. data/test/factbase/test_tee.rb +18 -9
  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
@@ -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
@@ -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
@@ -35,4 +35,18 @@ class TestPre < Minitest::Test
35
35
  assert_equal(42, f.foo)
36
36
  assert_equal(1, fb.query('(always)').each.to_a.size)
37
37
  end
38
+
39
+ def test_in_transaction
40
+ fb =
41
+ Factbase::Pre.new(Factbase.new) do |f, fbt|
42
+ f.total = fbt.size
43
+ end
44
+ fb.txn do |fbt|
45
+ fbt.insert
46
+ fbt.insert
47
+ end
48
+ arr = fb.query('(always)').each.to_a
49
+ assert_equal(1, arr[0].total)
50
+ assert_equal(2, arr[1].total)
51
+ end
38
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,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
@@ -58,7 +58,10 @@ class TestRules < Minitest::Test
58
58
  '(when (exists a) (exists b))'
59
59
  )
60
60
  f = fb.insert
61
- assert(f.to_s.length.positive?)
61
+ f.foo = 42
62
+ s = f.to_s
63
+ assert_predicate(s.length, :positive?, s)
64
+ assert_equal('[ foo: [42] ]', s)
62
65
  end
63
66
 
64
67
  def test_query_one
@@ -71,7 +74,7 @@ class TestRules < Minitest::Test
71
74
  def test_check_only_when_txn_is_closed
72
75
  fb = Factbase::Rules.new(Factbase.new, '(when (exists a) (exists b))')
73
76
  ok = false
74
- assert_raises do
77
+ assert_raises(StandardError) do
75
78
  fb.txn do |fbt|
76
79
  f = fbt.insert
77
80
  f.a = 1
@@ -84,7 +87,7 @@ class TestRules < Minitest::Test
84
87
 
85
88
  def test_rollback_on_violation
86
89
  fb = Factbase::Rules.new(Factbase.new, '(when (exists a) (exists b))')
87
- assert_raises do
90
+ assert_raises(StandardError) do
88
91
  fb.txn do |fbt|
89
92
  f = fbt.insert
90
93
  f.a = 1
@@ -101,7 +104,7 @@ class TestRules < Minitest::Test
101
104
  f.hello = 42
102
105
  end
103
106
  ok = false
104
- assert_raises do
107
+ assert_raises(StandardError) do
105
108
  fb.txn do |fbt|
106
109
  f = fbt.insert
107
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,22 +41,31 @@ 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'])
59
59
  t = Factbase::Tee.new(prim, t)
60
60
  assert_equal(7, t['$bar'])
61
61
  end
62
+
63
+ def test_prints_to_string
64
+ prim = Factbase::Fact.new(Factbase.new, Mutex.new, {})
65
+ prim.foo = 42
66
+ upper = Factbase::Fact.new(Factbase.new, Mutex.new, {})
67
+ upper.bar = 13
68
+ t = Factbase::Tee.new(prim, upper)
69
+ assert_equal('[ foo: [42] ]', t.to_s)
70
+ end
62
71
  end