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,166 +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/syntax'
8
-
9
- # Syntax test.
10
- # Author:: Yegor Bugayenko (yegor256@gmail.com)
11
- # Copyright:: Copyright (c) 2024-2025 Yegor Bugayenko
12
- # License:: MIT
13
- class TestSyntax < Factbase::Test
14
- def test_parses_string_right
15
- [
16
- "(foo 'abc')",
17
- "(foo 'one two')",
18
- "(foo 'one two three ')",
19
- "(foo 'one two three ' 'tail tail')"
20
- ].each do |q|
21
- assert_equal(q, Factbase::Syntax.new(q).to_term.to_s, q)
22
- end
23
- end
24
-
25
- def test_makes_abstract_terms
26
- {
27
- '(foo $bar)' => true,
28
- '(foo (bar (a (b c (f $bar)))))' => true,
29
- '(foo (bar (a (b c (f bar)))))' => false
30
- }.each do |q, a|
31
- assert_equal(a, Factbase::Syntax.new(q).to_term.abstract?)
32
- end
33
- end
34
-
35
- def test_makes_static_terms
36
- {
37
- '(foo bar)' => false,
38
- '(foo "bar")' => true,
39
- '(agg (always) (max id))' => true
40
- }.each do |q, a|
41
- assert_equal(a, Factbase::Syntax.new(q).to_term.static?)
42
- end
43
- end
44
-
45
- def test_simple_parsing
46
- [
47
- '(foo)',
48
- '(foo (bar) (zz 77) ) # hey',
49
- "# hello\n\n\n(foo ($bar))",
50
- "(eq foo \n\n 'Hello, world!'\n)\n",
51
- "(eq x 'Hello, \\' \n) \\' ( world!')",
52
- "# this is a comment\n(eq foo # test\n 42)\n\n# another comment\n",
53
- "(foo 'Hello,\n\nworld!\r\t\n')\n",
54
- "(or ( a 4) (b 5) (always) (and (always) (c 5) \t\t(r 7 w8s w8is 'Foo')))"
55
- ].each do |q|
56
- refute_nil(Factbase::Syntax.new(q).to_term)
57
- end
58
- end
59
-
60
- def test_exact_parsing
61
- [
62
- '(foo)',
63
- '(foo 7)',
64
- "(foo 7 'Dude')",
65
- "(r 'Dude\\'s Friend')",
66
- "(r 'I\\'m \\\"good\\\"')",
67
- '(foo x y z)',
68
- "(foo x y z t f 42 'Hi!# you' 33)",
69
- '(foo (x) y z)',
70
- '(eq t 2024-05-25T19:43:48Z)',
71
- '(eq t 2024-05-25T19:43:48Z)',
72
- '(eq t 3.1415926)',
73
- '(eq t 3.0e+21)',
74
- "(foo (x (f (t (y 42 'Hey you'))) (never) (r 3)) y z)"
75
- ].each do |q|
76
- assert_equal(q, Factbase::Syntax.new(q).to_term.to_s, q)
77
- end
78
- end
79
-
80
- def test_simple_matching
81
- m = {
82
- 'foo' => ['Hello, world!'],
83
- 'bar' => [42],
84
- 'z' => [1, 2, 3, 4]
85
- }
86
- {
87
- '(eq z 1)' => true,
88
- '(or (eq bar 888) (eq z 1))' => true,
89
- "(or (gt bar 100) (eq foo 'Hello, world!'))" => true
90
- }.each do |k, v|
91
- assert_equal(v, Factbase::Syntax.new(k).to_term.evaluate(m, [], Factbase.new), k)
92
- end
93
- end
94
-
95
- def test_broken_syntax
96
- [
97
- '',
98
- '()',
99
- '(foo',
100
- '(foo $)',
101
- '(foo 1) (bar 2)',
102
- 'some text',
103
- '"hello, world!',
104
- '(foo 7',
105
- "(foo 7 'Dude'",
106
- '(foo x y z (',
107
- '(bad-term-name 42)',
108
- '(foo x y (z t (f 42 ',
109
- ')foo ) y z)',
110
- '(x "")',
111
- ")y 42 'Hey you)",
112
- ')',
113
- '"'
114
- ].each do |q|
115
- msg = assert_raises(q) do
116
- Factbase::Syntax.new(q).to_term
117
- end.message
118
- assert_includes(msg, q, msg)
119
- end
120
- end
121
-
122
- def test_raises_on_broken_syntax
123
- 100.times do
124
- q = [
125
- '(', ')', '#test', '$foo', '%what',
126
- '"hello"', '42', '+', '?', '!', '\"',
127
- '\'', 'привет'
128
- ].shuffle.join(' . ')
129
- assert_raises(Factbase::Syntax::Broken, q) do
130
- Factbase::Syntax.new(q).to_term
131
- end
132
- end
133
- end
134
-
135
- def test_simplification
136
- {
137
- '(foo)' => '(foo)',
138
- '(and (foo) (foo))' => '(foo)',
139
- '(and (foo) (or (and (eq a 1))) (eq a 1) (foo))' => '(and (foo) (eq a 1))'
140
- }.each do |s, t|
141
- assert_equal(t, Factbase::Syntax.new(s).to_term.to_s)
142
- end
143
- end
144
-
145
- def test_fails_when_term_is_not_a_class
146
- assert_raises(StandardError) { Factbase::Syntax.new('(foo 1)', term: 'hello') }
147
- end
148
-
149
- def test_fails_when_term_is_wrong_class
150
- assert_raises(StandardError) { Factbase::Syntax.new('(bar 1)', term: String).to_term }
151
- end
152
-
153
- def test_fails_when_term_is_incorrectly_defined_class
154
- assert_includes(
155
- assert_raises(StandardError) { Factbase::Syntax.new('(bar 1)', term: FakeTerm).to_term }.message,
156
- 'wrong number of arguments'
157
- )
158
- end
159
-
160
- class FakeTerm < Factbase::Term
161
- def initialize(invalid)
162
- super
163
- @x = invalid
164
- end
165
- end
166
- end
@@ -1,81 +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 'threads'
8
- require_relative '../../lib/factbase'
9
- require_relative '../../lib/factbase/tallied'
10
-
11
- # Test.
12
- # Author:: Yegor Bugayenko (yegor256@gmail.com)
13
- # Copyright:: Copyright (c) 2024-2025 Yegor Bugayenko
14
- # License:: MIT
15
- class TestTallied < Factbase::Test
16
- def test_counts_size
17
- fb = Factbase::Tallied.new(Factbase.new)
18
- assert_equal(0, fb.size)
19
- end
20
-
21
- def test_queries_empty_factbase
22
- fb = Factbase::Tallied.new(Factbase.new)
23
- assert_equal(0, fb.query('(gt foo 1)').each.to_a.size)
24
- end
25
-
26
- def test_counts_simple_changes
27
- fb = Factbase::Tallied.new(Factbase.new)
28
- fb.insert.bar = 3
29
- fb.query('(exists bar)').each do |f|
30
- f.foo = 42
31
- end
32
- assert_equal(1, fb.churn.inserted)
33
- assert_equal(0, fb.churn.deleted)
34
- assert_equal(2, fb.churn.added)
35
- end
36
-
37
- def test_counts_in_one
38
- fb = Factbase::Tallied.new(Factbase.new)
39
- fb.insert.bar = 3
40
- assert_equal(1, fb.query('(agg (eq bar 3) (count))').one)
41
- assert_equal(1, fb.churn.added)
42
- end
43
-
44
- def test_returns_all_props
45
- fb = Factbase::Tallied.new(Factbase.new)
46
- f = fb.insert
47
- f.bar = 3
48
- assert_includes(f.all_properties, 'bar')
49
- end
50
-
51
- def test_counts_in_txn
52
- fb = Factbase::Tallied.new(Factbase.new)
53
- fb.txn do |fbt|
54
- fbt.insert.boom = 3
55
- fbt.query('(exists boom)').each do |f|
56
- f.foo = 88
57
- end
58
- end
59
- assert_equal(1, fb.churn.inserted)
60
- assert_equal(0, fb.churn.deleted)
61
- assert_equal(2, fb.churn.added)
62
- end
63
-
64
- def test_counts_in_txn_in_threads
65
- fb = Factbase::Tallied.new(Factbase.new)
66
- t = 5
67
- Threads.new(t).assert do |i|
68
- fb.txn do |fbt|
69
- fbt.insert.x = i
70
- fbt.query("(eq x #{i})").each do |f|
71
- f.send(:"a#{i}=", i)
72
- end
73
- fbt.query("(lt x #{t + 1})").delete!
74
- end
75
- end
76
- assert_equal(0, fb.size)
77
- assert_equal(t, fb.churn.inserted)
78
- assert_equal(t, fb.churn.deleted)
79
- assert_equal(t * 2, fb.churn.added)
80
- end
81
- end
@@ -1,72 +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'
8
- require_relative '../../lib/factbase/taped'
9
-
10
- # Test.
11
- # Author:: Yegor Bugayenko (yegor256@gmail.com)
12
- # Copyright:: Copyright (c) 2024-2025 Yegor Bugayenko
13
- # License:: MIT
14
- class TestTaped < Factbase::Test
15
- def test_tracks_insertion
16
- t = Factbase::Taped.new([])
17
- t << {}
18
- assert_equal(1, t.inserted.size)
19
- end
20
-
21
- def test_joins_with_empty
22
- t = Factbase::Taped.new([{ foo: 'yes' }])
23
- t &= []
24
- assert_equal(0, t.size)
25
- end
26
-
27
- def test_disjoins_with_empty
28
- t = Factbase::Taped.new([{ bar: 'oops' }])
29
- t |= []
30
- assert_equal(1, t.size)
31
- end
32
-
33
- def test_tracks_deletion
34
- t = Factbase::Taped.new([{ x: 1 }, { x: 2 }])
35
- t.delete_if { |m| m[:x] == 1 }
36
- assert_equal(1, t.deleted.size)
37
- end
38
-
39
- def test_tracks_addition
40
- h = { f: 5 }
41
- t = Factbase::Taped.new([h])
42
- t.each do |m|
43
- m[:bar] = 66
44
- end
45
- assert_equal(1, t.added.size)
46
- assert_equal(h.object_id, t.added.first)
47
- end
48
-
49
- def test_tracks_addition_uniquely
50
- h = { f: 5 }
51
- t = Factbase::Taped.new([h])
52
- t.each do |m|
53
- m[:bar] = 66
54
- m[:foo] = 77
55
- end
56
- assert_equal(1, t.added.size)
57
- end
58
-
59
- def test_tracks_factbase
60
- t = Factbase::Taped.new([])
61
- fb = Factbase.new(t)
62
- fb.insert
63
- fb.query('(always)').each do |f|
64
- f.foo = 42
65
- f.foo = 5
66
- end
67
- fb.query('(always)').delete!
68
- assert_equal(1, t.inserted.size)
69
- assert_equal(1, t.added.size)
70
- assert_equal(1, t.deleted.size)
71
- end
72
- end
@@ -1,85 +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'
8
- require_relative '../../lib/factbase/accum'
9
- require_relative '../../lib/factbase/tee'
10
- require_relative '../../lib/factbase/fact'
11
-
12
- def global_function_for_test_only(foo)
13
- raise foo
14
- end
15
-
16
- # Tee test.
17
- # Author:: Yegor Bugayenko (yegor256@gmail.com)
18
- # Copyright:: Copyright (c) 2024-2025 Yegor Bugayenko
19
- # License:: MIT
20
- class TestTee < Factbase::Test
21
- def test_two_facts
22
- prim = Factbase::Fact.new({})
23
- prim.foo = 42
24
- upper = Factbase::Fact.new({})
25
- upper.bar = 13
26
- t = Factbase::Tee.new(prim, upper)
27
- assert_equal(42, t.foo)
28
- assert_equal([13], t['$bar'])
29
- end
30
-
31
- def test_no_trip_to_prim_if_not_found
32
- prim = Factbase::Fact.new({})
33
- prim.foo = 777
34
- t = Factbase::Tee.new(prim, Factbase::Fact.new({}))
35
- assert_nil(t['$foo'])
36
- end
37
-
38
- def test_fetches_simply
39
- t = Factbase::Accum.new(
40
- Factbase::Tee.new(
41
- Factbase::Fact.new({ 'foo_bar' => [987] }),
42
- Factbase::Fact.new({})
43
- ),
44
- {}, true
45
- )
46
- assert_equal(987, t.foo_bar)
47
- end
48
-
49
- def test_fetches_without_conflict_with_global_name
50
- t = Factbase::Tee.new(
51
- Factbase::Fact.new({ 'global_function_for_test_only' => [2] }),
52
- Factbase::Fact.new({})
53
- )
54
- assert_equal(2, t.global_function_for_test_only)
55
- end
56
-
57
- def test_all_properties
58
- prim = Factbase::Fact.new({})
59
- prim.foo = 42
60
- upper = Factbase::Fact.new({})
61
- upper.bar = 13
62
- t = Factbase::Tee.new(prim, upper)
63
- assert_includes(t.all_properties, 'foo')
64
- assert_includes(t.all_properties, 'bar')
65
- end
66
-
67
- def test_recursively
68
- map = {}
69
- prim = Factbase::Fact.new(map)
70
- prim.foo = 42
71
- t = Factbase::Tee.new(Factbase::Fact.new({}), { 'bar' => [7] })
72
- assert_equal([7], t['$bar'])
73
- t = Factbase::Tee.new(prim, t)
74
- assert_equal([7], t['$bar'])
75
- end
76
-
77
- def test_prints_to_string
78
- prim = Factbase::Fact.new({})
79
- prim.foo = 42
80
- upper = Factbase::Fact.new({})
81
- upper.bar = 13
82
- t = Factbase::Tee.new(prim, upper)
83
- assert_equal('[ foo: [42] ]', t.to_s)
84
- end
85
- end
@@ -1,87 +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'
8
- require_relative '../../lib/factbase/term'
9
-
10
- # Term test.
11
- # Author:: Yegor Bugayenko (yegor256@gmail.com)
12
- # Copyright:: Copyright (c) 2024-2025 Yegor Bugayenko
13
- # License:: MIT
14
- class TestTerm < Factbase::Test
15
- def test_false_matching
16
- t = Factbase::Term.new(:never, [])
17
- refute(t.evaluate(fact('foo' => [100]), [], Factbase.new))
18
- end
19
-
20
- def test_size_matching
21
- t = Factbase::Term.new(:size, [:foo])
22
- assert_equal(3, t.evaluate(fact('foo' => [42, 12, -90]), [], Factbase.new))
23
- assert_equal(0, t.evaluate(fact('bar' => 100), [], Factbase.new))
24
- end
25
-
26
- def test_exists_matching
27
- t = Factbase::Term.new(:exists, [:foo])
28
- assert(t.evaluate(fact('foo' => [42, 12, -90]), [], Factbase.new))
29
- refute(t.evaluate(fact('bar' => 100), [], Factbase.new))
30
- end
31
-
32
- def test_absent_matching
33
- t = Factbase::Term.new(:absent, [:foo])
34
- assert(t.evaluate(fact('z' => [42, 12, -90]), [], Factbase.new))
35
- refute(t.evaluate(fact('foo' => 100), [], Factbase.new))
36
- end
37
-
38
- def test_type_matching
39
- t = Factbase::Term.new(:type, [:foo])
40
- assert_equal('Integer', t.evaluate(fact('foo' => 42), [], Factbase.new))
41
- assert_equal('Integer', t.evaluate(fact('foo' => [42]), [], Factbase.new))
42
- assert_equal('Array', t.evaluate(fact('foo' => [1, 2, 3]), [], Factbase.new))
43
- assert_equal('String', t.evaluate(fact('foo' => 'Hello, world!'), [], Factbase.new))
44
- assert_equal('Float', t.evaluate(fact('foo' => 3.14), [], Factbase.new))
45
- assert_equal('Time', t.evaluate(fact('foo' => Time.now), [], Factbase.new))
46
- assert_equal('Integer', t.evaluate(fact('foo' => 1_000_000_000_000_000), [], Factbase.new))
47
- assert_equal('nil', t.evaluate(fact, [], Factbase.new))
48
- end
49
-
50
- def test_past
51
- t = Factbase::Term.new(:prev, [:foo])
52
- assert_nil(t.evaluate(fact('foo' => 4), [], Factbase.new))
53
- assert_equal([4], t.evaluate(fact('foo' => 5), [], Factbase.new))
54
- end
55
-
56
- def test_at
57
- t = Factbase::Term.new(:at, [1, :foo])
58
- assert_nil(t.evaluate(fact('foo' => 4), [], Factbase.new))
59
- assert_equal(5, t.evaluate(fact('foo' => [4, 5]), [], Factbase.new))
60
- end
61
-
62
- def test_report_missing_term
63
- t = Factbase::Term.new(:something, [])
64
- msg = assert_raises(StandardError) do
65
- t.evaluate(fact, [], Factbase.new)
66
- end.message
67
- assert_includes(msg, 'not defined at (something)', msg)
68
- end
69
-
70
- def test_report_other_error
71
- t = Factbase::Term.new(:at, [])
72
- msg = assert_raises(StandardError) do
73
- t.evaluate(fact, [], Factbase.new)
74
- end.message
75
- assert_includes(msg, 'at (at)', msg)
76
- end
77
-
78
- def test_redresses_itself
79
- t = Factbase::Term.new(:something, [])
80
- require_relative '../../lib/factbase/indexed/indexed_term'
81
- t.redress!(Factbase::IndexedTerm)
82
- require_relative '../../lib/factbase/cached/cached_term'
83
- t.redress!(Factbase::CachedTerm)
84
- assert_kind_of(Factbase::CachedTerm, t)
85
- refute_kind_of(Factbase::CachedTerm, Factbase::Term.new(:something, []))
86
- end
87
- end
@@ -1,35 +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 'loog'
8
- require_relative '../../lib/factbase'
9
- require_relative '../../lib/factbase/to_json'
10
-
11
- # Test.
12
- # Author:: Yegor Bugayenko (yegor256@gmail.com)
13
- # Copyright:: Copyright (c) 2024-2025 Yegor Bugayenko
14
- # License:: MIT
15
- class TestToJSON < Factbase::Test
16
- def test_simple_rendering
17
- fb = Factbase.new
18
- f = fb.insert
19
- f.foo = 42
20
- f.foo = 256
21
- to = Factbase::ToJSON.new(fb)
22
- json = JSON.parse(to.json)
23
- assert_equal(256, json[0]['foo'][1])
24
- end
25
-
26
- def test_sort_keys
27
- fb = Factbase.new
28
- f = fb.insert
29
- f.c = 42
30
- f.b = 1
31
- f.a = 256
32
- json = Factbase::ToJSON.new(fb).json
33
- assert_includes(json, '{"a":256,"b":1,"c":42}', json)
34
- end
35
- end
@@ -1,89 +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 'loog'
8
- require_relative '../../lib/factbase'
9
- require_relative '../../lib/factbase/to_xml'
10
-
11
- # Test.
12
- # Author:: Yegor Bugayenko (yegor256@gmail.com)
13
- # Copyright:: Copyright (c) 2024-2025 Yegor Bugayenko
14
- # License:: MIT
15
- class TestToXML < Factbase::Test
16
- def test_simple_rendering
17
- fb = Factbase.new
18
- fb.insert.t = Time.now
19
- to = Factbase::ToXML.new(fb)
20
- xml = Nokogiri::XML.parse(to.xml)
21
- refute_empty(xml.xpath('/fb/f[t]'))
22
- assert_match(
23
- /^[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
24
- )
25
- end
26
-
27
- def test_complex_rendering
28
- fb = Factbase.new
29
- fb.insert.t = "\uffff < > & ' \""
30
- to = Factbase::ToXML.new(fb)
31
- xml = Nokogiri::XML.parse(to.xml)
32
- refute_empty(xml.xpath('/fb/f[t]'))
33
- end
34
-
35
- def test_meta_data_presence
36
- fb = Factbase.new
37
- fb.insert.x = 42
38
- to = Factbase::ToXML.new(fb)
39
- xml = Nokogiri::XML.parse(to.xml)
40
- refute_empty(xml.xpath('/fb[@version]'))
41
- refute_empty(xml.xpath('/fb[@size]'))
42
- end
43
-
44
- def test_to_xml_with_short_names
45
- fb = Factbase.new
46
- f = fb.insert
47
- f.type = 1
48
- f.f = 2
49
- to = Factbase::ToXML.new(fb)
50
- xml = Nokogiri::XML.parse(to.xml)
51
- refute_empty(xml.xpath('/fb/f/type'))
52
- refute_empty(xml.xpath('/fb/f/f'))
53
- end
54
-
55
- def test_show_types_as_attributes
56
- fb = Factbase.new
57
- f = fb.insert
58
- f.a = 42
59
- f.b = 3.14
60
- f.c = 'Hello'
61
- f.d = Time.now
62
- f.e = 'e'
63
- f.e = 4
64
- out = Factbase::ToXML.new(fb).xml
65
- xml = Nokogiri::XML.parse(out)
66
- [
67
- '/fb/f/a[@t="I"]',
68
- '/fb/f/b[@t="F"]',
69
- '/fb/f/c[@t="S"]',
70
- '/fb/f/d[@t="T"]',
71
- '/fb/f/e/v[@t="S"]',
72
- '/fb/f/e/v[@t="I"]'
73
- ].each { |x| refute_empty(xml.xpath(x), out) }
74
- end
75
-
76
- def test_sorts_keys
77
- fb = Factbase.new
78
- f = fb.insert
79
- f.x = 20
80
- f.t = 40
81
- f.a = 10
82
- f.c = 1
83
- to = Factbase::ToXML.new(fb)
84
- xml = Nokogiri::XML.parse(to.xml)
85
- %w[a c t x].each_with_index do |e, i|
86
- refute_empty(xml.xpath("/fb/f/#{e}[count(preceding-sibling::*) = #{i}]"), e)
87
- end
88
- end
89
- end
@@ -1,39 +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 'loog'
8
- require_relative '../../lib/factbase'
9
- require_relative '../../lib/factbase/to_yaml'
10
-
11
- # Test.
12
- # Author:: Yegor Bugayenko (yegor256@gmail.com)
13
- # Copyright:: Copyright (c) 2024-2025 Yegor Bugayenko
14
- # License:: MIT
15
- class TestToYAML < Factbase::Test
16
- def test_simple_rendering
17
- fb = Factbase.new
18
- f = fb.insert
19
- f._id = 1
20
- f.foo = 42
21
- f.foo = 256
22
- fb.insert._id = 2
23
- to = Factbase::ToYAML.new(fb)
24
- yaml = YAML.load(to.yaml)
25
- assert_equal(2, yaml.size)
26
- assert_equal(42, yaml[0]['foo'][0])
27
- assert_equal(256, yaml[0]['foo'][1])
28
- end
29
-
30
- def test_sorts_keys
31
- fb = Factbase.new
32
- f = fb.insert
33
- f.b = 42
34
- f.a = 256
35
- f.c = 10
36
- yaml = Factbase::ToYAML.new(fb).yaml
37
- assert_includes(yaml, "a: 256\n b: 42\n c: 10", yaml)
38
- end
39
- end
data/test/test__helper.rb DELETED
@@ -1,41 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- # SPDX-FileCopyrightText: Copyright (c) 2024-2025 Yegor Bugayenko
4
- # SPDX-License-Identifier: MIT
5
-
6
- $stdout.sync = true
7
-
8
- require 'simplecov'
9
- require 'simplecov-cobertura'
10
- unless SimpleCov.running || ENV['PICKS']
11
- SimpleCov.command_name('test')
12
- SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter.new(
13
- [
14
- SimpleCov::Formatter::HTMLFormatter,
15
- SimpleCov::Formatter::CoberturaFormatter
16
- ]
17
- )
18
- SimpleCov.minimum_coverage 95
19
- SimpleCov.minimum_coverage_by_file 90
20
- SimpleCov.start do
21
- add_filter 'test/'
22
- add_filter 'vendor/'
23
- add_filter 'target/'
24
- track_files 'lib/**/*.rb'
25
- track_files '*.rb'
26
- end
27
- end
28
-
29
- require 'minitest/autorun'
30
- require 'minitest/reporters'
31
- Minitest::Reporters.use! [Minitest::Reporters::SpecReporter.new]
32
-
33
- require_relative '../lib/factbase'
34
-
35
- # Default methods for all tests.
36
- class Factbase::Test < Minitest::Test
37
- def fact(map = {})
38
- require_relative '../lib/factbase/fact'
39
- Factbase::Fact.new(map)
40
- end
41
- end