judges 0.0.19 → 0.0.21

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: 22748b35c785164e5fef5f8a6d013d92c380e2023d9806759339a11763f51554
4
- data.tar.gz: 9245a7682189a256d5cd2b2779c7163189e751db721d0dd0eeb54e804bb0e7ca
3
+ metadata.gz: 428132cb0468f9c9e0fb7c3a51628cfb4f8b07a0ff26493cd476f10a8461ca02
4
+ data.tar.gz: 158206dab846c53314f29ed607e5789ede80e2b18c778dca09bd65ce67adaf93
5
5
  SHA512:
6
- metadata.gz: 0b8d102de3483627367d4f8705b5473324f469b9a9d7367bbdee224f3d1db6e37a8ed34bab345ef6930dd321f473781b69e314c53aab2e499c8f8f10916ef519
7
- data.tar.gz: d564a60e8d813fb4b785b0e4c084012f360c920ced92138bdf0f247f3aa89e1e5ac86104f928129cc2cc24b1c705d3d7f59c2d25bd59f019a4958024e0dcaa06
6
+ metadata.gz: c594b09ee2a9ea407344adf6e0a89f5e32f6ae2c4294810f89ac617dd9878cf3cee336ac2b3db934bfff1db68bf9b6a277d6a1b2d3afcf720fc34b58a12f73ab
7
+ data.tar.gz: 298affb7b7f6882a98a52117bc7fb5270e6ed71616505891d4b71080e53131b55236fe54de2a465a91a302d4ef2b70f361630bc4536a46c1a5190d9e9442fca6
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.19'
32
+ ver = '0.0.21'
33
33
 
34
34
  include GLI::App
35
35
 
@@ -88,19 +88,28 @@ desc 'Print the factbase into a human-readable format (YAML, JSON, etc.)'
88
88
  command :print do |c|
89
89
  c.desc 'Output format (xml, json, or yaml)'
90
90
  c.flag([:format], default_value: 'yaml')
91
- c.switch([:auto])
91
+ c.desc 'Generate output name of the file automatically'
92
+ c.switch([:auto], default_value: false)
92
93
  c.action do |global, options, args|
93
94
  require_relative '../lib/judges/commands/print'
94
95
  Judges::Print.new(loog).run(options, args)
95
96
  end
96
97
  end
97
98
 
99
+ desc 'Inspect the factbase and print all its possible meta-data'
100
+ command :inspect do |c|
101
+ c.action do |global, options, args|
102
+ require_relative '../lib/judges/commands/inspect'
103
+ Judges::Inspect.new(loog).run(options, args)
104
+ end
105
+ end
106
+
98
107
  desc 'Run automated tests for all judges'
99
108
  command :test do |c|
100
109
  c.desc 'Name of the test pack to run'
101
110
  c.flag([:pack], multiple: true)
102
- c.desc 'Fail if no judges tested?'
103
- c.flag([:quiet], default_value: false)
111
+ c.desc 'Stay quiet even if some tests fail or simply no tests executed?'
112
+ c.switch([:quiet], default_value: false)
104
113
  c.action do |global, options, args|
105
114
  require_relative '../lib/judges/commands/test'
106
115
  Judges::Test.new(loog).run(options, args)
data/features/cli.feature CHANGED
@@ -27,12 +27,12 @@ Feature: Simple Run
27
27
  Scenario: Simple test of a few judges
28
28
  Given I run bin/judges with "test ./fixtures"
29
29
  Then Stdout contains "👉 Testing"
30
- Then Stdout contains "judges tested successfully"
30
+ Then Stdout contains "judge(s) tested successfully"
31
31
  And Exit code is zero
32
32
 
33
33
  Scenario: Simple test of just one pack
34
34
  Given I run bin/judges with "test --pack reward_for_good_bug ./fixtures"
35
- Then Stdout contains "judges tested successfully"
35
+ Then Stdout contains "judge(s) tested successfully"
36
36
  And Exit code is zero
37
37
 
38
38
  Scenario: Simple test of no packs
@@ -64,3 +64,16 @@ Feature: Simple Run
64
64
  Then Stdout contains "printed"
65
65
  And Exit code is zero
66
66
 
67
+ Scenario: Simple inspect of a small factbase
68
+ Given I make a temp directory
69
+ Then I have a "simple/simple_judge.rb" file with content:
70
+ """
71
+ return if $fb.size > 2
72
+ n = $fb.insert
73
+ n.kind = 'yes!'
74
+ """
75
+ Then I run bin/judges with "update . simple.fb"
76
+ Then I run bin/judges with "inspect simple.fb"
77
+ Then Stdout contains "Facts: 3"
78
+ And Exit code is zero
79
+
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.19'
29
+ s.version = '0.0.21'
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.16'
45
+ s.add_runtime_dependency 'factbase', '~>0.0.21'
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'
@@ -0,0 +1,40 @@
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_relative '../../judges'
24
+ require_relative '../../judges/impex'
25
+
26
+ # Inspect.
27
+ # Author:: Yegor Bugayenko (yegor256@gmail.com)
28
+ # Copyright:: Copyright (c) 2024 Yegor Bugayenko
29
+ # License:: MIT
30
+ class Judges::Inspect
31
+ def initialize(loog)
32
+ @loog = loog
33
+ end
34
+
35
+ def run(_opts, args)
36
+ raise 'At lease one argument required' if args.empty?
37
+ fb = Judges::Impex.new(@loog, args[0]).import
38
+ @loog.info("Facts: #{fb.size}")
39
+ end
40
+ end
@@ -23,8 +23,7 @@
23
23
  require 'fileutils'
24
24
  require 'factbase'
25
25
  require_relative '../../judges'
26
- require_relative '../../judges/to_rel'
27
- require_relative '../../judges/packs'
26
+ require_relative '../../judges/impex'
28
27
 
29
28
  # Update.
30
29
  # Author:: Yegor Bugayenko (yegor256@gmail.com)
@@ -37,17 +36,14 @@ class Judges::Print
37
36
 
38
37
  def run(opts, args)
39
38
  raise 'At lease one argument required' if args.empty?
40
- f = args[0]
41
- raise "The file is absent: #{f.to_rel}" unless File.exist?(f)
42
39
  o = args[1]
40
+ f = args[0]
41
+ fb = Judges::Impex.new(@loog, f).import
43
42
  if o.nil?
44
43
  raise 'Either provide output file name or use --auto' unless opts[:auto]
45
44
  o = File.join(File.dirname(f), File.basename(f).gsub(/\.[^.]*$/, ''))
46
45
  o = "#{o}.#{opts[:format]}"
47
46
  end
48
- fb = Factbase.new
49
- fb.import(File.binread(f))
50
- @loog.info("Factbase imported from #{f.to_rel} (#{File.size(f)} bytes)")
51
47
  FileUtils.mkdir_p(File.dirname(o))
52
48
  output =
53
49
  case opts[:format].downcase
@@ -23,6 +23,7 @@
23
23
  require 'nokogiri'
24
24
  require 'factbase'
25
25
  require 'backtrace'
26
+ require 'factbase/looged'
26
27
  require_relative '../../judges'
27
28
  require_relative '../../judges/to_rel'
28
29
  require_relative '../../judges/packs'
@@ -58,12 +59,14 @@ class Judges::Test
58
59
  end
59
60
  done += 1
60
61
  end
61
- raise 'No judges tested :(' if done.zero? && !opts['quiet']
62
- if errors.empty?
63
- @loog.info("\nAll #{done} judges tested successfully")
62
+ if done.zero?
63
+ raise 'No judges tested :(' unless opts['quiet']
64
+ @loog.warn("\n👍 No judges tested")
65
+ elsif errors.empty?
66
+ @loog.info("\n👍 All #{done} judge(s) tested successfully")
64
67
  else
65
- @loog.info("\n#{done} judges tested, #{errors.size} of them failed")
66
- raise "#{errors.size} tests failed" unless errors.empty?
68
+ @loog.info("\n#{done} judge(s) tested, #{errors.size} of them failed")
69
+ raise "#{errors.size} tests failed" unless opts['quiet']
67
70
  end
68
71
  end
69
72
 
@@ -89,7 +92,7 @@ class Judges::Test
89
92
  end
90
93
  end
91
94
  end
92
- pack.run(fb, Judges::Options.new(yaml['options']))
95
+ pack.run(Factbase::Looged.new(fb, @loog), Judges::Options.new(yaml['options']))
93
96
  xml = Nokogiri::XML.parse(fb.to_xml)
94
97
  yaml['expected'].each do |xp|
95
98
  raise "#{pack.script} doesn't match '#{xp}':\n#{xml}" if xml.xpath(xp).empty?
@@ -21,6 +21,7 @@
21
21
  # SOFTWARE.
22
22
 
23
23
  require 'backtrace'
24
+ require 'factbase/looged'
24
25
  require_relative '../../judges'
25
26
  require_relative '../../judges/to_rel'
26
27
  require_relative '../../judges/packs'
@@ -42,6 +43,7 @@ class Judges::Update
42
43
  raise "The directory is absent: #{dir.to_rel}" unless File.exist?(dir)
43
44
  impex = Judges::Impex.new(@loog, args[1])
44
45
  fb = impex.import(strict: false)
46
+ fb = Factbase::Looged.new(fb, @loog)
45
47
  options = Judges::Options.new(opts['option'])
46
48
  @loog.debug("The following options provided:\n\t#{options.to_s.gsub("\n", "\n\t")}")
47
49
  packs = Judges::Packs.new(dir, @loog)
@@ -65,7 +67,7 @@ class Judges::Update
65
67
  errors = []
66
68
  diff = 0
67
69
  done = packs.each_with_index do |p, i|
68
- @loog.info("Running #{p.dir.to_rel} (##{i})...")
70
+ @loog.info("👍 Running #{p.name} (##{i}) at #{p.dir.to_rel}...")
69
71
  before = fb.size
70
72
  begin
71
73
  p.run(fb, options)
@@ -21,14 +21,24 @@
21
21
  # SOFTWARE.
22
22
 
23
23
  require 'judges'
24
+ require 'time'
24
25
 
25
26
  # Injects a fact if it's absent in the factbase.
26
27
  def if_absent(fb)
27
28
  attrs = {}
28
29
  f = Judges::Accumulator.new(attrs)
29
30
  yield f
30
- q = attrs.map { |k, v| "(eq #{k} #{v})" }.join(' ')
31
- return unless fb.query("(and #{q})").each.to_a.empty?
31
+ q = attrs.map do |k, v|
32
+ vv = v.to_s
33
+ if v.is_a?(String)
34
+ vv = "'#{vv.gsub('"', '\\"').gsub("'", "\\'")}'"
35
+ elsif v.is_a?(Time)
36
+ vv = v.iso8601
37
+ end
38
+ "(eq #{k} #{vv})"
39
+ end.join(' ')
40
+ q = "(and #{q})"
41
+ return unless fb.query(q).each.to_a.empty?
32
42
  n = fb.insert
33
43
  attrs.each { |k, v| n.send("#{k}=", v) }
34
44
  n
@@ -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 'minitest/autorun'
24
+ require 'loog'
25
+ require 'factbase'
26
+ require_relative '../../lib/judges'
27
+ require_relative '../../lib/judges/commands/inspect'
28
+
29
+ # Test.
30
+ # Author:: Yegor Bugayenko (yegor256@gmail.com)
31
+ # Copyright:: Copyright (c) 2024 Yegor Bugayenko
32
+ # License:: MIT
33
+ class TestInspect < Minitest::Test
34
+ def test_simple_inspect
35
+ Dir.mktmpdir do |d|
36
+ f = File.join(d, 'base.fb')
37
+ fb = Factbase.new
38
+ fb.insert
39
+ fb.insert
40
+ File.binwrite(f, fb.export)
41
+ loog = Loog::Buffer.new
42
+ Judges::Inspect.new(loog).run({}, [f])
43
+ assert(loog.to_s.include?('Facts: 2'))
44
+ end
45
+ end
46
+ end
@@ -23,6 +23,8 @@
23
23
  require 'minitest/autorun'
24
24
  require 'tmpdir'
25
25
  require 'factbase'
26
+ require 'factbase/looged'
27
+ require 'loog'
26
28
  require_relative '../../lib/judges'
27
29
  require_relative '../../lib/judges/fb/if_absent'
28
30
 
@@ -33,9 +35,19 @@ require_relative '../../lib/judges/fb/if_absent'
33
35
  class TestIfAbsent < Minitest::Test
34
36
  def test_ignores
35
37
  fb = Factbase.new
36
- fb.insert.foo = 42
38
+ fb.insert.foo = 'hello dude'
37
39
  n = if_absent(fb) do |f|
38
- f.foo = 42
40
+ f.foo = 'hello dude'
41
+ end
42
+ assert(n.nil?)
43
+ end
44
+
45
+ def test_ignores_with_time
46
+ fb = Factbase.new
47
+ t = Time.now
48
+ fb.insert.foo = t
49
+ n = if_absent(fb) do |f|
50
+ f.foo = t
39
51
  end
40
52
  assert(n.nil?)
41
53
  end
@@ -47,4 +59,38 @@ class TestIfAbsent < Minitest::Test
47
59
  end
48
60
  assert_equal(42, n.foo)
49
61
  end
62
+
63
+ def test_complex_ignores
64
+ fb = Factbase.new
65
+ f1 = fb.insert
66
+ f1.foo = 'hello, "dude"!'
67
+ f1.abc = 42
68
+ t = Time.now
69
+ f1.z = t
70
+ f1.bar = 3.14
71
+ n = if_absent(fb) do |f|
72
+ f.foo = 'hello, "dude"!'
73
+ f.abc = 42
74
+ f.z = t
75
+ f.bar = 3.14
76
+ end
77
+ assert(n.nil?)
78
+ end
79
+
80
+ def test_complex_injects
81
+ fb = Factbase.new
82
+ f1 = fb.insert
83
+ f1.foo = 'hello, "dude"!'
84
+ f1.abc = 42
85
+ t = Time.now
86
+ f1.z = t
87
+ f1.bar = 3.14
88
+ n = if_absent(fb) do |f|
89
+ f.foo = 'hello, "dude"!'
90
+ f.abc = 42
91
+ f.z = t + 1
92
+ f.bar = 3.15
93
+ end
94
+ assert(!n.nil?)
95
+ end
50
96
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: judges
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.19
4
+ version: 0.0.21
5
5
  platform: ruby
6
6
  authors:
7
7
  - Yegor Bugayenko
@@ -30,14 +30,14 @@ dependencies:
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: 0.0.16
33
+ version: 0.0.21
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.16
40
+ version: 0.0.21
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: gli
43
43
  requirement: !ruby/object:Gem::Requirement
@@ -121,6 +121,7 @@ files:
121
121
  - fixtures/reward_for_good_bug/simple-reward.yml
122
122
  - judges.gemspec
123
123
  - lib/judges.rb
124
+ - lib/judges/commands/inspect.rb
124
125
  - lib/judges/commands/join.rb
125
126
  - lib/judges/commands/print.rb
126
127
  - lib/judges/commands/test.rb
@@ -134,6 +135,7 @@ files:
134
135
  - lib/judges/packs.rb
135
136
  - lib/judges/to_rel.rb
136
137
  - renovate.json
138
+ - test/commands/test_inspect.rb
137
139
  - test/commands/test_join.rb
138
140
  - test/commands/test_print.rb
139
141
  - test/commands/test_test.rb