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.
- checksums.yaml +4 -4
- data/Gemfile.lock +5 -5
- data/factbase.gemspec +4 -4
- data/lib/factbase/fact.rb +1 -1
- data/lib/factbase/fact_as_yaml.rb +10 -1
- data/lib/factbase/indexed/indexed_term.rb +6 -1
- data/lib/factbase/version.rb +1 -1
- metadata +7 -87
- data/.0pdd.yml +0 -8
- data/.gitattributes +0 -7
- data/.github/publish-benchmark.sh +0 -24
- data/.github/workflows/actionlint.yml +0 -25
- data/.github/workflows/benchmark.yml +0 -36
- data/.github/workflows/codecov.yml +0 -27
- data/.github/workflows/copyrights.yml +0 -19
- data/.github/workflows/markdown-lint.yml +0 -23
- data/.github/workflows/pdd.yml +0 -19
- data/.github/workflows/rake.yml +0 -28
- data/.github/workflows/reuse.yml +0 -19
- data/.github/workflows/typos.yml +0 -19
- data/.github/workflows/xcop.yml +0 -19
- data/.github/workflows/yamllint.yml +0 -19
- data/.gitignore +0 -11
- data/.pdd +0 -7
- data/.rubocop.yml +0 -51
- data/.rultor.yml +0 -27
- data/benchmark/bench_factbase.rb +0 -61
- data/benchmark/bench_large_query.rb +0 -128
- data/benchmark/bench_query.rb +0 -57
- data/benchmark/bench_taped.rb +0 -33
- data/fixtures/stories/agg.yml +0 -17
- data/fixtures/stories/always.yml +0 -16
- data/fixtures/stories/and.yml +0 -19
- data/fixtures/stories/as.yml +0 -16
- data/fixtures/stories/count.yml +0 -18
- data/fixtures/stories/empty.yml +0 -23
- data/fixtures/stories/eq.yml +0 -30
- data/fixtures/stories/gt.yml +0 -18
- data/fixtures/stories/join.yml +0 -22
- data/fixtures/stories/max.yml +0 -14
- data/fixtures/stories/min.yml +0 -14
- data/fixtures/stories/nth.yml +0 -14
- data/fixtures/stories/one.yml +0 -14
- data/fixtures/stories/or.yml +0 -18
- data/fixtures/stories/sprintf.yml +0 -12
- data/fixtures/stories/sum.yml +0 -14
- data/fixtures/stories/unique.yml +0 -30
- data/renovate.json +0 -6
- data/test/factbase/cached/test_cached_factbase.rb +0 -44
- data/test/factbase/cached/test_cached_query.rb +0 -100
- data/test/factbase/indexed/test_indexed_fact.rb +0 -23
- data/test/factbase/indexed/test_indexed_factbase.rb +0 -96
- data/test/factbase/indexed/test_indexed_query.rb +0 -208
- data/test/factbase/indexed/test_indexed_term.rb +0 -140
- data/test/factbase/sync/test_sync_factbase.rb +0 -22
- data/test/factbase/sync/test_sync_query.rb +0 -30
- data/test/factbase/terms/test_aggregates.rb +0 -63
- data/test/factbase/terms/test_aliases.rb +0 -58
- data/test/factbase/terms/test_casting.rb +0 -33
- data/test/factbase/terms/test_debug.rb +0 -111
- data/test/factbase/terms/test_defn.rb +0 -48
- data/test/factbase/terms/test_logical.rb +0 -57
- data/test/factbase/terms/test_math.rb +0 -122
- data/test/factbase/terms/test_meta.rb +0 -70
- data/test/factbase/terms/test_ordering.rb +0 -44
- data/test/factbase/terms/test_strings.rb +0 -36
- data/test/factbase/terms/test_system.rb +0 -31
- data/test/factbase/test_accum.rb +0 -74
- data/test/factbase/test_churn.rb +0 -41
- data/test/factbase/test_fact.rb +0 -108
- data/test/factbase/test_fact_as_yaml.rb +0 -77
- data/test/factbase/test_flatten.rb +0 -28
- data/test/factbase/test_impatient.rb +0 -176
- data/test/factbase/test_inv.rb +0 -44
- data/test/factbase/test_logged.rb +0 -155
- data/test/factbase/test_pre.rb +0 -35
- data/test/factbase/test_query.rb +0 -445
- data/test/factbase/test_rules.rb +0 -128
- data/test/factbase/test_syntax.rb +0 -166
- data/test/factbase/test_tallied.rb +0 -81
- data/test/factbase/test_taped.rb +0 -72
- data/test/factbase/test_tee.rb +0 -85
- data/test/factbase/test_term.rb +0 -87
- data/test/factbase/test_to_json.rb +0 -35
- data/test/factbase/test_to_xml.rb +0 -89
- data/test/factbase/test_to_yaml.rb +0 -39
- data/test/test__helper.rb +0 -41
- data/test/test_factbase.rb +0 -509
data/test/factbase/test_accum.rb
DELETED
@@ -1,74 +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/fact'
|
10
|
-
|
11
|
-
def global_function_for_this_test_only(foo)
|
12
|
-
raise foo
|
13
|
-
end
|
14
|
-
|
15
|
-
# Accum test.
|
16
|
-
# Author:: Yegor Bugayenko (yegor256@gmail.com)
|
17
|
-
# Copyright:: Copyright (c) 2024-2025 Yegor Bugayenko
|
18
|
-
# License:: MIT
|
19
|
-
class TestAccum < Factbase::Test
|
20
|
-
def test_holds_props
|
21
|
-
map = {}
|
22
|
-
f = Factbase::Fact.new(map)
|
23
|
-
props = {}
|
24
|
-
a = Factbase::Accum.new(f, props, false)
|
25
|
-
a.foo = 42
|
26
|
-
assert_raises(StandardError) { f.foo }
|
27
|
-
assert_equal(42, a.foo)
|
28
|
-
assert_equal([42], props['foo'])
|
29
|
-
end
|
30
|
-
|
31
|
-
def test_fetches_without_conflict_with_global_name
|
32
|
-
t = Factbase::Accum.new(
|
33
|
-
Factbase::Fact.new({ 'global_function_for_this_test_only' => [2] }),
|
34
|
-
{}, true
|
35
|
-
)
|
36
|
-
assert_equal(2, t.global_function_for_this_test_only)
|
37
|
-
end
|
38
|
-
|
39
|
-
def test_passes_props
|
40
|
-
map = {}
|
41
|
-
f = Factbase::Fact.new(map)
|
42
|
-
props = {}
|
43
|
-
a = Factbase::Accum.new(f, props, true)
|
44
|
-
a.foo = 42
|
45
|
-
assert_equal(42, f.foo)
|
46
|
-
assert_equal(42, a.foo)
|
47
|
-
assert_equal([42], props['foo'])
|
48
|
-
end
|
49
|
-
|
50
|
-
def test_appends_props
|
51
|
-
map = {}
|
52
|
-
f = Factbase::Fact.new(map)
|
53
|
-
f.foo = 42
|
54
|
-
props = {}
|
55
|
-
a = Factbase::Accum.new(f, props, false)
|
56
|
-
a.foo = 55
|
57
|
-
assert_equal(2, a['foo'].size)
|
58
|
-
end
|
59
|
-
|
60
|
-
def test_empties
|
61
|
-
f = Factbase::Fact.new({})
|
62
|
-
a = Factbase::Accum.new(f, {}, false)
|
63
|
-
assert_nil(a['foo'])
|
64
|
-
end
|
65
|
-
|
66
|
-
def test_prints_to_string
|
67
|
-
map = {}
|
68
|
-
f = Factbase::Fact.new(map)
|
69
|
-
props = {}
|
70
|
-
a = Factbase::Accum.new(f, props, true)
|
71
|
-
a.foo = 42
|
72
|
-
assert_equal('[ foo: [42] ]', f.to_s)
|
73
|
-
end
|
74
|
-
end
|
data/test/factbase/test_churn.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
|
-
require_relative '../test__helper'
|
7
|
-
require 'loog'
|
8
|
-
require_relative '../../lib/factbase'
|
9
|
-
require_relative '../../lib/factbase/churn'
|
10
|
-
|
11
|
-
# Test.
|
12
|
-
# Author:: Yegor Bugayenko (yegor256@gmail.com)
|
13
|
-
# Copyright:: Copyright (c) 2024-2025 Yegor Bugayenko
|
14
|
-
# License:: MIT
|
15
|
-
class TestChurn < Factbase::Test
|
16
|
-
def test_appends
|
17
|
-
c = Factbase::Churn.new
|
18
|
-
c.append(1, 2, 3)
|
19
|
-
assert_equal('1i/2d/3a', c.to_s)
|
20
|
-
assert_equal(6, c.to_i)
|
21
|
-
end
|
22
|
-
|
23
|
-
def test_checks_for_zero
|
24
|
-
c = Factbase::Churn.new
|
25
|
-
assert_predicate(c, :zero?)
|
26
|
-
end
|
27
|
-
|
28
|
-
def test_makes_a_duplicate
|
29
|
-
c = Factbase::Churn.new
|
30
|
-
assert_predicate(c.dup, :zero?)
|
31
|
-
end
|
32
|
-
|
33
|
-
def test_concatenates_with_other
|
34
|
-
c1 = Factbase::Churn.new
|
35
|
-
c1.append(1, 6, 3)
|
36
|
-
c2 = Factbase::Churn.new
|
37
|
-
c2.append(3, 2, 46)
|
38
|
-
c3 = c1 + c2
|
39
|
-
assert_equal('4i/8d/49a', c3.to_s)
|
40
|
-
end
|
41
|
-
end
|
data/test/factbase/test_fact.rb
DELETED
@@ -1,108 +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/fact'
|
9
|
-
|
10
|
-
# Fact test.
|
11
|
-
# Author:: Yegor Bugayenko (yegor256@gmail.com)
|
12
|
-
# Copyright:: Copyright (c) 2024-2025 Yegor Bugayenko
|
13
|
-
# License:: MIT
|
14
|
-
class TestFact < Factbase::Test
|
15
|
-
def test_injects_data_correctly
|
16
|
-
map = {}
|
17
|
-
f = Factbase::Fact.new(map)
|
18
|
-
f.foo_bar = 1
|
19
|
-
f.bar = 2
|
20
|
-
f.bar = 3
|
21
|
-
assert_equal(2, map.size)
|
22
|
-
assert_equal([1], map['foo_bar'])
|
23
|
-
assert_equal([2, 3], map['bar'])
|
24
|
-
end
|
25
|
-
|
26
|
-
def test_simple_resetting
|
27
|
-
map = {}
|
28
|
-
f = Factbase::Fact.new(map)
|
29
|
-
f.foo = 42
|
30
|
-
assert_equal(42, f.foo, f.to_s)
|
31
|
-
f.foo = 256
|
32
|
-
assert_equal(42, f.foo, f.to_s)
|
33
|
-
assert_equal([42, 256], f['foo'], f.to_s)
|
34
|
-
end
|
35
|
-
|
36
|
-
def test_keeps_values_unique
|
37
|
-
map = {}
|
38
|
-
f = Factbase::Fact.new(map)
|
39
|
-
f.foo = 42
|
40
|
-
f.foo = 'Hello'
|
41
|
-
assert_equal(2, map['foo'].size)
|
42
|
-
f.foo = 42
|
43
|
-
assert_equal(2, map['foo'].size)
|
44
|
-
end
|
45
|
-
|
46
|
-
def test_fails_when_empty
|
47
|
-
f = Factbase::Fact.new({})
|
48
|
-
assert_raises(StandardError) do
|
49
|
-
f.something
|
50
|
-
end
|
51
|
-
end
|
52
|
-
|
53
|
-
def test_fails_when_setting_nil
|
54
|
-
f = Factbase::Fact.new({})
|
55
|
-
assert_raises(StandardError) do
|
56
|
-
f.foo = nil
|
57
|
-
end
|
58
|
-
end
|
59
|
-
|
60
|
-
def test_fails_when_setting_empty
|
61
|
-
f = Factbase::Fact.new({})
|
62
|
-
assert_raises(StandardError) do
|
63
|
-
f.foo = ''
|
64
|
-
end
|
65
|
-
end
|
66
|
-
|
67
|
-
def test_fails_when_not_found
|
68
|
-
f = Factbase::Fact.new({})
|
69
|
-
f.first = 42
|
70
|
-
assert_raises(StandardError) do
|
71
|
-
f.second
|
72
|
-
end
|
73
|
-
end
|
74
|
-
|
75
|
-
def test_set_by_name
|
76
|
-
f = Factbase::Fact.new({})
|
77
|
-
f.send(:_foo_bar=, 42)
|
78
|
-
assert_equal(42, f._foo_bar, f.to_s)
|
79
|
-
end
|
80
|
-
|
81
|
-
def test_set_twice_same_value
|
82
|
-
map = {}
|
83
|
-
f = Factbase::Fact.new(map)
|
84
|
-
f.foo = 42
|
85
|
-
f.foo = 42
|
86
|
-
assert_equal([42], map['foo'])
|
87
|
-
end
|
88
|
-
|
89
|
-
def test_time_in_utc
|
90
|
-
f = Factbase::Fact.new({})
|
91
|
-
t = Time.now
|
92
|
-
f.foo = t
|
93
|
-
assert_equal(t.utc, f.foo)
|
94
|
-
assert_equal(t.utc.to_s, f.foo.to_s)
|
95
|
-
end
|
96
|
-
|
97
|
-
def test_some_names_are_prohibited
|
98
|
-
f = Factbase::Fact.new({})
|
99
|
-
assert_raises(StandardError) { f.to_s = 42 }
|
100
|
-
assert_raises(StandardError) { f.class = 42 }
|
101
|
-
end
|
102
|
-
|
103
|
-
def test_get_all_properties
|
104
|
-
f = Factbase::Fact.new({})
|
105
|
-
f.foo = 42
|
106
|
-
assert_includes(f.all_properties, 'foo')
|
107
|
-
end
|
108
|
-
end
|
@@ -1,77 +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 'yaml'
|
7
|
-
require_relative '../../lib/factbase'
|
8
|
-
require_relative '../../lib/factbase/fact_as_yaml'
|
9
|
-
require_relative '../test__helper'
|
10
|
-
|
11
|
-
# Test.
|
12
|
-
# Author:: Yegor Bugayenko (yegor256@gmail.com)
|
13
|
-
# Copyright:: Copyright (c) 2024-2025 Yegor Bugayenko
|
14
|
-
# License:: MIT
|
15
|
-
class TestFactAsYaml < Factbase::Test
|
16
|
-
def test_prints_exactly
|
17
|
-
fb = Factbase.new
|
18
|
-
f = fb.insert
|
19
|
-
f._id = 1
|
20
|
-
f.foo = 42
|
21
|
-
f.foo = 33
|
22
|
-
f.bar = 'hello, world! how are you?'
|
23
|
-
assert_equal(
|
24
|
-
"_id: [1]\n" \
|
25
|
-
"bar: [\"hello, world! how are you?\"]\n" \
|
26
|
-
'foo: [42, 33]',
|
27
|
-
Factbase::FactAsYaml.new(f).to_s
|
28
|
-
)
|
29
|
-
end
|
30
|
-
|
31
|
-
def test_simple_rendering
|
32
|
-
fb = Factbase.new
|
33
|
-
f = fb.insert
|
34
|
-
f._id = 1
|
35
|
-
f.foo = 42
|
36
|
-
f.bar = 'hello'
|
37
|
-
yaml_str = Factbase::FactAsYaml.new(f).to_s
|
38
|
-
yaml = YAML.load(yaml_str)
|
39
|
-
assert_equal(1, yaml['_id'][0])
|
40
|
-
assert_equal('hello', yaml['bar'][0])
|
41
|
-
assert_equal(42, yaml['foo'][0])
|
42
|
-
end
|
43
|
-
|
44
|
-
def test_multiple_values
|
45
|
-
fb = Factbase.new
|
46
|
-
f = fb.insert
|
47
|
-
f.foo = 42
|
48
|
-
f.foo = 256
|
49
|
-
f.foo = 512
|
50
|
-
yaml_str = Factbase::FactAsYaml.new(f).to_s
|
51
|
-
yaml = YAML.load(yaml_str)
|
52
|
-
assert_equal([42, 256, 512], yaml['foo'])
|
53
|
-
end
|
54
|
-
|
55
|
-
def test_sorted_keys
|
56
|
-
fb = Factbase.new
|
57
|
-
f = fb.insert
|
58
|
-
f.c = 3
|
59
|
-
f.a = 1
|
60
|
-
f.b = 2
|
61
|
-
yaml_str = Factbase::FactAsYaml.new(f).to_s
|
62
|
-
assert_operator(yaml_str.index('a:'), :<, yaml_str.index('b:'))
|
63
|
-
assert_operator(yaml_str.index('b:'), :<, yaml_str.index('c:'))
|
64
|
-
end
|
65
|
-
|
66
|
-
def test_usage_example_from_issue
|
67
|
-
fb = Factbase.new
|
68
|
-
f = fb.insert
|
69
|
-
f._id = 1
|
70
|
-
f.name = 'test'
|
71
|
-
f = fb.query('(eq _id 1)').each.to_a.first
|
72
|
-
yaml_str = Factbase::FactAsYaml.new(f).to_s
|
73
|
-
assert(yaml_str)
|
74
|
-
assert_includes(yaml_str, '_id')
|
75
|
-
assert_includes(yaml_str, 'name')
|
76
|
-
end
|
77
|
-
end
|
@@ -1,28 +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/flatten'
|
9
|
-
|
10
|
-
# Test.
|
11
|
-
# Author:: Yegor Bugayenko (yegor256@gmail.com)
|
12
|
-
# Copyright:: Copyright (c) 2024-2025 Yegor Bugayenko
|
13
|
-
# License:: MIT
|
14
|
-
class TestFlatten < Factbase::Test
|
15
|
-
def test_mapping
|
16
|
-
maps = [{ 'b' => [42], 'i' => 1 }, { 'a' => 33, 'i' => 0 }, { 'c' => %w[hey you], 'i' => 2 }]
|
17
|
-
to = Factbase::Flatten.new(maps, 'i').it
|
18
|
-
assert_equal(33, to[0]['a'])
|
19
|
-
assert_equal(42, to[1]['b'])
|
20
|
-
assert_equal(2, to[2]['c'].size)
|
21
|
-
end
|
22
|
-
|
23
|
-
def test_without_sorter
|
24
|
-
maps = [{ 'b' => [42], 'i' => [44] }, { 'a' => 33 }]
|
25
|
-
to = Factbase::Flatten.new(maps, 'i').it
|
26
|
-
assert_equal(33, to[0]['a'])
|
27
|
-
end
|
28
|
-
end
|
@@ -1,176 +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/query'
|
9
|
-
require_relative '../../lib/factbase/impatient'
|
10
|
-
|
11
|
-
# Test.
|
12
|
-
# Author:: Yegor Bugayenko (yegor256@gmail.com)
|
13
|
-
# Copyright:: Copyright (c) 2024-2025 Yegor Bugayenko
|
14
|
-
# License:: MIT
|
15
|
-
class TestImpatient < Factbase::Test
|
16
|
-
class SlowFactbase < Factbase
|
17
|
-
class SlowQuery < Factbase::Query
|
18
|
-
def one(fb = @fb, params = {})
|
19
|
-
sleep 0.2
|
20
|
-
super
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
|
-
def query(term, maps = nil)
|
25
|
-
maps ||= @maps
|
26
|
-
term = to_term(term) if term.is_a?(String)
|
27
|
-
SlowQuery.new(maps, term, self)
|
28
|
-
end
|
29
|
-
end
|
30
|
-
|
31
|
-
class SlowDeleteFactbase < Factbase
|
32
|
-
class SlowQuery < Factbase::Query
|
33
|
-
def delete!(fb = @fb)
|
34
|
-
sleep 0.2
|
35
|
-
super
|
36
|
-
end
|
37
|
-
end
|
38
|
-
|
39
|
-
def query(term, maps = nil)
|
40
|
-
maps ||= @maps
|
41
|
-
term = to_term(term) if term.is_a?(String)
|
42
|
-
SlowQuery.new(maps, term, self)
|
43
|
-
end
|
44
|
-
end
|
45
|
-
|
46
|
-
class SlowEnoughFactbase < Factbase
|
47
|
-
class SlowQuery < Factbase::Query
|
48
|
-
def one(fb = @fb, params = {})
|
49
|
-
sleep 1.5
|
50
|
-
super
|
51
|
-
end
|
52
|
-
end
|
53
|
-
|
54
|
-
def query(term, maps = nil)
|
55
|
-
maps ||= @maps
|
56
|
-
term = to_term(term) if term.is_a?(String)
|
57
|
-
SlowQuery.new(maps, term, self)
|
58
|
-
end
|
59
|
-
end
|
60
|
-
|
61
|
-
def test_simple_query
|
62
|
-
fb = Factbase::Impatient.new(Factbase.new)
|
63
|
-
fb.insert
|
64
|
-
fb.insert.bar = 3
|
65
|
-
found = 0
|
66
|
-
fb.query('(exists bar)').each do |f|
|
67
|
-
assert_predicate(f.bar, :positive?)
|
68
|
-
f.foo = 42
|
69
|
-
assert_equal(42, f.foo)
|
70
|
-
found += 1
|
71
|
-
end
|
72
|
-
assert_equal(1, found)
|
73
|
-
assert_equal(2, fb.size)
|
74
|
-
end
|
75
|
-
|
76
|
-
def test_query_one
|
77
|
-
fb = Factbase::Impatient.new(Factbase.new)
|
78
|
-
fb.insert
|
79
|
-
fb.insert.bar = 42
|
80
|
-
assert_equal(1, fb.query('(agg (exists bar) (count))').one)
|
81
|
-
assert_equal([42], fb.query('(agg (exists bar) (first bar))').one)
|
82
|
-
end
|
83
|
-
|
84
|
-
def test_query_one_timeout
|
85
|
-
slow = SlowFactbase.new
|
86
|
-
10_000.times do
|
87
|
-
slow.insert.value = rand(1000)
|
88
|
-
end
|
89
|
-
fb = Factbase::Impatient.new(slow, timeout: 0.01)
|
90
|
-
ex =
|
91
|
-
assert_raises(StandardError) do
|
92
|
-
fb.query('(agg (min value))').one
|
93
|
-
end
|
94
|
-
assert_includes(ex.message, 'timed out after')
|
95
|
-
end
|
96
|
-
|
97
|
-
def test_delete_timeout
|
98
|
-
slow = SlowDeleteFactbase.new
|
99
|
-
1000.times do |i|
|
100
|
-
slow.insert.value = i
|
101
|
-
end
|
102
|
-
fb = Factbase::Impatient.new(slow, timeout: 0.01)
|
103
|
-
ex =
|
104
|
-
assert_raises(StandardError) do
|
105
|
-
fb.query('(gt value 500)').delete!
|
106
|
-
end
|
107
|
-
assert_includes(ex.message, 'timed out after')
|
108
|
-
end
|
109
|
-
|
110
|
-
def test_with_txn
|
111
|
-
fb = Factbase::Impatient.new(Factbase.new)
|
112
|
-
assert(
|
113
|
-
fb.txn do |fbt|
|
114
|
-
fbt.insert.foo = 42
|
115
|
-
end
|
116
|
-
)
|
117
|
-
assert_equal(1, fb.size)
|
118
|
-
end
|
119
|
-
|
120
|
-
def test_returns_int
|
121
|
-
fb = Factbase.new
|
122
|
-
fb.insert
|
123
|
-
fb.insert
|
124
|
-
assert_equal(2, Factbase::Impatient.new(fb).query('(always)').each(&:to_s))
|
125
|
-
end
|
126
|
-
|
127
|
-
def test_returns_int_when_empty
|
128
|
-
fb = Factbase.new
|
129
|
-
assert_equal(0, Factbase::Impatient.new(fb).query('(always)').each(&:to_s))
|
130
|
-
end
|
131
|
-
|
132
|
-
def test_returns_to_s_correctly
|
133
|
-
fb = Factbase.new
|
134
|
-
q = '(always)'
|
135
|
-
assert_equal(q, fb.query(q).to_s)
|
136
|
-
end
|
137
|
-
|
138
|
-
def test_enumerator_support
|
139
|
-
fb = Factbase::Impatient.new(Factbase.new)
|
140
|
-
assert_equal(0, fb.query('(always)').each.to_a.size)
|
141
|
-
fb.insert
|
142
|
-
assert_equal(1, fb.query('(always)').each.to_a.size)
|
143
|
-
end
|
144
|
-
|
145
|
-
def test_query_completes_before_timeout
|
146
|
-
fb = Factbase::Impatient.new(Factbase.new, timeout: 1)
|
147
|
-
100.times do |i|
|
148
|
-
fb.insert.index = i
|
149
|
-
end
|
150
|
-
count = 0
|
151
|
-
fb.query('(always)').each do |f|
|
152
|
-
count += 1
|
153
|
-
assert_equal(count - 1, f.index)
|
154
|
-
end
|
155
|
-
assert_equal(100, count)
|
156
|
-
end
|
157
|
-
|
158
|
-
def test_custom_timeout
|
159
|
-
slow = SlowEnoughFactbase.new
|
160
|
-
slow.insert.value = 42
|
161
|
-
fb = Factbase::Impatient.new(slow, timeout: 2)
|
162
|
-
start = Time.now
|
163
|
-
result = fb.query('(agg (eq value 42) (first value))').one
|
164
|
-
elapsed = Time.now - start
|
165
|
-
assert_operator(elapsed, :>=, 1.5)
|
166
|
-
assert_equal([42], result)
|
167
|
-
end
|
168
|
-
|
169
|
-
def test_nil_factbase_raises
|
170
|
-
ex =
|
171
|
-
assert_raises(StandardError) do
|
172
|
-
Factbase::Impatient.new(nil)
|
173
|
-
end
|
174
|
-
assert_equal('The "fb" is nil', ex.message)
|
175
|
-
end
|
176
|
-
end
|
data/test/factbase/test_inv.rb
DELETED
@@ -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 'loog'
|
8
|
-
require_relative '../../lib/factbase'
|
9
|
-
require_relative '../../lib/factbase/inv'
|
10
|
-
require_relative '../../lib/factbase/pre'
|
11
|
-
|
12
|
-
# Test.
|
13
|
-
# Author:: Yegor Bugayenko (yegor256@gmail.com)
|
14
|
-
# Copyright:: Copyright (c) 2024-2025 Yegor Bugayenko
|
15
|
-
# License:: MIT
|
16
|
-
class TestInv < Factbase::Test
|
17
|
-
def test_simple_checking
|
18
|
-
fb =
|
19
|
-
Factbase::Inv.new(Factbase.new) do |p, v|
|
20
|
-
raise 'oops' if v.is_a?(String) && p == 'b'
|
21
|
-
end
|
22
|
-
f = fb.insert
|
23
|
-
f.a = 42
|
24
|
-
assert_raises(StandardError) do
|
25
|
-
f.b = 'here we should crash'
|
26
|
-
end
|
27
|
-
f.c = 256
|
28
|
-
assert_equal(42, f.a)
|
29
|
-
assert_equal(1, fb.query('(always)').each.to_a.size)
|
30
|
-
end
|
31
|
-
|
32
|
-
def test_pre_and_inv
|
33
|
-
fb =
|
34
|
-
Factbase::Inv.new(Factbase.new) do |p, v|
|
35
|
-
raise 'oops' if v.is_a?(String) && p == 'b'
|
36
|
-
end
|
37
|
-
fb =
|
38
|
-
Factbase::Pre.new(fb) do |f|
|
39
|
-
f.id = 42
|
40
|
-
end
|
41
|
-
f = fb.insert
|
42
|
-
assert_equal(42, f.id)
|
43
|
-
end
|
44
|
-
end
|
@@ -1,155 +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/logged'
|
10
|
-
require_relative '../../lib/factbase/cached/cached_factbase'
|
11
|
-
|
12
|
-
# Test.
|
13
|
-
# Author:: Yegor Bugayenko (yegor256@gmail.com)
|
14
|
-
# Copyright:: Copyright (c) 2024-2025 Yegor Bugayenko
|
15
|
-
# License:: MIT
|
16
|
-
class TestLogged < Factbase::Test
|
17
|
-
def test_simple_setting
|
18
|
-
fb = Factbase::Logged.new(Factbase.new, Loog::NULL)
|
19
|
-
fb.insert
|
20
|
-
fb.insert.bar = 3
|
21
|
-
found = 0
|
22
|
-
fb.query('(exists bar)').each do |f|
|
23
|
-
assert_predicate(f.bar, :positive?)
|
24
|
-
f.foo = 42
|
25
|
-
assert_equal(42, f.foo)
|
26
|
-
found += 1
|
27
|
-
end
|
28
|
-
assert_equal(1, found)
|
29
|
-
assert_equal(2, fb.size)
|
30
|
-
end
|
31
|
-
|
32
|
-
def test_reading_one
|
33
|
-
fb = Factbase::Logged.new(Factbase.new, Loog::NULL)
|
34
|
-
fb.insert
|
35
|
-
fb.insert.bar = 42
|
36
|
-
assert_equal(1, fb.query('(agg (exists bar) (count))').one)
|
37
|
-
assert_equal([42], fb.query('(agg (exists bar) (first bar))').one)
|
38
|
-
end
|
39
|
-
|
40
|
-
def test_avoid_inner_logging
|
41
|
-
buf = Loog::Buffer.new
|
42
|
-
fb = Factbase.new
|
43
|
-
fb.insert
|
44
|
-
fb.insert.bar = 42
|
45
|
-
fb = Factbase::Logged.new(Factbase::CachedFactbase.new(fb), buf)
|
46
|
-
fb.query('(agg (exists bar) (count))').one
|
47
|
-
fb.query('(join "foo<=bar" (exists bar))').each.to_a
|
48
|
-
refute_includes(buf.to_s, '\'(count)\'')
|
49
|
-
refute_includes(buf.to_s, '\'(exists bar)\'')
|
50
|
-
end
|
51
|
-
|
52
|
-
def test_with_txn
|
53
|
-
log = Loog::Buffer.new
|
54
|
-
fb = Factbase::Logged.new(Factbase.new, log)
|
55
|
-
assert(
|
56
|
-
fb.txn do |fbt|
|
57
|
-
fbt.insert.foo = 42
|
58
|
-
end
|
59
|
-
)
|
60
|
-
assert_equal(1, fb.size)
|
61
|
-
assert_includes(log.to_s, 'touched', log)
|
62
|
-
end
|
63
|
-
|
64
|
-
def test_with_slow_txn
|
65
|
-
log = Loog::Buffer.new
|
66
|
-
fb = Factbase::Logged.new(Factbase.new, log, time_tolerate: 0.1)
|
67
|
-
fb.txn { sleep 0.4 }
|
68
|
-
assert_includes(log.to_s, '(slow!)', log)
|
69
|
-
end
|
70
|
-
|
71
|
-
def test_with_txn_rollback
|
72
|
-
log = Loog::Buffer.new
|
73
|
-
fb = Factbase::Logged.new(Factbase.new, log)
|
74
|
-
assert_equal(0, fb.txn { raise Factbase::Rollback })
|
75
|
-
assert_equal(0, fb.size)
|
76
|
-
assert_includes(log.to_s, 'rolled back', log)
|
77
|
-
refute_includes(log.to_s, 'didn\'t touch', log)
|
78
|
-
end
|
79
|
-
|
80
|
-
def test_with_modifying_txn
|
81
|
-
log = Loog::Buffer.new
|
82
|
-
fb = Factbase::Logged.new(Factbase.new, log)
|
83
|
-
fb.insert.foo = 1
|
84
|
-
assert_equal(0, fb.txn { |fbt| fbt.query('(always)').each.to_a }.to_i, log)
|
85
|
-
assert_equal(1, fb.txn { |fbt| fbt.query('(always)').each.to_a[0].foo = 42 }.to_i)
|
86
|
-
assert_includes(log.to_s, 'touched', log)
|
87
|
-
end
|
88
|
-
|
89
|
-
def test_with_empty_txn
|
90
|
-
log = Loog::Buffer.new
|
91
|
-
fb = Factbase::Logged.new(Factbase.new, log)
|
92
|
-
assert_equal(0, fb.txn { |fbt| fbt.query('(always)').each.to_a }.to_i)
|
93
|
-
assert_includes(log.to_s, 'touched', log)
|
94
|
-
end
|
95
|
-
|
96
|
-
def test_returns_int
|
97
|
-
fb = Factbase.new
|
98
|
-
fb.insert
|
99
|
-
fb.insert
|
100
|
-
assert_equal(2, Factbase::Logged.new(fb, Loog::NULL).query('(always)').each(&:to_s))
|
101
|
-
end
|
102
|
-
|
103
|
-
def test_returns_int_when_empty
|
104
|
-
fb = Factbase.new
|
105
|
-
assert_equal(0, Factbase::Logged.new(fb, Loog::NULL).query('(always)').each(&:to_s))
|
106
|
-
end
|
107
|
-
|
108
|
-
def test_returns_to_s_correctly
|
109
|
-
fb = Factbase.new
|
110
|
-
q = '(always)'
|
111
|
-
assert_equal(q, fb.query(q).to_s)
|
112
|
-
end
|
113
|
-
|
114
|
-
def test_logs_when_enumerator
|
115
|
-
fb = Factbase::Logged.new(Factbase.new, Loog::NULL)
|
116
|
-
assert_equal(0, fb.query('(always)').each.to_a.size)
|
117
|
-
fb.insert
|
118
|
-
assert_equal(1, fb.query('(always)').each.to_a.size)
|
119
|
-
end
|
120
|
-
|
121
|
-
def test_proper_logging
|
122
|
-
log = Loog::Buffer.new
|
123
|
-
fb = Factbase::Logged.new(Factbase.new, log)
|
124
|
-
fb.insert
|
125
|
-
fb.insert.bar = 3
|
126
|
-
fb.insert
|
127
|
-
fb.insert.str =
|
128
|
-
"Он поскорей звонит. Вбегает
|
129
|
-
К нему слуга француз Гильо,
|
130
|
-
Халат и туфли предлагает
|
131
|
-
И подает ему белье.
|
132
|
-
Спешит Онегин одеваться,
|
133
|
-
Слуге велит приготовляться
|
134
|
-
С ним вместе ехать и с собой
|
135
|
-
Взять также ящик боевой.
|
136
|
-
Готовы санки беговые.
|
137
|
-
Он сел, на мельницу летит.
|
138
|
-
Примчались. Он слуге велит
|
139
|
-
Лепажа стволы роковые
|
140
|
-
Нести за ним, а лошадям
|
141
|
-
Отъехать в поле к двум дубкам."
|
142
|
-
fb.query('(exists bar)').each(&:to_s)
|
143
|
-
fb.query('(not (exists bar))').delete!
|
144
|
-
[
|
145
|
-
'Inserted new fact #1',
|
146
|
-
'Inserted new fact #2',
|
147
|
-
'Set \'bar\' to 3 (Integer)',
|
148
|
-
'Set \'str\' to "Он поскорей звонит. Вбегает\n ... Отъехать в поле к двум дубкам." (String)',
|
149
|
-
'Found 1/4 fact(s) by \'(exists bar)\'',
|
150
|
-
'Deleted 3 fact(s) out of 4 by \'(not (exists bar))\''
|
151
|
-
].each do |s|
|
152
|
-
assert_includes(log.to_s, s, "#{log}\n")
|
153
|
-
end
|
154
|
-
end
|
155
|
-
end
|