judges 0.0.15 → 0.0.17

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: 921a2ee75d8305caea875d0ed79fcbd6b45edc165a7ddb6d8f049a66c489146e
4
- data.tar.gz: 73176a8f9b99a4aad3ab987f611468b3ca26b47bcc7a9048c4890a76f22e0d7b
3
+ metadata.gz: 7312c2f398cbad4906226fbc64c489a95428281003dcab21988185b214bea734
4
+ data.tar.gz: 7ecf453fcef5028bb43219ddfde277bd1e0e3633059afa69bafe895c8b9fa52a
5
5
  SHA512:
6
- metadata.gz: 567a566e23353d7cf625b117f733379543a24725456f13c0f5aa680abfc08732c7074e2159368ecf4a7c90e2615a0a72a32e88819f195bea9f2bc93ed9ed80cb
7
- data.tar.gz: 1294c1cd68138b2e39a632b51e913ac0cb1e8e539f32f7ea3067339a946ce93ea6c27356d45ea375d8fd8d42b396f24a4ca2b868d05707c4140d5d4c47a4b866
6
+ metadata.gz: 8000605816940bd197b284921b1a8218e51537c77f98fd7a932f5f47bac5c366dbe48fa3da0113dfa2db0c3760070d943a5d07a189f29ee87ddb3e0f6cedb18f
7
+ data.tar.gz: 9692dc49019dab0d0573cec9a95bbdd611328a7e2d95b3efc12ae5cc2e6a250d1ed2801d0c54b954872f53cf5d00139bf12c514612b8a86be72d18cf6dfd3d5e
data/bin/judges CHANGED
@@ -29,7 +29,7 @@ require 'factbase'
29
29
  Encoding.default_external = Encoding::UTF_8
30
30
  Encoding.default_internal = Encoding::UTF_8
31
31
 
32
- ver = '0.0.15'
32
+ ver = '0.0.17'
33
33
 
34
34
  include GLI::App
35
35
 
@@ -72,6 +72,16 @@ command :print do |c|
72
72
  end
73
73
  end
74
74
 
75
+ desc 'Remove the facts that are too old'
76
+ command :trim do |c|
77
+ c.desc 'Remove facts that are older than X days'
78
+ c.flag([:days], type: Integer, default_value: 90)
79
+ c.action do |global, options, args|
80
+ require_relative '../lib/judges/commands/trim'
81
+ Judges::Trim.new(loog).run(options, args)
82
+ end
83
+ end
84
+
75
85
  desc 'Print the factbase into a human-readable format (YAML, JSON, etc.)'
76
86
  command :print do |c|
77
87
  c.desc 'Output format (xml, json, or yaml)'
@@ -85,6 +95,10 @@ end
85
95
 
86
96
  desc 'Run automated tests for all judges'
87
97
  command :test do |c|
98
+ c.desc 'Name of the test pack to run'
99
+ c.flag([:pack], multiple: true)
100
+ c.desc 'Fail if no judges tested?'
101
+ c.flag([:quiet], default_value: false)
88
102
  c.action do |global, options, args|
89
103
  require_relative '../lib/judges/commands/test'
90
104
  Judges::Test.new(loog).run(options, args)
data/features/cli.feature CHANGED
@@ -27,7 +27,28 @@ Feature: Simple Run
27
27
 
28
28
  Scenario: Simple test of a few judges
29
29
  Given I run bin/judges with "test ./fixtures"
30
- Then Stdout contains "judges tested"
30
+ Then Stdout contains "👉 Testing"
31
+ Then Stdout contains "judges tested successfully"
32
+ And Exit code is zero
33
+
34
+ Scenario: Simple test of just one pack
35
+ Given I run bin/judges with "test --pack reward_for_good_bug ./fixtures"
36
+ Then Stdout contains "judges tested successfully"
37
+ And Exit code is zero
38
+
39
+ Scenario: Simple test of no packs
40
+ Given I run bin/judges with "test --pack absent_for_sure ./fixtures"
41
+ Then Exit code is not zero
42
+
43
+ Scenario: Simple trimming of a factbase
44
+ Given I make a temp directory
45
+ Then I have a "simple/simple_judge.rb" file with content:
46
+ """
47
+ $fb.insert.time = Time.now - 100 * 60 * 60 * 24
48
+ """
49
+ Then I run bin/judges with "--verbose update . simple.fb"
50
+ Given I run bin/judges with "trim --days 5 simple.fb"
51
+ Then Stdout contains "1 facts deleted"
31
52
  And Exit code is zero
32
53
 
33
54
  Scenario: Simple print of a small factbase
data/judges.gemspec CHANGED
@@ -26,7 +26,7 @@ Gem::Specification.new do |s|
26
26
  s.required_rubygems_version = Gem::Requirement.new('>= 0') if s.respond_to? :required_rubygems_version=
27
27
  s.required_ruby_version = '>=3.2'
28
28
  s.name = 'judges'
29
- s.version = '0.0.15'
29
+ s.version = '0.0.17'
30
30
  s.license = 'MIT'
31
31
  s.summary = 'Command-Line Tool for a Factbase'
32
32
  s.description = '
@@ -42,7 +42,7 @@ Gem::Specification.new do |s|
42
42
  s.rdoc_options = ['--charset=UTF-8']
43
43
  s.extra_rdoc_files = ['README.md', 'LICENSE.txt']
44
44
  s.add_runtime_dependency 'backtrace', '~> 0.3'
45
- s.add_runtime_dependency 'factbase', '~>0.0.12'
45
+ s.add_runtime_dependency 'factbase', '~>0.0.15'
46
46
  s.add_runtime_dependency 'gli', '~>2.21'
47
47
  s.add_runtime_dependency 'loog', '~>0.2'
48
48
  s.add_runtime_dependency 'nokogiri', '~> 1.10'
@@ -20,12 +20,8 @@
20
20
  # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
21
  # SOFTWARE.
22
22
 
23
- require 'factbase'
24
- require 'fileutils'
25
23
  require_relative '../../judges'
26
- require_relative '../../judges/to_rel'
27
- require_relative '../../judges/packs'
28
- require_relative '../../judges/options'
24
+ require_relative '../../judges/impex'
29
25
 
30
26
  # Join.
31
27
  # Author:: Yegor Bugayenko (yegor256@gmail.com)
@@ -38,16 +34,10 @@ class Judges::Join
38
34
 
39
35
  def run(_opts, args)
40
36
  raise 'Exactly two arguments required' unless args.size == 2
41
- master = args[0]
42
- raise "The master factbase is absent: #{master.to_rel}" unless File.exist?(master)
43
- slave = args[1]
44
- raise "The slave factbase is absent: #{slave.to_rel}" unless File.exist?(slave)
45
- fb = Factbase.new
46
- fb.import(File.binread(master))
47
- @loog.info("Master factbase imported from #{master.to_rel} (#{File.size(master)} bytes)")
48
- fb.import(File.binread(slave))
49
- @loog.info("Slave factbase imported from #{slave.to_rel} (#{File.size(slave)} bytes)")
50
- File.binwrite(master, fb.export)
51
- @loog.info("Master factbase exported to #{master.to_rel} (#{File.size(master)} bytes)")
37
+ master = Judges::Impex.new(@loog, args[0])
38
+ slave = Judges::Impex.new(@loog, args[1])
39
+ fb = master.import
40
+ slave.import_to(fb)
41
+ master.export(fb)
52
42
  end
53
43
  end
@@ -37,12 +37,14 @@ class Judges::Test
37
37
  @loog = loog
38
38
  end
39
39
 
40
- def run(_opts, args)
40
+ def run(opts, args)
41
41
  raise 'Exactly one argument required' unless args.size == 1
42
42
  dir = args[0]
43
43
  @loog.info("Testing judges in #{dir.to_rel}...")
44
44
  errors = []
45
- done = Judges::Packs.new(dir, @loog).each_with_index do |p, i|
45
+ done = 0
46
+ Judges::Packs.new(dir, @loog).each_with_index do |p, i|
47
+ next unless include?(opts, p.name)
46
48
  @loog.info("\n👉 Testing #{p.script} (##{i}) in #{p.dir.to_rel}...")
47
49
  p.tests.each do |f|
48
50
  yaml = YAML.load_file(f, permitted_classes: [Time])
@@ -54,7 +56,9 @@ class Judges::Test
54
56
  errors << f
55
57
  end
56
58
  end
59
+ done += 1
57
60
  end
61
+ raise 'No judges tested :(' if done.zero? && !opts['quiet']
58
62
  if errors.empty?
59
63
  @loog.info("\nAll #{done} judges tested successfully")
60
64
  else
@@ -65,6 +69,12 @@ class Judges::Test
65
69
 
66
70
  private
67
71
 
72
+ def include?(opts, name)
73
+ packs = opts['pack'] || []
74
+ return true if packs.empty?
75
+ packs.include?(name)
76
+ end
77
+
68
78
  def test_one(pack, yaml)
69
79
  fb = Factbase.new
70
80
  yaml['input'].each do |i|
@@ -0,0 +1,46 @@
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 NONINFRINGEMENT. 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 'time'
24
+ require_relative '../../judges'
25
+ require_relative '../../judges/impex'
26
+
27
+ # Trim.
28
+ # Author:: Yegor Bugayenko (yegor256@gmail.com)
29
+ # Copyright:: Copyright (c) 2024 Yegor Bugayenko
30
+ # License:: MIT
31
+ class Judges::Trim
32
+ def initialize(loog)
33
+ @loog = loog
34
+ end
35
+
36
+ def run(opts, args)
37
+ raise 'Exactly one argument required' unless args.size == 1
38
+ impex = Judges::Impex.new(@loog, args[0])
39
+ fb = impex.import
40
+ day = Time.now - (opts['days'].to_i * 60 * 60 * 24)
41
+ p "(lt time #{day.utc.iso8601})"
42
+ deleted = fb.query("(lt time #{day.utc.iso8601})").delete!
43
+ @loog.info("#{deleted} facts deleted because they are too old")
44
+ impex.export(fb)
45
+ end
46
+ end
@@ -20,13 +20,12 @@
20
20
  # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
21
  # SOFTWARE.
22
22
 
23
- require 'factbase'
24
- require 'fileutils'
25
23
  require 'backtrace'
26
24
  require_relative '../../judges'
27
25
  require_relative '../../judges/to_rel'
28
26
  require_relative '../../judges/packs'
29
27
  require_relative '../../judges/options'
28
+ require_relative '../../judges/impex'
30
29
 
31
30
  # Update.
32
31
  # Author:: Yegor Bugayenko (yegor256@gmail.com)
@@ -41,14 +40,8 @@ class Judges::Update
41
40
  raise 'Exactly two arguments required' unless args.size == 2
42
41
  dir = args[0]
43
42
  raise "The directory is absent: #{dir.to_rel}" unless File.exist?(dir)
44
- file = args[1]
45
- fb = Factbase.new
46
- if File.exist?(file)
47
- fb.import(File.binread(file))
48
- @loog.info("Factbase imported from #{file.to_rel} (#{File.size(file)} bytes)")
49
- else
50
- @loog.info("There is no Factbase to import from #{file.to_rel} (file is absent)")
51
- end
43
+ impex = Judges::Impex.new(@loog, args[1])
44
+ fb = impex.import(strict: false)
52
45
  options = Judges::Options.new(opts['option'])
53
46
  @loog.debug("The following options provided:\n\t#{options.to_s.gsub("\n", "\n\t")}")
54
47
  errors = []
@@ -65,9 +58,7 @@ class Judges::Update
65
58
  @loog.info("Pack #{p.dir.to_rel} added #{after - before} facts") if after > before
66
59
  end
67
60
  @loog.info("#{done} judges processed (#{errors.size} errors)")
68
- FileUtils.mkdir_p(File.dirname(file))
69
- File.binwrite(file, fb.export)
70
- @loog.info("Factbase exported to #{file.to_rel} (#{File.size(file)} bytes)")
71
61
  raise "Failed to update correctly (#{errors.size} errors)" unless errors.empty?
62
+ impex.export(fb)
72
63
  end
73
64
  end
@@ -0,0 +1,61 @@
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 NONINFRINGEMENT. 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 'judges'
24
+
25
+ # Injects a fact if it's absent in the factbase.
26
+ def if_absent(fb)
27
+ attrs = {}
28
+ f = Judges::Accumulator.new(attrs)
29
+ yield f
30
+ q = attrs.map { |k, v| "(eq #{k} #{v})" }.join(' ')
31
+ return unless fb.query("(and #{q})").each.to_a.empty?
32
+ n = fb.insert
33
+ attrs.each { |k, v| n.send("#{k}=", v) }
34
+ n
35
+ end
36
+
37
+ # Predents to be a fact, just accumulating all attribute sets.
38
+ # Author:: Yegor Bugayenko (yegor256@gmail.com)
39
+ # Copyright:: Copyright (c) 2024 Yegor Bugayenko
40
+ # License:: MIT
41
+ class Judges::Accumulator
42
+ def initialize(map)
43
+ @map = map
44
+ end
45
+
46
+ def method_missing(*args)
47
+ k = args[0]
48
+ raise "Unexpected interation with the fact: '#{k}'" unless k.end_with?('=')
49
+ @map[k[0..-2]] = args[1]
50
+ end
51
+
52
+ # rubocop:disable Style/OptionalBooleanParameter
53
+ def respond_to?(_method, _include_private = false)
54
+ # rubocop:enable Style/OptionalBooleanParameter
55
+ true
56
+ end
57
+
58
+ def respond_to_missing?(_method, _include_private = false)
59
+ true
60
+ end
61
+ end
@@ -20,16 +20,18 @@
20
20
  # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
21
  # SOFTWARE.
22
22
 
23
+ require 'judges'
24
+
23
25
  # Returns a decorated global factbase, which only touches facts once
24
26
  def once(fb, judge: $judge)
25
- Factbase::Once.new(fb, judge)
27
+ Judges::Once.new(fb, judge)
26
28
  end
27
29
 
28
30
  # Runs only once.
29
31
  # Author:: Yegor Bugayenko (yegor256@gmail.com)
30
32
  # Copyright:: Copyright (c) 2024 Yegor Bugayenko
31
33
  # License:: MIT
32
- class Factbase::Once
34
+ class Judges::Once
33
35
  def initialize(fb, func)
34
36
  @fb = fb
35
37
  @func = func
@@ -0,0 +1,60 @@
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 NONINFRINGEMENT. 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 'factbase'
24
+ require 'fileutils'
25
+ require_relative '../judges'
26
+ require_relative '../judges/to_rel'
27
+
28
+ # Import/Export of factbases.
29
+ # Author:: Yegor Bugayenko (yegor256@gmail.com)
30
+ # Copyright:: Copyright (c) 2024 Yegor Bugayenko
31
+ # License:: MIT
32
+ class Judges::Impex
33
+ def initialize(loog, file)
34
+ @loog = loog
35
+ @file = file
36
+ end
37
+
38
+ def import(strict: true)
39
+ fb = Factbase.new
40
+ if File.exist?(@file)
41
+ fb.import(File.binread(@file))
42
+ @loog.info("The factbase imported from #{@file.to_rel} (#{File.size(@file)} bytes)")
43
+ elsif strict
44
+ raise "The factbase is absent at #{@file.to_rel}"
45
+ end
46
+ fb
47
+ end
48
+
49
+ def import_to(fb)
50
+ raise "The factbase is absent at #{@file.to_rel}" unless File.exist?(@file)
51
+ fb.import(File.binread(@file))
52
+ @loog.info("The factbase loaded from #{@file.to_rel} (#{File.size(@file)} bytes)")
53
+ end
54
+
55
+ def export(fb)
56
+ FileUtils.mkdir_p(File.dirname(@file))
57
+ File.binwrite(@file, fb.export)
58
+ @loog.info("Factbase exported to #{@file.to_rel} (#{File.size(@file)} bytes)")
59
+ end
60
+ end
data/lib/judges/pack.rb CHANGED
@@ -24,6 +24,7 @@ require 'yaml'
24
24
  require 'time'
25
25
  require_relative '../judges'
26
26
  require_relative '../judges/fb/once'
27
+ require_relative '../judges/fb/if_absent'
27
28
 
28
29
  # A single pack.
29
30
  # Author:: Yegor Bugayenko (yegor256@gmail.com)
@@ -52,6 +53,11 @@ class Judges::Pack
52
53
  end
53
54
  end
54
55
 
56
+ # Get the name of the pack.
57
+ def name
58
+ File.basename(@dir)
59
+ end
60
+
55
61
  # Get the name of the .rb script in the pack.
56
62
  def script
57
63
  File.basename(Dir.glob(File.join(@dir, '*.rb')).first)
@@ -45,7 +45,7 @@ class TestTest < Minitest::Test
45
45
  - /fb/f[bar='4']
46
46
  YAML
47
47
  )
48
- Judges::Test.new(Loog::VERBOSE).run(nil, [d])
48
+ Judges::Test.new(Loog::NULL).run({}, [d])
49
49
  end
50
50
  end
51
51
 
@@ -65,7 +65,7 @@ class TestTest < Minitest::Test
65
65
  YAML
66
66
  )
67
67
  assert_raises do
68
- Judges::Test.new(Loog::VERBOSE).run(nil, [d])
68
+ Judges::Test.new(Loog::NULL).run({}, [d])
69
69
  end
70
70
  end
71
71
  end
@@ -84,7 +84,24 @@ class TestTest < Minitest::Test
84
84
  - /fb/f[foo='42']
85
85
  YAML
86
86
  )
87
- Judges::Test.new(Loog::VERBOSE).run(nil, [d])
87
+ Judges::Test.new(Loog::NULL).run({}, [d])
88
+ end
89
+ end
90
+
91
+ def test_one_pack_negative
92
+ Dir.mktmpdir do |d|
93
+ File.write(File.join(d, 'foo.rb'), '')
94
+ File.write(
95
+ File.join(d, 'x.yml'),
96
+ <<-YAML
97
+ input: []
98
+ expected:
99
+ - /fb[count(f)=1]
100
+ YAML
101
+ )
102
+ assert_raises do
103
+ Judges::Test.new(Loog::NULL).run({ 'pack' => [File.basename(dir)] }, [d])
104
+ end
88
105
  end
89
106
  end
90
107
  end
@@ -0,0 +1,48 @@
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 NONINFRINGEMENT. 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 'loog'
25
+ require 'nokogiri'
26
+ require 'time'
27
+ require_relative '../../lib/judges'
28
+ require_relative '../../lib/judges/commands/trim'
29
+
30
+ # Test.
31
+ # Author:: Yegor Bugayenko (yegor256@gmail.com)
32
+ # Copyright:: Copyright (c) 2024 Yegor Bugayenko
33
+ # License:: MIT
34
+ class TestTrim < Minitest::Test
35
+ def test_trims_factbase
36
+ Dir.mktmpdir do |d|
37
+ file = File.join(d, 'base.fb')
38
+ before = Factbase.new
39
+ before.insert.time = Time.now + 1
40
+ before.insert.time = Time.now - (100 * 24 * 60 * 60)
41
+ File.binwrite(file, before.export)
42
+ Judges::Trim.new(Loog::VERBOSE).run({ 'days' => '10' }, [file])
43
+ after = Factbase.new
44
+ after.import(File.binread(file))
45
+ assert_equal(1, after.size)
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,50 @@
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 NONINFRINGEMENT. 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 'tmpdir'
25
+ require 'factbase'
26
+ require_relative '../../lib/judges'
27
+ require_relative '../../lib/judges/fb/if_absent'
28
+
29
+ # Test.
30
+ # Author:: Yegor Bugayenko (yegor256@gmail.com)
31
+ # Copyright:: Copyright (c) 2024 Yegor Bugayenko
32
+ # License:: MIT
33
+ class TestIfAbsent < Minitest::Test
34
+ def test_ignores
35
+ fb = Factbase.new
36
+ fb.insert.foo = 42
37
+ n = if_absent(fb) do |f|
38
+ f.foo = 42
39
+ end
40
+ assert(n.nil?)
41
+ end
42
+
43
+ def test_injects
44
+ fb = Factbase.new
45
+ n = if_absent(fb) do |f|
46
+ f.foo = 42
47
+ end
48
+ assert_equal(42, n.foo)
49
+ end
50
+ end
@@ -0,0 +1,52 @@
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 NONINFRINGEMENT. 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 'tmpdir'
25
+ require 'loog'
26
+ require_relative '../lib/judges'
27
+ require_relative '../lib/judges/impex'
28
+
29
+ # Test.
30
+ # Author:: Yegor Bugayenko (yegor256@gmail.com)
31
+ # Copyright:: Copyright (c) 2024 Yegor Bugayenko
32
+ # License:: MIT
33
+ class TestImpex < Minitest::Test
34
+ def test_basic
35
+ Dir.mktmpdir do |d|
36
+ f = File.join(d, 'foo.rb')
37
+ impex = Judges::Impex.new(Loog::VERBOSE, f)
38
+ impex.import(strict: false)
39
+ impex.export(Factbase.new)
40
+ end
41
+ end
42
+
43
+ def test_strict_import
44
+ Dir.mktmpdir do |d|
45
+ f = File.join(d, 'x.rb')
46
+ impex = Judges::Impex.new(Loog::VERBOSE, f)
47
+ impex.import(strict: false)
48
+ impex.export(Factbase.new)
49
+ impex.import
50
+ end
51
+ end
52
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: judges
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.15
4
+ version: 0.0.17
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-05-13 00:00:00.000000000 Z
11
+ date: 2024-05-14 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: backtrace
@@ -30,14 +30,14 @@ dependencies:
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: 0.0.12
33
+ version: 0.0.15
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: 0.0.12
40
+ version: 0.0.15
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: gli
43
43
  requirement: !ruby/object:Gem::Requirement
@@ -124,8 +124,11 @@ files:
124
124
  - lib/judges/commands/join.rb
125
125
  - lib/judges/commands/print.rb
126
126
  - lib/judges/commands/test.rb
127
+ - lib/judges/commands/trim.rb
127
128
  - lib/judges/commands/update.rb
129
+ - lib/judges/fb/if_absent.rb
128
130
  - lib/judges/fb/once.rb
131
+ - lib/judges/impex.rb
129
132
  - lib/judges/options.rb
130
133
  - lib/judges/pack.rb
131
134
  - lib/judges/packs.rb
@@ -134,9 +137,12 @@ files:
134
137
  - test/commands/test_join.rb
135
138
  - test/commands/test_print.rb
136
139
  - test/commands/test_test.rb
140
+ - test/commands/test_trim.rb
137
141
  - test/commands/test_update.rb
142
+ - test/fb/test_if_absent.rb
138
143
  - test/fb/test_once.rb
139
144
  - test/test__helper.rb
145
+ - test/test_impex.rb
140
146
  - test/test_judges.rb
141
147
  - test/test_options.rb
142
148
  - test/test_pack.rb