factbase 0.0.50 → 0.0.51
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 +1 -1
- data/Gemfile.lock +13 -20
- data/README.md +52 -35
- data/factbase.gemspec +1 -0
- data/lib/factbase/{tuples.rb → accum.rb} +39 -40
- data/lib/factbase/fact.rb +4 -9
- data/lib/factbase/looged.rb +1 -2
- data/lib/factbase/query.rb +7 -2
- data/lib/factbase/syntax.rb +2 -2
- data/lib/factbase/tee.rb +57 -0
- data/lib/factbase/term.rb +32 -278
- data/lib/factbase/terms/aggregates.rb +102 -0
- data/lib/factbase/terms/aliases.rb +56 -0
- data/lib/factbase/terms/debug.rb +39 -0
- data/lib/factbase/terms/defn.rb +54 -0
- data/lib/factbase/terms/logical.rb +95 -0
- data/lib/factbase/terms/math.rb +91 -0
- data/lib/factbase/terms/meta.rb +73 -0
- data/lib/factbase/terms/ordering.rb +51 -0
- data/lib/factbase/terms/strings.rb +41 -0
- data/lib/factbase/to_xml.rb +6 -2
- data/lib/factbase.rb +3 -1
- data/test/factbase/terms/test_aggregates.rb +62 -0
- data/test/factbase/terms/test_aliases.rb +76 -0
- data/test/factbase/terms/test_math.rb +99 -0
- data/test/factbase/test_accum.rb +70 -0
- data/test/factbase/test_query.rb +23 -8
- data/test/factbase/test_syntax.rb +1 -1
- data/test/factbase/test_tee.rb +43 -0
- data/test/factbase/test_term.rb +7 -76
- data/test/factbase/test_to_xml.rb +26 -2
- data/test/test_factbase.rb +3 -3
- metadata +32 -4
- data/test/factbase/test_tuples.rb +0 -106
@@ -43,7 +43,7 @@ class TestSyntax < Minitest::Test
|
|
43
43
|
[
|
44
44
|
'(foo)',
|
45
45
|
'(foo (bar) (zz 77) ) # hey',
|
46
|
-
"# hello\n\n\n(foo (bar))",
|
46
|
+
"# hello\n\n\n(foo ($bar))",
|
47
47
|
"(eq foo \n\n 'Hello, world!'\n)\n",
|
48
48
|
"(eq x 'Hello, \\' \n) \\' ( world!')",
|
49
49
|
"# this is a comment\n(eq foo # test\n 42)\n\n# another comment\n",
|
@@ -0,0 +1,43 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Copyright (c) 2024 Yegor Bugayenko
|
4
|
+
#
|
5
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
# of this software and associated documentation files (the 'Software'), to deal
|
7
|
+
# in the Software without restriction, including without limitation the rights
|
8
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
# copies of the Software, and to permit persons to whom the Software is
|
10
|
+
# furnished to do so, subject to the following conditions:
|
11
|
+
#
|
12
|
+
# The above copyright notice and this permission notice shall be included in all
|
13
|
+
# copies or substantial portions of the Software.
|
14
|
+
#
|
15
|
+
# THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
21
|
+
# SOFTWARE.
|
22
|
+
|
23
|
+
require 'minitest/autorun'
|
24
|
+
require_relative '../../lib/factbase'
|
25
|
+
require_relative '../../lib/factbase/tee'
|
26
|
+
require_relative '../../lib/factbase/fact'
|
27
|
+
|
28
|
+
# Tee test.
|
29
|
+
# Author:: Yegor Bugayenko (yegor256@gmail.com)
|
30
|
+
# Copyright:: Copyright (c) 2024 Yegor Bugayenko
|
31
|
+
# License:: MIT
|
32
|
+
class TestTee < Minitest::Test
|
33
|
+
def test_two_facts
|
34
|
+
map = {}
|
35
|
+
prim = Factbase::Fact.new(Mutex.new, map)
|
36
|
+
prim.foo = 42
|
37
|
+
upper = Factbase::Fact.new(Mutex.new, map)
|
38
|
+
upper.bar = 13
|
39
|
+
t = Factbase::Tee.new(prim, upper)
|
40
|
+
assert_equal(42, t.foo)
|
41
|
+
assert_equal([13], t['$bar'])
|
42
|
+
end
|
43
|
+
end
|
data/test/factbase/test_term.rb
CHANGED
@@ -22,67 +22,12 @@
|
|
22
22
|
|
23
23
|
require 'minitest/autorun'
|
24
24
|
require_relative '../../lib/factbase/term'
|
25
|
-
require_relative '../../lib/factbase/syntax'
|
26
25
|
|
27
26
|
# Term test.
|
28
27
|
# Author:: Yegor Bugayenko (yegor256@gmail.com)
|
29
28
|
# Copyright:: Copyright (c) 2024 Yegor Bugayenko
|
30
29
|
# License:: MIT
|
31
30
|
class TestTerm < Minitest::Test
|
32
|
-
def test_simple_matching
|
33
|
-
t = Factbase::Term.new(:eq, [:foo, 42])
|
34
|
-
assert(t.evaluate(fact('foo' => [42]), []))
|
35
|
-
assert(!t.evaluate(fact('foo' => 'Hello!'), []))
|
36
|
-
assert(!t.evaluate(fact('bar' => ['Hello!']), []))
|
37
|
-
end
|
38
|
-
|
39
|
-
def test_eq_matching
|
40
|
-
t = Factbase::Term.new(:eq, [:foo, 42])
|
41
|
-
assert(t.evaluate(fact('foo' => 42), []))
|
42
|
-
assert(t.evaluate(fact('foo' => [10, 5, 6, -8, 'hey', 42, 9, 'fdsf']), []))
|
43
|
-
assert(!t.evaluate(fact('foo' => [100]), []))
|
44
|
-
assert(!t.evaluate(fact('foo' => []), []))
|
45
|
-
assert(!t.evaluate(fact('bar' => []), []))
|
46
|
-
end
|
47
|
-
|
48
|
-
def test_eq_matching_time
|
49
|
-
now = Time.now
|
50
|
-
t = Factbase::Term.new(:eq, [:foo, Time.parse(now.iso8601)])
|
51
|
-
assert(t.evaluate(fact('foo' => now), []))
|
52
|
-
assert(t.evaluate(fact('foo' => [now, Time.now]), []))
|
53
|
-
end
|
54
|
-
|
55
|
-
def test_lt_matching
|
56
|
-
t = Factbase::Term.new(:lt, [:foo, 42])
|
57
|
-
assert(t.evaluate(fact('foo' => [10]), []))
|
58
|
-
assert(!t.evaluate(fact('foo' => [100]), []))
|
59
|
-
assert(!t.evaluate(fact('foo' => 100), []))
|
60
|
-
assert(!t.evaluate(fact('bar' => 100), []))
|
61
|
-
end
|
62
|
-
|
63
|
-
def test_gt_matching
|
64
|
-
t = Factbase::Term.new(:gt, [:foo, 42])
|
65
|
-
assert(t.evaluate(fact('foo' => [100]), []))
|
66
|
-
assert(t.evaluate(fact('foo' => 100), []))
|
67
|
-
assert(!t.evaluate(fact('foo' => [10]), []))
|
68
|
-
assert(!t.evaluate(fact('foo' => 10), []))
|
69
|
-
assert(!t.evaluate(fact('bar' => 10), []))
|
70
|
-
end
|
71
|
-
|
72
|
-
def test_lt_matching_time
|
73
|
-
t = Factbase::Term.new(:lt, [:foo, Time.now])
|
74
|
-
assert(t.evaluate(fact('foo' => [Time.now - 100]), []))
|
75
|
-
assert(!t.evaluate(fact('foo' => [Time.now + 100]), []))
|
76
|
-
assert(!t.evaluate(fact('bar' => [100]), []))
|
77
|
-
end
|
78
|
-
|
79
|
-
def test_gt_matching_time
|
80
|
-
t = Factbase::Term.new(:gt, [:foo, Time.now])
|
81
|
-
assert(t.evaluate(fact('foo' => [Time.now + 100]), []))
|
82
|
-
assert(!t.evaluate(fact('foo' => [Time.now - 100]), []))
|
83
|
-
assert(!t.evaluate(fact('bar' => [100]), []))
|
84
|
-
end
|
85
|
-
|
86
31
|
def test_false_matching
|
87
32
|
t = Factbase::Term.new(:never, [])
|
88
33
|
assert(!t.evaluate(fact('foo' => [100]), []))
|
@@ -125,6 +70,7 @@ class TestTerm < Minitest::Test
|
|
125
70
|
assert_equal('String', t.evaluate(fact('foo' => 'Hello, world!'), []))
|
126
71
|
assert_equal('Float', t.evaluate(fact('foo' => 3.14), []))
|
127
72
|
assert_equal('Time', t.evaluate(fact('foo' => Time.now), []))
|
73
|
+
assert_equal('Integer', t.evaluate(fact('foo' => 1_000_000_000_000_000), []))
|
128
74
|
assert_equal('nil', t.evaluate(fact, []))
|
129
75
|
end
|
130
76
|
|
@@ -213,6 +159,12 @@ class TestTerm < Minitest::Test
|
|
213
159
|
assert_equal([42], t.evaluate(fact('foo' => 4), []))
|
214
160
|
end
|
215
161
|
|
162
|
+
def test_plus
|
163
|
+
t = Factbase::Term.new(:plus, [:foo, 42])
|
164
|
+
assert_equal(46, t.evaluate(fact('foo' => 4), []))
|
165
|
+
assert(t.evaluate(fact, []).nil?)
|
166
|
+
end
|
167
|
+
|
216
168
|
def test_report_missing_term
|
217
169
|
t = Factbase::Term.new(:something, [])
|
218
170
|
msg = assert_raises do
|
@@ -229,27 +181,6 @@ class TestTerm < Minitest::Test
|
|
229
181
|
assert(msg.include?('at (at)'), msg)
|
230
182
|
end
|
231
183
|
|
232
|
-
def test_aggregation
|
233
|
-
maps = [
|
234
|
-
{ 'x' => 1, 'y' => 0, 'z' => 4 },
|
235
|
-
{ 'x' => 2, 'y' => 42, 'z' => 3 },
|
236
|
-
{ 'x' => 3, 'y' => 42, 'z' => 5 },
|
237
|
-
{ 'x' => 4, 'y' => 42, 'z' => 2 },
|
238
|
-
{ 'x' => 5, 'y' => 42, 'z' => 1 },
|
239
|
-
{ 'x' => 8, 'y' => 0, 'z' => 6 }
|
240
|
-
]
|
241
|
-
{
|
242
|
-
'(eq x (agg (eq y 42) (min x)))' => '(eq x 2)',
|
243
|
-
'(eq z (agg (eq y 0) (max z)))' => '(eq x 8)',
|
244
|
-
'(eq x (agg (and (eq y 42) (gt z 1)) (max x)))' => '(eq x 4)',
|
245
|
-
'(and (eq x (agg (eq y 42) (min x))) (eq z 3))' => '(eq x 2)'
|
246
|
-
}.each do |q, r|
|
247
|
-
t = Factbase::Syntax.new(q).to_term
|
248
|
-
f = maps.find { |m| t.evaluate(fact(m), maps) }
|
249
|
-
assert(Factbase::Syntax.new(r).to_term.evaluate(fact(f), []))
|
250
|
-
end
|
251
|
-
end
|
252
|
-
|
253
184
|
private
|
254
185
|
|
255
186
|
def fact(map = {})
|
@@ -73,6 +73,27 @@ class TestToXML < Minitest::Test
|
|
73
73
|
assert(!xml.xpath('/fb/f/class').empty?)
|
74
74
|
end
|
75
75
|
|
76
|
+
def test_show_types_as_attributes
|
77
|
+
fb = Factbase.new
|
78
|
+
f = fb.insert
|
79
|
+
f.a = 42
|
80
|
+
f.b = 3.14
|
81
|
+
f.c = 'Hello'
|
82
|
+
f.d = Time.now
|
83
|
+
f.e = 'e'
|
84
|
+
f.e = 4
|
85
|
+
out = Factbase::ToXML.new(fb).xml
|
86
|
+
xml = Nokogiri::XML.parse(out)
|
87
|
+
[
|
88
|
+
'/fb/f/a[@t="I"]',
|
89
|
+
'/fb/f/b[@t="F"]',
|
90
|
+
'/fb/f/c[@t="S"]',
|
91
|
+
'/fb/f/d[@t="T"]',
|
92
|
+
'/fb/f/e/v[@t="S"]',
|
93
|
+
'/fb/f/e/v[@t="I"]'
|
94
|
+
].each { |x| assert(!xml.xpath(x).empty?, out) }
|
95
|
+
end
|
96
|
+
|
76
97
|
def test_sorts_keys
|
77
98
|
fb = Factbase.new
|
78
99
|
f = fb.insert
|
@@ -80,7 +101,10 @@ class TestToXML < Minitest::Test
|
|
80
101
|
f.t = 40
|
81
102
|
f.a = 10
|
82
103
|
f.c = 1
|
83
|
-
|
84
|
-
|
104
|
+
to = Factbase::ToXML.new(fb)
|
105
|
+
xml = Nokogiri::XML.parse(to.xml)
|
106
|
+
%w[a c t x].each_with_index do |e, i|
|
107
|
+
assert(!xml.xpath("/fb/f/#{e}[count(preceding-sibling::*) = #{i}]").empty?, e)
|
108
|
+
end
|
85
109
|
end
|
86
110
|
end
|
data/test/test_factbase.rb
CHANGED
@@ -68,15 +68,15 @@ class TestFactbase < Minitest::Test
|
|
68
68
|
fb.insert.bar = 1
|
69
69
|
fb.query('(exists bar)').each do |f|
|
70
70
|
f.bar = 42
|
71
|
-
assert_equal(
|
71
|
+
assert_equal(2, f['bar'].size)
|
72
72
|
end
|
73
73
|
found = 0
|
74
74
|
fb.query('(always)').each do |f|
|
75
|
-
assert_equal(
|
75
|
+
assert_equal(2, f['bar'].size)
|
76
76
|
found += 1
|
77
77
|
end
|
78
78
|
assert_equal(1, found)
|
79
|
-
assert_equal(
|
79
|
+
assert_equal(2, fb.query('(always)').each.to_a[0]['bar'].size)
|
80
80
|
end
|
81
81
|
|
82
82
|
def test_serialize_and_deserialize
|
metadata
CHANGED
@@ -1,15 +1,29 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: factbase
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.51
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Yegor Bugayenko
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2024-06-
|
11
|
+
date: 2024-06-18 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: backtrace
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0.3'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0.3'
|
13
27
|
- !ruby/object:Gem::Dependency
|
14
28
|
name: json
|
15
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -115,6 +129,7 @@ files:
|
|
115
129
|
- Rakefile
|
116
130
|
- factbase.gemspec
|
117
131
|
- lib/factbase.rb
|
132
|
+
- lib/factbase/accum.rb
|
118
133
|
- lib/factbase/fact.rb
|
119
134
|
- lib/factbase/flatten.rb
|
120
135
|
- lib/factbase/inv.rb
|
@@ -123,12 +138,25 @@ files:
|
|
123
138
|
- lib/factbase/query.rb
|
124
139
|
- lib/factbase/rules.rb
|
125
140
|
- lib/factbase/syntax.rb
|
141
|
+
- lib/factbase/tee.rb
|
126
142
|
- lib/factbase/term.rb
|
143
|
+
- lib/factbase/terms/aggregates.rb
|
144
|
+
- lib/factbase/terms/aliases.rb
|
145
|
+
- lib/factbase/terms/debug.rb
|
146
|
+
- lib/factbase/terms/defn.rb
|
147
|
+
- lib/factbase/terms/logical.rb
|
148
|
+
- lib/factbase/terms/math.rb
|
149
|
+
- lib/factbase/terms/meta.rb
|
150
|
+
- lib/factbase/terms/ordering.rb
|
151
|
+
- lib/factbase/terms/strings.rb
|
127
152
|
- lib/factbase/to_json.rb
|
128
153
|
- lib/factbase/to_xml.rb
|
129
154
|
- lib/factbase/to_yaml.rb
|
130
|
-
- lib/factbase/tuples.rb
|
131
155
|
- renovate.json
|
156
|
+
- test/factbase/terms/test_aggregates.rb
|
157
|
+
- test/factbase/terms/test_aliases.rb
|
158
|
+
- test/factbase/terms/test_math.rb
|
159
|
+
- test/factbase/test_accum.rb
|
132
160
|
- test/factbase/test_fact.rb
|
133
161
|
- test/factbase/test_flatten.rb
|
134
162
|
- test/factbase/test_inv.rb
|
@@ -137,11 +165,11 @@ files:
|
|
137
165
|
- test/factbase/test_query.rb
|
138
166
|
- test/factbase/test_rules.rb
|
139
167
|
- test/factbase/test_syntax.rb
|
168
|
+
- test/factbase/test_tee.rb
|
140
169
|
- test/factbase/test_term.rb
|
141
170
|
- test/factbase/test_to_json.rb
|
142
171
|
- test/factbase/test_to_xml.rb
|
143
172
|
- test/factbase/test_to_yaml.rb
|
144
|
-
- test/factbase/test_tuples.rb
|
145
173
|
- test/test__helper.rb
|
146
174
|
- test/test_factbase.rb
|
147
175
|
homepage: http://github.com/yegor256/factbase.rb
|
@@ -1,106 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
# Copyright (c) 2024 Yegor Bugayenko
|
4
|
-
#
|
5
|
-
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
-
# of this software and associated documentation files (the 'Software'), to deal
|
7
|
-
# in the Software without restriction, including without limitation the rights
|
8
|
-
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
-
# copies of the Software, and to permit persons to whom the Software is
|
10
|
-
# furnished to do so, subject to the following conditions:
|
11
|
-
#
|
12
|
-
# The above copyright notice and this permission notice shall be included in all
|
13
|
-
# copies or substantial portions of the Software.
|
14
|
-
#
|
15
|
-
# THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
-
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
-
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFINGEMENT. IN NO EVENT SHALL THE
|
18
|
-
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
-
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
-
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
21
|
-
# SOFTWARE.
|
22
|
-
|
23
|
-
require 'minitest/autorun'
|
24
|
-
require_relative '../../lib/factbase'
|
25
|
-
require_relative '../../lib/factbase/tuples'
|
26
|
-
|
27
|
-
# Test.
|
28
|
-
# Author:: Yegor Bugayenko (yegor256@gmail.com)
|
29
|
-
# Copyright:: Copyright (c) 2024 Yegor Bugayenko
|
30
|
-
# License:: MIT
|
31
|
-
class TestTuples < Minitest::Test
|
32
|
-
def test_passes_facts
|
33
|
-
fb = Factbase.new
|
34
|
-
f1 = fb.insert
|
35
|
-
f1.foo = 42
|
36
|
-
f2 = fb.insert
|
37
|
-
f2.bar = 55
|
38
|
-
Factbase::Tuples.new(fb, ['(exists foo)', '(exists bar)']).each do |a, b|
|
39
|
-
assert_equal(42, a.foo)
|
40
|
-
assert_equal(55, b.bar)
|
41
|
-
end
|
42
|
-
end
|
43
|
-
|
44
|
-
def test_with_empty_list_of_queries
|
45
|
-
fb = Factbase.new
|
46
|
-
f1 = fb.insert
|
47
|
-
f1.foo = 42
|
48
|
-
tuples = Factbase::Tuples.new(fb, [])
|
49
|
-
assert(tuples.each.to_a.empty?)
|
50
|
-
end
|
51
|
-
|
52
|
-
def test_is_reusable
|
53
|
-
fb = Factbase.new
|
54
|
-
f1 = fb.insert
|
55
|
-
f1.foo = 42
|
56
|
-
tuples = Factbase::Tuples.new(fb, ['(exists foo)'])
|
57
|
-
assert_equal(1, tuples.each.to_a.size)
|
58
|
-
assert_equal(1, tuples.each.to_a.size)
|
59
|
-
end
|
60
|
-
|
61
|
-
def test_with_modifications
|
62
|
-
fb = Factbase.new
|
63
|
-
f1 = fb.insert
|
64
|
-
f1.foo = 42
|
65
|
-
Factbase::Tuples.new(fb, ['(exists foo)']).each do |fs|
|
66
|
-
fs[0].bar = 1
|
67
|
-
end
|
68
|
-
assert_equal(1, fb.query('(exists bar)').each.to_a.size)
|
69
|
-
end
|
70
|
-
|
71
|
-
def test_with_txn
|
72
|
-
fb = Factbase.new
|
73
|
-
f1 = fb.insert
|
74
|
-
f1.foo = 42
|
75
|
-
Factbase::Tuples.new(fb, ['(exists foo)']).each do |fs|
|
76
|
-
fb.txn do |fbt|
|
77
|
-
f = fbt.insert
|
78
|
-
f.bar = 1
|
79
|
-
end
|
80
|
-
fs[0].xyz = 'hey'
|
81
|
-
end
|
82
|
-
assert_equal(1, fb.query('(exists bar)').each.to_a.size)
|
83
|
-
assert_equal(1, fb.query('(exists xyz)').each.to_a.size)
|
84
|
-
end
|
85
|
-
|
86
|
-
def test_with_chaining
|
87
|
-
fb = Factbase.new
|
88
|
-
f1 = fb.insert
|
89
|
-
f1.name = 'Jeff'
|
90
|
-
f1.friend = 'Walter'
|
91
|
-
f2 = fb.insert
|
92
|
-
f2.name = 'Walter'
|
93
|
-
f2.group = 1
|
94
|
-
f3 = fb.insert
|
95
|
-
f3.name = 'Donny'
|
96
|
-
f3.group = 1
|
97
|
-
tuples = Factbase::Tuples.new(
|
98
|
-
fb, ['(eq name "Jeff")', '(eq name "{f0.friend}")', '(eq group {f1.group})']
|
99
|
-
)
|
100
|
-
tuples.each do |fs|
|
101
|
-
assert_equal('Walter', fs[1].name)
|
102
|
-
assert(%w[Walter Donny].include?(fs[2].name))
|
103
|
-
end
|
104
|
-
assert_equal(2, tuples.each.to_a.size)
|
105
|
-
end
|
106
|
-
end
|