factbase 0.0.57 → 0.0.59

Sign up to get free protection for your applications and to get access to all the features.
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