factbase 0.0.57 → 0.0.59

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: fec35b6880c4cfe0224107a19dd60c4b2e9ca6316b87331897b06d339f1e0f39
4
- data.tar.gz: c096effe0c1789dae54ad5da35c9ca603f279c55f93597871f0c03846c04e457
3
+ metadata.gz: c62bd0cae1b70119954f0f2c1eef5ef9ff92e7073dc5f86492cc1f048456580c
4
+ data.tar.gz: 7cfd0410d94217f51b84e41707c1bfecd493f022a840507f18a2d92fd9bb3d9c
5
5
  SHA512:
6
- metadata.gz: 6b2b85cf88fe6f5857fd51d5f58989f4ef078829749bf565b41184b15472b6247c9fa9f901848fcdfc0cc2dfe04be32098e43351e887ea546cbc2817171f0d44
7
- data.tar.gz: 1d720b58f13c156e8ee1a8c2c81d88f27339a5924fdfac8a362341a6c0324524d540c82ce1fb2df09e05d7ca7c01e5ca77369b8a35861f8aa131f06eb40018be
6
+ metadata.gz: 46d98f86cc24e7ca8db4c543fe34080c2571009e0715699be377fdd4a4589d0a99165c9d45ae2e2fbc432d2592231be7122d0c1c45bc77c5d351c497d1fee703
7
+ data.tar.gz: d8f0f6e49e6d5c7740f3d70f46860a425f1f9de3a91bdf927cec4579f87aac4357e5e0a6e148d7d9d58ed34a99ddc1ad57c40c0018e735110083f30a594d1ee4
data/Gemfile CHANGED
@@ -23,7 +23,7 @@
23
23
  source 'https://rubygems.org'
24
24
  gemspec
25
25
 
26
- gem 'minitest', '5.24.0', require: false
26
+ gem 'minitest', '5.24.1', require: false
27
27
  gem 'rake', '13.2.1', require: false
28
28
  gem 'rspec-rails', '6.1.3', require: false
29
29
  gem 'rubocop', '1.64.1', require: false
data/Gemfile.lock CHANGED
@@ -64,8 +64,8 @@ GEM
64
64
  loofah (2.22.0)
65
65
  crass (~> 1.0.2)
66
66
  nokogiri (>= 1.12.0)
67
- loog (0.5.1)
68
- minitest (5.24.0)
67
+ loog (0.5.2)
68
+ minitest (5.24.1)
69
69
  mutex_m (0.2.0)
70
70
  nokogiri (1.16.6-arm64-darwin)
71
71
  racc (~> 1.4)
@@ -113,7 +113,7 @@ GEM
113
113
  regexp_parser (2.9.2)
114
114
  reline (0.5.9)
115
115
  io-console (~> 0.5)
116
- rexml (3.3.0)
116
+ rexml (3.3.1)
117
117
  strscan
118
118
  rspec-core (3.13.0)
119
119
  rspec-support (~> 3.13.0)
@@ -180,7 +180,7 @@ PLATFORMS
180
180
 
181
181
  DEPENDENCIES
182
182
  factbase!
183
- minitest (= 5.24.0)
183
+ minitest (= 5.24.1)
184
184
  rake (= 13.2.1)
185
185
  rspec-rails (= 6.1.3)
186
186
  rubocop (= 1.64.1)
data/README.md CHANGED
@@ -72,6 +72,11 @@ or `b1` is `false`
72
72
  * `(gt v1 v2)` — if any `v1` is greater than any `v2`
73
73
  * `(many v)` — if `v` has many values
74
74
  * `(one v)` — if `v` has one value
75
+
76
+ There are string manipulators:
77
+
78
+ * `(concat v1 v2 v3 ...)` — concatenates all `v`
79
+ * `(sprintf v v1 v2 ...)` — creates a string by `v` format with params
75
80
  * `(matches v s)` — if any `v` matches the `s` regular expression
76
81
 
77
82
  There are a few terms that return non-boolean values:
@@ -97,6 +102,12 @@ Also, some simple arithmetic:
97
102
  * `(times v1 v2)` is a multiplication of `∏v1` and `∏v2`
98
103
  * `(div v1 v2)` is a division of `∏v1` by `∏v2`
99
104
 
105
+ Types may be converted:
106
+
107
+ * `(to_int v)` is an integer of `v`
108
+ * `(to_str v)` is a string of `v`
109
+ * `(to_float v)` is a float of `v`
110
+
100
111
  One term is for meta-programming:
101
112
 
102
113
  * `(defn f "self.to_s")` defines a new term using Ruby syntax and returns `true`
data/lib/factbase/tee.rb CHANGED
@@ -42,7 +42,7 @@ class Factbase::Tee
42
42
  end
43
43
 
44
44
  def all_properties
45
- @fact.all_properties
45
+ @fact.all_properties + (@upper.is_a?(Hash) ? @upper.keys : @upper.all_properties)
46
46
  end
47
47
 
48
48
  others do |*args|
data/lib/factbase/term.rb CHANGED
@@ -95,7 +95,7 @@ class Factbase::Term
95
95
  def evaluate(fact, maps)
96
96
  send(@op, fact, maps)
97
97
  rescue NoMethodError => e
98
- raise "Term '#{@op}' is not defined at #{self}:\n#{Backtrace.new(e)}"
98
+ raise "Probably the term '#{@op}' is not defined at #{self}:\n#{Backtrace.new(e)}"
99
99
  rescue StandardError => e
100
100
  raise "#{e.message} at #{self}:\n#{Backtrace.new(e)}"
101
101
  end
@@ -51,6 +51,27 @@ module Factbase::Term::Math
51
51
  vv.any? { |v| (v.is_a?(Integer) || v.is_a?(Float)) && v.zero? }
52
52
  end
53
53
 
54
+ def to_str(fact, maps)
55
+ assert_args(1)
56
+ vv = the_values(0, fact, maps)
57
+ return nil if vv.nil?
58
+ vv[0].to_s
59
+ end
60
+
61
+ def to_int(fact, maps)
62
+ assert_args(1)
63
+ vv = the_values(0, fact, maps)
64
+ return nil if vv.nil?
65
+ vv[0].to_i
66
+ end
67
+
68
+ def to_float(fact, maps)
69
+ assert_args(1)
70
+ vv = the_values(0, fact, maps)
71
+ return nil if vv.nil?
72
+ vv[0].to_f
73
+ end
74
+
54
75
  def eq(fact, maps)
55
76
  cmp(:==, fact, maps)
56
77
  end
@@ -36,10 +36,10 @@ module Factbase::Term::Ordering
36
36
  before
37
37
  end
38
38
 
39
- def unique(fact, _maps)
39
+ def unique(fact, maps)
40
40
  @uniques = [] if @uniques.nil?
41
41
  assert_args(1)
42
- vv = by_symbol(0, fact)
42
+ vv = the_values(0, fact, maps)
43
43
  return false if vv.nil?
44
44
  vv = [vv] unless vv.is_a?(Array)
45
45
  vv.each do |v|
@@ -28,6 +28,16 @@ require_relative '../../factbase'
28
28
  # Copyright:: Copyright (c) 2024 Yegor Bugayenko
29
29
  # License:: MIT
30
30
  module Factbase::Term::Strings
31
+ def concat(fact, maps)
32
+ (0..@operands.length - 1).map { |i| the_values(i, fact, maps)[0] }.join
33
+ end
34
+
35
+ def sprintf(fact, maps)
36
+ fmt = the_values(0, fact, maps)[0]
37
+ ops = (1..@operands.length - 1).map { |i| the_values(i, fact, maps)[0] }
38
+ format(*([fmt] + ops))
39
+ end
40
+
31
41
  def matches(fact, maps)
32
42
  assert_args(2)
33
43
  str = the_values(0, fact, maps)
data/lib/factbase.rb CHANGED
@@ -81,7 +81,7 @@ require 'yaml'
81
81
  # License:: MIT
82
82
  class Factbase
83
83
  # Current version of the gem (changed by .rultor.yml on every release)
84
- VERSION = '0.0.57'
84
+ VERSION = '0.0.59'
85
85
 
86
86
  # An exception that may be thrown in a transaction, to roll it back.
87
87
  class Rollback < StandardError; end
@@ -32,13 +32,14 @@ require_relative '../../../lib/factbase/accum'
32
32
  class TestAliases < Minitest::Test
33
33
  def test_aliases
34
34
  maps = [
35
- { 'x' => [1], 'y' => [0] },
36
- { 'x' => [2], 'y' => [42] }
35
+ { 'x' => [1], 'y' => [0], 't1' => [Time.now], 't2' => [Time.now] },
36
+ { 'x' => [2], 'y' => [42], 't' => [Time.now] }
37
37
  ]
38
38
  {
39
39
  '(as foo (plus x 1))' => '(exists foo)',
40
40
  '(as foo (plus x y))' => '(gt foo 0)',
41
- '(as foo (plus bar 1))' => '(absent foo)'
41
+ '(as foo (plus bar 1))' => '(absent foo)',
42
+ '(as foo (minus t1 t2))' => '(when (exists foo) (eq "Float" (type foo)))'
42
43
  }.each do |q, r|
43
44
  t = Factbase::Syntax.new(q).to_term
44
45
  maps.each do |m|
@@ -23,7 +23,7 @@
23
23
  require 'minitest/autorun'
24
24
  require_relative '../../../lib/factbase/term'
25
25
 
26
- # Aggregates test.
26
+ # Math test.
27
27
  # Author:: Yegor Bugayenko (yegor256@gmail.com)
28
28
  # Copyright:: Copyright (c) 2024 Yegor Bugayenko
29
29
  # License:: MIT
@@ -91,6 +91,21 @@ class TestMath < Minitest::Test
91
91
  assert(!t.evaluate(fact('bar' => [100]), []))
92
92
  end
93
93
 
94
+ def test_to_str
95
+ t = Factbase::Term.new(:to_str, [Time.now])
96
+ assert_equal('String', t.evaluate(fact, []).class.to_s)
97
+ end
98
+
99
+ def test_to_int
100
+ t = Factbase::Term.new(:to_int, [[42, 'hello']])
101
+ assert_equal('Integer', t.evaluate(fact, []).class.to_s)
102
+ end
103
+
104
+ def test_to_float
105
+ t = Factbase::Term.new(:to_float, [[3.14, 'hello']])
106
+ assert_equal('Float', t.evaluate(fact, []).class.to_s)
107
+ end
108
+
94
109
  private
95
110
 
96
111
  def fact(map = {})
@@ -0,0 +1,51 @@
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/term'
25
+
26
+ # Strings test.
27
+ # Author:: Yegor Bugayenko (yegor256@gmail.com)
28
+ # Copyright:: Copyright (c) 2024 Yegor Bugayenko
29
+ # License:: MIT
30
+ class TestStrings < Minitest::Test
31
+ def test_concat
32
+ t = Factbase::Term.new(:concat, [42, 'hi', 3.14, Time.now])
33
+ assert(t.evaluate(fact, []).start_with?('42hi3.14'))
34
+ end
35
+
36
+ def test_concat_empty
37
+ t = Factbase::Term.new(:concat, [])
38
+ assert_equal('', t.evaluate(fact, []))
39
+ end
40
+
41
+ def test_sprintf
42
+ t = Factbase::Term.new(:sprintf, ['hi, %s!', 'Jeff'])
43
+ assert_equal('hi, Jeff!', t.evaluate(fact, []))
44
+ end
45
+
46
+ private
47
+
48
+ def fact(map = {})
49
+ Factbase::Fact.new(Mutex.new, map)
50
+ end
51
+ end
@@ -31,16 +31,25 @@ require_relative '../../lib/factbase/fact'
31
31
  # License:: MIT
32
32
  class TestTee < Minitest::Test
33
33
  def test_two_facts
34
- map = {}
35
- prim = Factbase::Fact.new(Mutex.new, map)
34
+ prim = Factbase::Fact.new(Mutex.new, {})
36
35
  prim.foo = 42
37
- upper = Factbase::Fact.new(Mutex.new, map)
36
+ upper = Factbase::Fact.new(Mutex.new, {})
38
37
  upper.bar = 13
39
38
  t = Factbase::Tee.new(prim, upper)
40
39
  assert_equal(42, t.foo)
41
40
  assert_equal([13], t['$bar'])
42
41
  end
43
42
 
43
+ def test_all_properties
44
+ prim = Factbase::Fact.new(Mutex.new, {})
45
+ prim.foo = 42
46
+ upper = Factbase::Fact.new(Mutex.new, {})
47
+ upper.bar = 13
48
+ t = Factbase::Tee.new(prim, upper)
49
+ assert(t.all_properties.include?('foo'))
50
+ assert(t.all_properties.include?('bar'))
51
+ end
52
+
44
53
  def test_recursively
45
54
  map = {}
46
55
  prim = Factbase::Fact.new(Mutex.new, map)
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: factbase
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.57
4
+ version: 0.0.59
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-29 00:00:00.000000000 Z
11
+ date: 2024-07-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: backtrace
@@ -184,6 +184,7 @@ files:
184
184
  - test/factbase/terms/test_aggregates.rb
185
185
  - test/factbase/terms/test_aliases.rb
186
186
  - test/factbase/terms/test_math.rb
187
+ - test/factbase/terms/test_strings.rb
187
188
  - test/factbase/test_accum.rb
188
189
  - test/factbase/test_fact.rb
189
190
  - test/factbase/test_flatten.rb