factbase 0.15.0 → 0.15.1

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 (88) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile.lock +5 -5
  3. data/factbase.gemspec +4 -4
  4. data/lib/factbase/fact.rb +1 -1
  5. data/lib/factbase/fact_as_yaml.rb +10 -1
  6. data/lib/factbase/indexed/indexed_term.rb +6 -1
  7. data/lib/factbase/version.rb +1 -1
  8. metadata +7 -87
  9. data/.0pdd.yml +0 -8
  10. data/.gitattributes +0 -7
  11. data/.github/publish-benchmark.sh +0 -24
  12. data/.github/workflows/actionlint.yml +0 -25
  13. data/.github/workflows/benchmark.yml +0 -36
  14. data/.github/workflows/codecov.yml +0 -27
  15. data/.github/workflows/copyrights.yml +0 -19
  16. data/.github/workflows/markdown-lint.yml +0 -23
  17. data/.github/workflows/pdd.yml +0 -19
  18. data/.github/workflows/rake.yml +0 -28
  19. data/.github/workflows/reuse.yml +0 -19
  20. data/.github/workflows/typos.yml +0 -19
  21. data/.github/workflows/xcop.yml +0 -19
  22. data/.github/workflows/yamllint.yml +0 -19
  23. data/.gitignore +0 -11
  24. data/.pdd +0 -7
  25. data/.rubocop.yml +0 -51
  26. data/.rultor.yml +0 -27
  27. data/benchmark/bench_factbase.rb +0 -61
  28. data/benchmark/bench_large_query.rb +0 -128
  29. data/benchmark/bench_query.rb +0 -57
  30. data/benchmark/bench_taped.rb +0 -33
  31. data/fixtures/stories/agg.yml +0 -17
  32. data/fixtures/stories/always.yml +0 -16
  33. data/fixtures/stories/and.yml +0 -19
  34. data/fixtures/stories/as.yml +0 -16
  35. data/fixtures/stories/count.yml +0 -18
  36. data/fixtures/stories/empty.yml +0 -23
  37. data/fixtures/stories/eq.yml +0 -30
  38. data/fixtures/stories/gt.yml +0 -18
  39. data/fixtures/stories/join.yml +0 -22
  40. data/fixtures/stories/max.yml +0 -14
  41. data/fixtures/stories/min.yml +0 -14
  42. data/fixtures/stories/nth.yml +0 -14
  43. data/fixtures/stories/one.yml +0 -14
  44. data/fixtures/stories/or.yml +0 -18
  45. data/fixtures/stories/sprintf.yml +0 -12
  46. data/fixtures/stories/sum.yml +0 -14
  47. data/fixtures/stories/unique.yml +0 -30
  48. data/renovate.json +0 -6
  49. data/test/factbase/cached/test_cached_factbase.rb +0 -44
  50. data/test/factbase/cached/test_cached_query.rb +0 -100
  51. data/test/factbase/indexed/test_indexed_fact.rb +0 -23
  52. data/test/factbase/indexed/test_indexed_factbase.rb +0 -96
  53. data/test/factbase/indexed/test_indexed_query.rb +0 -208
  54. data/test/factbase/indexed/test_indexed_term.rb +0 -140
  55. data/test/factbase/sync/test_sync_factbase.rb +0 -22
  56. data/test/factbase/sync/test_sync_query.rb +0 -30
  57. data/test/factbase/terms/test_aggregates.rb +0 -63
  58. data/test/factbase/terms/test_aliases.rb +0 -58
  59. data/test/factbase/terms/test_casting.rb +0 -33
  60. data/test/factbase/terms/test_debug.rb +0 -111
  61. data/test/factbase/terms/test_defn.rb +0 -48
  62. data/test/factbase/terms/test_logical.rb +0 -57
  63. data/test/factbase/terms/test_math.rb +0 -122
  64. data/test/factbase/terms/test_meta.rb +0 -70
  65. data/test/factbase/terms/test_ordering.rb +0 -44
  66. data/test/factbase/terms/test_strings.rb +0 -36
  67. data/test/factbase/terms/test_system.rb +0 -31
  68. data/test/factbase/test_accum.rb +0 -74
  69. data/test/factbase/test_churn.rb +0 -41
  70. data/test/factbase/test_fact.rb +0 -108
  71. data/test/factbase/test_fact_as_yaml.rb +0 -77
  72. data/test/factbase/test_flatten.rb +0 -28
  73. data/test/factbase/test_impatient.rb +0 -176
  74. data/test/factbase/test_inv.rb +0 -44
  75. data/test/factbase/test_logged.rb +0 -155
  76. data/test/factbase/test_pre.rb +0 -35
  77. data/test/factbase/test_query.rb +0 -445
  78. data/test/factbase/test_rules.rb +0 -128
  79. data/test/factbase/test_syntax.rb +0 -166
  80. data/test/factbase/test_tallied.rb +0 -81
  81. data/test/factbase/test_taped.rb +0 -72
  82. data/test/factbase/test_tee.rb +0 -85
  83. data/test/factbase/test_term.rb +0 -87
  84. data/test/factbase/test_to_json.rb +0 -35
  85. data/test/factbase/test_to_xml.rb +0 -89
  86. data/test/factbase/test_to_yaml.rb +0 -39
  87. data/test/test__helper.rb +0 -41
  88. data/test/test_factbase.rb +0 -509
@@ -1,58 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- # SPDX-FileCopyrightText: Copyright (c) 2024-2025 Yegor Bugayenko
4
- # SPDX-License-Identifier: MIT
5
-
6
- require 'loog'
7
- require_relative '../../test__helper'
8
- require_relative '../../../lib/factbase/term'
9
- require_relative '../../../lib/factbase/syntax'
10
- require_relative '../../../lib/factbase/accum'
11
-
12
- # Aliases test.
13
- # Author:: Yegor Bugayenko (yegor256@gmail.com)
14
- # Copyright:: Copyright (c) 2024-2025 Yegor Bugayenko
15
- # License:: MIT
16
- class TestAliases < Factbase::Test
17
- def test_aliases
18
- maps = [
19
- { 'x' => [1], 'y' => [0], 't1' => [Time.now], 't2' => [Time.now] },
20
- { 'x' => [2], 'y' => [42], 't' => [Time.now] }
21
- ]
22
- {
23
- '(as foo (plus x 1))' => '(exists foo)',
24
- '(as foo (plus x y))' => '(gt foo 0)',
25
- '(as foo (plus bar 1))' => '(absent foo)',
26
- '(as foo (minus t1 t2))' => '(when (exists foo) (eq "Float" (type foo)))'
27
- }.each do |q, r|
28
- t = Factbase::Syntax.new(q).to_term
29
- maps.each do |m|
30
- f = Factbase::Accum.new(fact(m), {}, false)
31
- next unless t.evaluate(f, maps, Factbase.new)
32
- assert(Factbase::Syntax.new(r).to_term.evaluate(f, [], Factbase.new), "#{q} -> #{f}")
33
- end
34
- end
35
- end
36
-
37
- def test_join
38
- maps = [
39
- { 'x' => 1, 'y' => 0, 'z' => 4 },
40
- { 'x' => [2], 'bar' => [44, 55, 66] }
41
- ]
42
- {
43
- '(join "foo_x<=x" (gt x 1))' => '(exists foo_x)',
44
- '(join "foo <=bar " (exists bar))' => '(and (eq foo 44) (eq foo 55))',
45
- '(join "uuu" (eq x 1))' => '(absent uuu)',
46
- '(join "uuu <= fff" (eq fff 1))' => '(absent uuu)'
47
- }.each do |q, r|
48
- t = Factbase::Syntax.new(q).to_term
49
- maps.each do |m|
50
- f = Factbase::Accum.new(fact(m), {}, false)
51
- require_relative '../../../lib/factbase/logged'
52
- f = Factbase::Logged::Fact.new(f, log: Loog::NULL)
53
- next unless t.evaluate(f, maps, Factbase.new)
54
- assert(Factbase::Syntax.new(r).to_term.evaluate(f, [], Factbase.new), "#{q} -> #{f} doesn't match #{r}")
55
- end
56
- end
57
- end
58
- end
@@ -1,33 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- # SPDX-FileCopyrightText: Copyright (c) 2024-2025 Yegor Bugayenko
4
- # SPDX-License-Identifier: MIT
5
-
6
- require_relative '../../test__helper'
7
- require_relative '../../../lib/factbase/term'
8
-
9
- # Math test.
10
- # Author:: Yegor Bugayenko (yegor256@gmail.com)
11
- # Copyright:: Copyright (c) 2024-2025 Yegor Bugayenko
12
- # License:: MIT
13
- class TestCasting < Factbase::Test
14
- def test_to_str
15
- t = Factbase::Term.new(:to_string, [Time.now])
16
- assert_equal('String', t.evaluate(fact, [], Factbase.new).class.to_s)
17
- end
18
-
19
- def test_to_integer
20
- t = Factbase::Term.new(:to_integer, [[42, 'hello']])
21
- assert_equal('Integer', t.evaluate(fact, [], Factbase.new).class.to_s)
22
- end
23
-
24
- def test_to_float
25
- t = Factbase::Term.new(:to_float, [[3.14, 'hello']])
26
- assert_equal('Float', t.evaluate(fact, [], Factbase.new).class.to_s)
27
- end
28
-
29
- def test_to_time
30
- t = Factbase::Term.new(:to_time, [%w[2023-01-01 hello]])
31
- assert_equal('Time', t.evaluate(fact, [], Factbase.new).class.to_s)
32
- end
33
- end
@@ -1,111 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- # SPDX-FileCopyrightText: Copyright (c) 2024-2025 Yegor Bugayenko
4
- # SPDX-License-Identifier: MIT
5
-
6
- require_relative '../../test__helper'
7
- require_relative '../../../lib/factbase/term'
8
-
9
- # Debug test.
10
- # Author:: Yegor Bugayenko (yegor256@gmail.com)
11
- # Copyright:: Copyright (c) 2024-2025 Yegor Bugayenko
12
- # License:: MIT
13
- class TestDebug < Factbase::Test
14
- def test_traced
15
- t = Factbase::Term.new(:traced, [Factbase::Term.new(:defn, [:test_debug, 'self.to_s'])])
16
- assert_output("(traced (defn test_debug 'self.to_s')) -> true\n") do
17
- assert(t.evaluate(fact, [], Factbase.new))
18
- end
19
- end
20
-
21
- def test_traced_raises
22
- e = assert_raises(StandardError) { Factbase::Term.new(:traced, ['foo']).evaluate(fact, [], Factbase.new) }
23
- assert_match(/A term is expected, but 'foo' provided/, e.message)
24
- end
25
-
26
- def test_traced_raises_when_too_many_args
27
- e =
28
- assert_raises(StandardError) do
29
- Factbase::Term.new(
30
- :traced,
31
- [Factbase::Term.new(:defn, [:debug, 'self.to_s']), 'something']
32
- ).evaluate(fact, [], Factbase.new)
33
- end
34
- assert_match(/Too many \(\d+\) operands for 'traced' \(\d+ expected\)/, e.message)
35
- end
36
-
37
- def test_assert_with_true_condition
38
- t = Factbase::Term.new(:assert, ['all must be positive', Factbase::Term.new(:gt, [:foo, 0])])
39
- assert(t.evaluate(fact('foo' => 5), [], Factbase.new))
40
- end
41
-
42
- def test_assert_with_false_condition
43
- t = Factbase::Term.new(:assert, ['all must be positive', Factbase::Term.new(:gt, [:foo, 0])])
44
- e =
45
- assert_raises(RuntimeError) do
46
- t.evaluate(fact('foo' => -1), [], Factbase.new)
47
- end
48
- assert_equal("all must be positive at (assert 'all must be positive' (gt foo 0))", e.message)
49
- end
50
-
51
- def test_assert_with_zero_value
52
- t = Factbase::Term.new(:assert, ['value must not be zero', Factbase::Term.new(:gt, [:foo, 0])])
53
- e =
54
- assert_raises(RuntimeError) do
55
- t.evaluate(fact('foo' => 0), [], Factbase.new)
56
- end
57
- assert_equal("value must not be zero at (assert 'value must not be zero' (gt foo 0))", e.message)
58
- end
59
-
60
- def test_assert_with_array_true_condition
61
- t = Factbase::Term.new(:assert, ['at least one positive', Factbase::Term.new(:gt, [:foo, 0])])
62
- assert(t.evaluate(fact('foo' => [1, 2, 3]), [], Factbase.new))
63
- end
64
-
65
- def test_assert_with_array_false_condition
66
- t = Factbase::Term.new(:assert, ['at least one positive', Factbase::Term.new(:gt, [:foo, 0])])
67
- e =
68
- assert_raises(RuntimeError) do
69
- t.evaluate(fact('foo' => [-1, -2, -3]), [], Factbase.new)
70
- end
71
- assert_equal("at least one positive at (assert 'at least one positive' (gt foo 0))", e.message)
72
- end
73
-
74
- def test_assert_with_mixed_array
75
- t = Factbase::Term.new(:assert, ['at least one positive', Factbase::Term.new(:gt, [:foo, 0])])
76
- assert(t.evaluate(fact('foo' => [-1, 0, 3]), [], Factbase.new))
77
- end
78
-
79
- def test_assert_raises_when_message_not_string
80
- e =
81
- assert_raises(StandardError) do
82
- Factbase::Term.new(:assert, [123, Factbase::Term.new(:gt, [:foo, 0])]).evaluate(fact, [], Factbase.new)
83
- end
84
- assert_match(/A string is expected as first argument of 'assert', but '123' provided/, e.message)
85
- end
86
-
87
- def test_assert_raises_when_second_arg_not_term
88
- e =
89
- assert_raises(StandardError) do
90
- Factbase::Term.new(:assert, %w[message not_a_term]).evaluate(fact, [], Factbase.new)
91
- end
92
- assert_match(/A term is expected as second argument of 'assert', but 'not_a_term' provided/, e.message)
93
- end
94
-
95
- def test_assert_raises_when_too_few_args
96
- e =
97
- assert_raises(StandardError) do
98
- Factbase::Term.new(:assert, ['message']).evaluate(fact, [], Factbase.new)
99
- end
100
- assert_match(/Too few \(\d+\) operands for 'assert' \(\d+ expected\)/, e.message)
101
- end
102
-
103
- def test_assert_raises_when_too_many_args
104
- e =
105
- assert_raises(StandardError) do
106
- Factbase::Term.new(:assert, ['message', Factbase::Term.new(:gt, [:foo, 0]), 'extra']).evaluate(fact, [],
107
- Factbase.new)
108
- end
109
- assert_match(/Too many \(\d+\) operands for 'assert' \(\d+ expected\)/, e.message)
110
- end
111
- end
@@ -1,48 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- # SPDX-FileCopyrightText: Copyright (c) 2024-2025 Yegor Bugayenko
4
- # SPDX-License-Identifier: MIT
5
-
6
- require_relative '../../test__helper'
7
- require_relative '../../../lib/factbase/term'
8
-
9
- # Defn test.
10
- # Author:: Yegor Bugayenko (yegor256@gmail.com)
11
- # Copyright:: Copyright (c) 2024-2025 Yegor Bugayenko
12
- # License:: MIT
13
- class TestDefn < Factbase::Test
14
- def test_defn_simple
15
- t = Factbase::Term.new(:defn, [:foo, 'self.to_s'])
16
- assert(t.evaluate(fact('foo' => 4), [], Factbase.new))
17
- t1 = Factbase::Term.new(:foo, ['hello, world!'])
18
- assert_equal('(foo \'hello, world!\')', t1.evaluate(fact, [], Factbase.new))
19
- end
20
-
21
- def test_defn_again_by_mistake
22
- t = Factbase::Term.new(:defn, [:and, 'self.to_s'])
23
- assert_raises(StandardError) do
24
- t.evaluate(fact, [], Factbase.new)
25
- end
26
- end
27
-
28
- def test_defn_bad_name_by_mistake
29
- t = Factbase::Term.new(:defn, [:to_s, 'self.to_s'])
30
- assert_raises(StandardError) do
31
- t.evaluate(fact, [], Factbase.new)
32
- end
33
- end
34
-
35
- def test_defn_bad_name_spelling_by_mistake
36
- t = Factbase::Term.new(:defn, [:'some-key', 'self.to_s'])
37
- assert_raises(StandardError) do
38
- t.evaluate(fact, [], Factbase.new)
39
- end
40
- end
41
-
42
- def test_undef_simple
43
- t = Factbase::Term.new(:defn, [:hello, 'self.to_s'])
44
- assert(t.evaluate(fact, [], Factbase.new))
45
- t = Factbase::Term.new(:undef, [:hello])
46
- assert(t.evaluate(fact, [], Factbase.new))
47
- end
48
- end
@@ -1,57 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- # SPDX-FileCopyrightText: Copyright (c) 2024-2025 Yegor Bugayenko
4
- # SPDX-License-Identifier: MIT
5
-
6
- require_relative '../../test__helper'
7
- require_relative '../../../lib/factbase/accum'
8
- require_relative '../../../lib/factbase/term'
9
- require_relative '../../../lib/factbase/syntax'
10
-
11
- # Logical test.
12
- # Author:: Yegor Bugayenko (yegor256@gmail.com)
13
- # Copyright:: Copyright (c) 2024-2025 Yegor Bugayenko
14
- # License:: MIT
15
- class TestLogical < Factbase::Test
16
- def test_not_matching
17
- t = Factbase::Term.new(:not, [Factbase::Term.new(:always, [])])
18
- refute(t.evaluate(fact('foo' => [100]), [], Factbase.new))
19
- end
20
-
21
- def test_not_eq_matching
22
- t = Factbase::Term.new(:not, [Factbase::Term.new(:eq, [:foo, 100])])
23
- assert(t.evaluate(fact('foo' => [42, 12, -90]), [], Factbase.new))
24
- refute(t.evaluate(fact('foo' => 100), [], Factbase.new))
25
- end
26
-
27
- def test_either
28
- t = Factbase::Term.new(:either, [Factbase::Term.new(:at, [5, :foo]), 42])
29
- assert_equal([42], t.evaluate(fact('foo' => 4), [], Factbase.new))
30
- end
31
-
32
- def test_or_matching
33
- t = Factbase::Term.new(
34
- :or,
35
- [
36
- Factbase::Term.new(:eq, [:foo, 4]),
37
- Factbase::Term.new(:eq, [:bar, 5])
38
- ]
39
- )
40
- assert(t.evaluate(fact('foo' => [4]), [], Factbase.new))
41
- assert(t.evaluate(fact('bar' => [5]), [], Factbase.new))
42
- refute(t.evaluate(fact('bar' => [42]), [], Factbase.new))
43
- end
44
-
45
- def test_when_matching
46
- t = Factbase::Term.new(
47
- :when,
48
- [
49
- Factbase::Term.new(:eq, [:foo, 4]),
50
- Factbase::Term.new(:eq, [:bar, 5])
51
- ]
52
- )
53
- assert(t.evaluate(fact('foo' => 4, 'bar' => 5), [], Factbase.new))
54
- refute(t.evaluate(fact('foo' => 4), [], Factbase.new))
55
- assert(t.evaluate(fact('foo' => 5, 'bar' => 5), [], Factbase.new))
56
- end
57
- end
@@ -1,122 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- # SPDX-FileCopyrightText: Copyright (c) 2024-2025 Yegor Bugayenko
4
- # SPDX-License-Identifier: MIT
5
-
6
- require_relative '../../test__helper'
7
- require_relative '../../../lib/factbase/term'
8
-
9
- # Math test.
10
- # Author:: Yegor Bugayenko (yegor256@gmail.com)
11
- # Copyright:: Copyright (c) 2024-2025 Yegor Bugayenko
12
- # License:: MIT
13
- class TestMath < Factbase::Test
14
- def test_simple
15
- t = Factbase::Term.new(:eq, [:foo, 42])
16
- assert(t.evaluate(fact('foo' => [42]), [], Factbase.new))
17
- refute(t.evaluate(fact('foo' => 'Hello!'), [], Factbase.new))
18
- refute(t.evaluate(fact('bar' => ['Hello!']), [], Factbase.new))
19
- end
20
-
21
- def test_zero
22
- t = Factbase::Term.new(:zero, [:foo])
23
- assert(t.evaluate(fact('foo' => [0]), [], Factbase.new))
24
- assert(t.evaluate(fact('foo' => [10, 5, 6, -8, 'hey', 0, 9, 'fdsf']), [], Factbase.new))
25
- refute(t.evaluate(fact('foo' => [100]), [], Factbase.new))
26
- refute(t.evaluate(fact('foo' => []), [], Factbase.new))
27
- refute(t.evaluate(fact('bar' => []), [], Factbase.new))
28
- end
29
-
30
- def test_eq
31
- t = Factbase::Term.new(:eq, [:foo, 42])
32
- assert(t.evaluate(fact('foo' => 42), [], Factbase.new))
33
- assert(t.evaluate(fact('foo' => [10, 5, 6, -8, 'hey', 42, 9, 'fdsf']), [], Factbase.new))
34
- refute(t.evaluate(fact('foo' => [100]), [], Factbase.new))
35
- refute(t.evaluate(fact('foo' => []), [], Factbase.new))
36
- refute(t.evaluate(fact('bar' => []), [], Factbase.new))
37
- end
38
-
39
- def test_eq_time
40
- now = Time.now
41
- t = Factbase::Term.new(:eq, [:foo, Time.parse(now.iso8601)])
42
- assert(t.evaluate(fact('foo' => now), [], Factbase.new))
43
- assert(t.evaluate(fact('foo' => [now, Time.now]), [], Factbase.new))
44
- end
45
-
46
- def test_lt
47
- t = Factbase::Term.new(:lt, [:foo, 42])
48
- assert(t.evaluate(fact('foo' => [10]), [], Factbase.new))
49
- refute(t.evaluate(fact('foo' => [100]), [], Factbase.new))
50
- refute(t.evaluate(fact('foo' => 100), [], Factbase.new))
51
- refute(t.evaluate(fact('bar' => 100), [], Factbase.new))
52
- end
53
-
54
- def test_gte
55
- t = Factbase::Term.new(:gte, [:foo, 42])
56
- assert(t.evaluate(fact('foo' => 100), [], Factbase.new))
57
- assert(t.evaluate(fact('foo' => 42), [], Factbase.new))
58
- refute(t.evaluate(fact('foo' => 41), [], Factbase.new))
59
- end
60
-
61
- def test_lte
62
- t = Factbase::Term.new(:lte, [:foo, 42])
63
- assert(t.evaluate(fact('foo' => 41), [], Factbase.new))
64
- assert(t.evaluate(fact('foo' => 42), [], Factbase.new))
65
- refute(t.evaluate(fact('foo' => 100), [], Factbase.new))
66
- end
67
-
68
- def test_gt
69
- t = Factbase::Term.new(:gt, [:foo, 42])
70
- assert(t.evaluate(fact('foo' => [100]), [], Factbase.new))
71
- assert(t.evaluate(fact('foo' => 100), [], Factbase.new))
72
- refute(t.evaluate(fact('foo' => [10]), [], Factbase.new))
73
- refute(t.evaluate(fact('foo' => 10), [], Factbase.new))
74
- refute(t.evaluate(fact('bar' => 10), [], Factbase.new))
75
- end
76
-
77
- def test_lt_time
78
- t = Factbase::Term.new(:lt, [:foo, Time.now])
79
- assert(t.evaluate(fact('foo' => [Time.now - 100]), [], Factbase.new))
80
- refute(t.evaluate(fact('foo' => [Time.now + 100]), [], Factbase.new))
81
- refute(t.evaluate(fact('bar' => [100]), [], Factbase.new))
82
- end
83
-
84
- def test_gt_time
85
- t = Factbase::Term.new(:gt, [:foo, Time.now])
86
- assert(t.evaluate(fact('foo' => [Time.now + 100]), [], Factbase.new))
87
- refute(t.evaluate(fact('foo' => [Time.now - 100]), [], Factbase.new))
88
- refute(t.evaluate(fact('bar' => [100]), [], Factbase.new))
89
- end
90
-
91
- def test_plus
92
- t = Factbase::Term.new(:plus, [:foo, 42])
93
- assert_equal(46, t.evaluate(fact('foo' => 4), [], Factbase.new))
94
- assert_nil(t.evaluate(fact, [], Factbase.new))
95
- end
96
-
97
- def test_plus_time
98
- t = Factbase::Term.new(:plus, [:foo, '12 days'])
99
- assert_equal(Time.parse('2024-01-13'), t.evaluate(fact('foo' => Time.parse('2024-01-01')), [], Factbase.new))
100
- assert_nil(t.evaluate(fact, [], Factbase.new))
101
- end
102
-
103
- def test_minus
104
- t = Factbase::Term.new(:minus, [:foo, 42])
105
- assert_equal(58, t.evaluate(fact('foo' => 100), [], Factbase.new))
106
- assert_nil(t.evaluate(fact, [], Factbase.new))
107
- end
108
-
109
- def test_minus_time
110
- t = Factbase::Term.new(:minus, [:foo, '4 hours'])
111
- assert_equal(Time.parse('2024-01-01T06:04'),
112
- t.evaluate(fact('foo' => Time.parse('2024-01-01T10:04')), [], Factbase.new))
113
- assert_nil(t.evaluate(fact, [], Factbase.new))
114
- end
115
-
116
- def test_minus_time_singular
117
- t = Factbase::Term.new(:minus, [:foo, '1 hour'])
118
- assert_equal(Time.parse('2024-01-01T09:04'),
119
- t.evaluate(fact('foo' => Time.parse('2024-01-01T10:04')), [], Factbase.new))
120
- assert_nil(t.evaluate(fact, [], Factbase.new))
121
- end
122
- end
@@ -1,70 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- # SPDX-FileCopyrightText: Copyright (c) 2024-2025 Yegor Bugayenko
4
- # SPDX-License-Identifier: MIT
5
-
6
- require_relative '../../test__helper'
7
- require_relative '../../../lib/factbase/term'
8
-
9
- # Meta test.
10
- # Author:: Yegor Bugayenko (yegor256@gmail.com)
11
- # Copyright:: Copyright (c) 2024-2025 Yegor Bugayenko
12
- # License:: MIT
13
- class TestMeta < Factbase::Test
14
- def test_exists
15
- t = Factbase::Term.new(:exists, [:foo])
16
- assert(t.evaluate(fact('foo' => 41), [], Factbase.new))
17
- refute(t.evaluate(fact('bar' => 41), [], Factbase.new))
18
- end
19
-
20
- def test_absent
21
- t = Factbase::Term.new(:absent, [:foo])
22
- refute(t.evaluate(fact('foo' => 41), [], Factbase.new))
23
- assert(t.evaluate(fact('bar' => 41), [], Factbase.new))
24
- end
25
-
26
- def test_size
27
- t = Factbase::Term.new(:size, [:foo])
28
- assert_equal(1, t.evaluate(fact('foo' => 41), [], Factbase.new))
29
- assert_equal(0, t.evaluate(fact('foo' => nil), [], Factbase.new))
30
- assert_equal(4, t.evaluate(fact('foo' => [1, 2, 3, 4]), [], Factbase.new))
31
- assert_equal(0, t.evaluate(fact('foo' => []), [], Factbase.new))
32
- assert_equal(1, t.evaluate(fact('foo' => ''), [], Factbase.new))
33
- end
34
-
35
- def test_type
36
- t = Factbase::Term.new(:type, [:foo])
37
- assert_equal('nil', t.evaluate(fact('foo' => nil), [], Factbase.new))
38
- assert_equal('Integer', t.evaluate(fact('foo' => [1]), [], Factbase.new))
39
- assert_equal('Array', t.evaluate(fact('foo' => [1, 2]), [], Factbase.new))
40
- assert_equal('String', t.evaluate(fact('foo' => 'bar'), [], Factbase.new))
41
- assert_equal('Float', t.evaluate(fact('foo' => 2.1), [], Factbase.new))
42
- assert_equal('Time', t.evaluate(fact('foo' => Time.now), [], Factbase.new))
43
- end
44
-
45
- def test_nil
46
- t = Factbase::Term.new(:nil, [:foo])
47
- assert(t.evaluate(fact('foo' => nil), [], Factbase.new))
48
- refute(t.evaluate(fact('foo' => true), [], Factbase.new))
49
- refute(t.evaluate(fact('foo' => 'bar'), [], Factbase.new))
50
- end
51
-
52
- def test_many
53
- t = Factbase::Term.new(:many, [:foo])
54
- refute(t.evaluate(fact('foo' => nil), [], Factbase.new))
55
- refute(t.evaluate(fact('foo' => 1), [], Factbase.new))
56
- refute(t.evaluate(fact('foo' => '1234'), [], Factbase.new))
57
- assert(t.evaluate(fact('foo' => [1, 3, 5]), [], Factbase.new))
58
- refute(t.evaluate(fact('foo' => []), [], Factbase.new))
59
- end
60
-
61
- def test_one
62
- t = Factbase::Term.new(:one, [:foo])
63
- assert(t.evaluate(fact('foo' => 1), [], Factbase.new))
64
- assert(t.evaluate(fact('foo' => '1234'), [], Factbase.new))
65
- assert(t.evaluate(fact('foo' => [1]), [], Factbase.new))
66
- refute(t.evaluate(fact('foo' => nil), [], Factbase.new))
67
- refute(t.evaluate(fact('foo' => [1, 3, 5]), [], Factbase.new))
68
- refute(t.evaluate(fact('foo' => []), [], Factbase.new))
69
- end
70
- end
@@ -1,44 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- # SPDX-FileCopyrightText: Copyright (c) 2024-2025 Yegor Bugayenko
4
- # SPDX-License-Identifier: MIT
5
-
6
- require_relative '../../test__helper'
7
- require_relative '../../../lib/factbase/term'
8
-
9
- # Ordering test.
10
- # Author:: Yegor Bugayenko (yegor256@gmail.com)
11
- # Copyright:: Copyright (c) 2024-2025 Yegor Bugayenko
12
- # License:: MIT
13
- class TestOrdering < Factbase::Test
14
- def test_prev
15
- t = Factbase::Term.new(:prev, [:foo])
16
- assert_nil(t.evaluate(fact('foo' => 41), [], Factbase.new))
17
- assert_equal([41], t.evaluate(fact('foo' => 5), [], Factbase.new))
18
- assert_equal([5], t.evaluate(fact('foo' => 6), [], Factbase.new))
19
- end
20
-
21
- def test_unique
22
- t = Factbase::Term.new(:unique, [:foo])
23
- refute(t.evaluate(fact, [], Factbase.new))
24
- assert(t.evaluate(fact('foo' => 41), [], Factbase.new))
25
- refute(t.evaluate(fact('foo' => 41), [], Factbase.new))
26
- assert(t.evaluate(fact('foo' => 1), [], Factbase.new))
27
- end
28
-
29
- def test_unique_with_multiple_arguments
30
- t = Factbase::Term.new(:unique, %i[foo bar])
31
- assert(t.evaluate(fact('foo' => 1, 'bar' => 'a'), [], Factbase.new))
32
- assert(t.evaluate(fact('foo' => 1, 'bar' => 'b'), [], Factbase.new))
33
- assert(t.evaluate(fact('foo' => 2, 'bar' => 'a'), [], Factbase.new))
34
- refute(t.evaluate(fact('foo' => 1, 'bar' => 'a'), [], Factbase.new))
35
- end
36
-
37
- def test_unique_stops_when_all_arguments_are_duplicates
38
- t = Factbase::Term.new(:unique, %i[foo bar baz])
39
- assert(t.evaluate(fact('foo' => 1, 'bar' => 'x', 'baz' => true), [], Factbase.new))
40
- assert(t.evaluate(fact('foo' => 2, 'bar' => 'x', 'baz' => false), [], Factbase.new))
41
- assert(t.evaluate(fact('foo' => 1, 'bar' => 'y', 'baz' => true), [], Factbase.new))
42
- refute(t.evaluate(fact('foo' => 1, 'bar' => 'x', 'baz' => true), [], Factbase.new))
43
- end
44
- end
@@ -1,36 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- # SPDX-FileCopyrightText: Copyright (c) 2024-2025 Yegor Bugayenko
4
- # SPDX-License-Identifier: MIT
5
-
6
- require_relative '../../test__helper'
7
- require_relative '../../../lib/factbase/term'
8
-
9
- # Strings test.
10
- # Author:: Yegor Bugayenko (yegor256@gmail.com)
11
- # Copyright:: Copyright (c) 2024-2025 Yegor Bugayenko
12
- # License:: MIT
13
- class TestStrings < Factbase::Test
14
- def test_regexp_matching
15
- t = Factbase::Term.new(:matches, [:foo, '[a-z]+'])
16
- assert(t.evaluate(fact('foo' => 'hello'), [], Factbase.new))
17
- assert(t.evaluate(fact('foo' => 'hello 42'), [], Factbase.new))
18
- refute(t.evaluate(fact('foo' => 42), [], Factbase.new))
19
- end
20
-
21
- def test_concat
22
- t = Factbase::Term.new(:concat, [42, 'hi', 3.14, :hey, Time.now])
23
- s = t.evaluate(fact, [], Factbase.new)
24
- assert(s.start_with?('42hi3.14'))
25
- end
26
-
27
- def test_concat_empty
28
- t = Factbase::Term.new(:concat, [])
29
- assert_equal('', t.evaluate(fact, [], Factbase.new))
30
- end
31
-
32
- def test_sprintf
33
- t = Factbase::Term.new(:sprintf, ['hi, %s!', 'Jeff'])
34
- assert_equal('hi, Jeff!', t.evaluate(fact, [], Factbase.new))
35
- end
36
- end
@@ -1,31 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- # SPDX-FileCopyrightText: Copyright (c) 2024-2025 Yegor Bugayenko
4
- # SPDX-License-Identifier: MIT
5
-
6
- require_relative '../../test__helper'
7
- require_relative '../../../lib/factbase/term'
8
-
9
- # System test.
10
- # Author:: Yegor Bugayenko (yegor256@gmail.com)
11
- # Copyright:: Copyright (c) 2024-2025 Yegor Bugayenko
12
- # License:: MIT
13
- class TestSystem < Factbase::Test
14
- def test_env
15
- ENV.store('FOO', 'bar')
16
- t = Factbase::Term.new(:env, ['FOO', ''])
17
- assert_equal('bar', t.evaluate(fact, [], Factbase.new))
18
- end
19
-
20
- def test_default
21
- ENV.delete('FOO')
22
- t = Factbase::Term.new(:env, ['FOO', 'мой друг'])
23
- assert_equal('мой друг', t.evaluate(fact, [], Factbase.new))
24
- end
25
-
26
- def test_when_default_is_absent
27
- ENV.delete('FOO')
28
- t = Factbase::Term.new(:env, ['FOO'])
29
- assert_raises(StandardError) { t.evaluate(fact, [], Factbase.new) }
30
- end
31
- end