judges 0.0.30 → 0.0.32

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: 2966161948e1ac2ed8c36b5f0e515183a9f8ea02d6ddabf396e7bd5db98ca787
4
- data.tar.gz: 227712553b74473211e835d5c1df9afbf03e00d8942639d137fea6d98d40a236
3
+ metadata.gz: cf26642d3989b5d0097e54b224bd8c8b431f5e488f04a6c6cc778f9a914e0ad6
4
+ data.tar.gz: 79974f0a047a19f499e8b9b69566ded6b9b78d3bf6f470bfc67e9aead9988dc9
5
5
  SHA512:
6
- metadata.gz: 120d2cec10fbca12aa6a9107ea348236dd44e999a8499dbef93952cb2fb313ea11bb67c658d0ebb6b6ee4f002383d2f8177d75d06bd8cb01d547032222e6b9aa
7
- data.tar.gz: 3cf907ef01704e0e11ffa8313226420536436571ab11ea9a25cf4d8c7cbc98e334cbb7e193ea5994910c36c20dcf29d0ae1d1fee040cefca9c7b5d2c0ec91a33
6
+ metadata.gz: f7af589ce71752db5991f3838ea4e6b0e13969f3caab954f21d991d692d75b592c5f3bbe5d42e26cdc9a5d2c68a8ed3fcbe87401c34b1d6daa92c380f6fc7688
7
+ data.tar.gz: 25a4cc8aa470fb2f457c9f00b1581d5e4c05ab07d8580da124fd59d92c768796b4548948cb03abfc88256936b3ad8a2ae2fa4dd0edd66a7f1ae69a8530176fcf
@@ -0,0 +1,57 @@
1
+ # Copyright (c) 2024 Yegor Bugayenko
2
+ #
3
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ # of this software and associated documentation files (the 'Software'), to deal
5
+ # in the Software without restriction, including without limitation the rights
6
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ # copies of the Software, and to permit persons to whom the Software is
8
+ # furnished to do so, subject to the following conditions:
9
+ #
10
+ # The above copyright notice and this permission notice shall be included in all
11
+ # copies or substantial portions of the Software.
12
+ #
13
+ # THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19
+ # SOFTWARE.
20
+ ---
21
+ name: license
22
+ 'on':
23
+ push:
24
+ branches:
25
+ - master
26
+ pull_request:
27
+ branches:
28
+ - master
29
+ jobs:
30
+ license:
31
+ runs-on: ubuntu-22.04
32
+ steps:
33
+ - uses: actions/checkout@v4
34
+ - shell: bash
35
+ run: |
36
+ header="Copyright (c) $(date +%Y) Yegor Bugayenko"
37
+ failed="false"
38
+ while IFS= read -r file; do
39
+ if ! grep -q "${header}" "${file}"; then
40
+ failed="true"
41
+ echo "⚠️ Copyright header is not found in: ${file}"
42
+ else
43
+ echo "File looks good: ${file}"
44
+ fi
45
+ done < <(find . -type f \( \
46
+ -name "Dockerfile" -o \
47
+ -name "LICENSE.txt" -o \
48
+ -name "Makefile" -o \
49
+ -name "Rakefile" -o \
50
+ -name "*.sh" -o \
51
+ -name "*.rb" -o \
52
+ -name "*.fe" -o \
53
+ -name "*.yml" \
54
+ \) -print)
55
+ if [ "${failed}" = "true" ]; then
56
+ exit 1
57
+ fi
data/Gemfile CHANGED
@@ -24,10 +24,10 @@ source 'https://rubygems.org'
24
24
  gemspec
25
25
 
26
26
  gem 'cucumber', '9.2.0', require: false
27
- gem 'minitest', '5.23.0', require: false
27
+ gem 'minitest', '5.23.1', require: false
28
28
  gem 'rake', '13.2.1', require: false
29
29
  gem 'rspec-rails', '6.1.2', require: false
30
- gem 'rubocop', '1.63.5', require: false
30
+ gem 'rubocop', '1.64.0', require: false
31
31
  gem 'rubocop-performance', '1.21.0', require: false
32
32
  gem 'rubocop-rspec', '2.29.2', require: false
33
33
  gem 'simplecov', '0.22.0', require: false
data/Gemfile.lock CHANGED
@@ -3,7 +3,7 @@ PATH
3
3
  specs:
4
4
  judges (0.0.0)
5
5
  backtrace (~> 0.3)
6
- factbase (~> 0.0.29)
6
+ factbase (~> 0.0.30)
7
7
  gli (~> 2.21)
8
8
  loog (~> 0.2)
9
9
  nokogiri (~> 1.10)
@@ -74,7 +74,7 @@ GEM
74
74
  docile (1.4.0)
75
75
  drb (2.2.1)
76
76
  erubi (1.12.0)
77
- factbase (0.0.29)
77
+ factbase (0.0.30)
78
78
  json (~> 2.7)
79
79
  loog (~> 0.2)
80
80
  nokogiri (~> 1.10)
@@ -95,7 +95,7 @@ GEM
95
95
  nokogiri (>= 1.12.0)
96
96
  loog (0.5.1)
97
97
  mini_mime (1.1.5)
98
- minitest (5.23.0)
98
+ minitest (5.23.1)
99
99
  multi_test (1.1.0)
100
100
  mutex_m (0.2.0)
101
101
  nokogiri (1.16.5-arm64-darwin)
@@ -112,7 +112,7 @@ GEM
112
112
  racc
113
113
  psych (5.1.2)
114
114
  stringio
115
- racc (1.7.3)
115
+ racc (1.8.0)
116
116
  rack (3.0.11)
117
117
  rack-session (2.0.0)
118
118
  rack (>= 3.0.0)
@@ -138,7 +138,7 @@ GEM
138
138
  zeitwerk (~> 2.6)
139
139
  rainbow (3.1.1)
140
140
  rake (13.2.1)
141
- rdoc (6.6.3.1)
141
+ rdoc (6.7.0)
142
142
  psych (>= 4.0.0)
143
143
  regexp_parser (2.9.2)
144
144
  reline (0.5.7)
@@ -162,7 +162,7 @@ GEM
162
162
  rspec-mocks (~> 3.13)
163
163
  rspec-support (~> 3.13)
164
164
  rspec-support (3.13.1)
165
- rubocop (1.63.5)
165
+ rubocop (1.64.0)
166
166
  json (~> 2.3)
167
167
  language_server-protocol (>= 3.17.0)
168
168
  parallel (~> 1.10)
@@ -221,10 +221,10 @@ PLATFORMS
221
221
  DEPENDENCIES
222
222
  cucumber (= 9.2.0)
223
223
  judges!
224
- minitest (= 5.23.0)
224
+ minitest (= 5.23.1)
225
225
  rake (= 13.2.1)
226
226
  rspec-rails (= 6.1.2)
227
- rubocop (= 1.63.5)
227
+ rubocop (= 1.64.0)
228
228
  rubocop-performance (= 1.21.0)
229
229
  rubocop-rspec (= 2.29.2)
230
230
  simplecov (= 0.22.0)
data/bin/judges CHANGED
@@ -32,7 +32,7 @@ Encoding.default_internal = Encoding::UTF_8
32
32
  class App
33
33
  extend GLI::App
34
34
 
35
- ver = '0.0.30'
35
+ ver = '0.0.32'
36
36
 
37
37
  loog = Loog::REGULAR
38
38
 
@@ -13,5 +13,5 @@ Feature: Import
13
13
  z: 3.14
14
14
  """
15
15
  Then I run bin/judges with "--verbose import simple.yaml simple.fb"
16
- Then Stdout contains "Import finished"
16
+ Then Stdout contains "Import of 2 facts finished"
17
17
  And Exit code is zero
@@ -49,7 +49,7 @@ When(%r{^I run bin/judges with "([^"]*)"$}) do |arg|
49
49
  home = File.join(File.dirname(__FILE__), '../..')
50
50
  cmd = "ruby -I#{home}/lib #{home}/bin/judges #{arg}"
51
51
  cmd = "GLI_DEBUG=true #{cmd}" unless Gem.win_platform?
52
- @stdout = `#{cmd}`
52
+ @stdout = `#{cmd} 2>&1`
53
53
  @exitstatus = $CHILD_STATUS.exitstatus
54
54
  end
55
55
 
@@ -8,7 +8,7 @@ Feature: Test
8
8
  And Exit code is zero
9
9
 
10
10
  Scenario: Simple test of just one pack
11
- Given I run bin/judges with "test --pack reward_for_good_bug ./fixtures"
11
+ Given I run bin/judges with "test --pack guess ./fixtures"
12
12
  Then Stdout contains "judge(s) tested successfully"
13
13
  And Exit code is zero
14
14
 
@@ -30,3 +30,23 @@ Feature: Update
30
30
  Then Stdout contains "1 judge(s) processed"
31
31
  Then Stdout contains "Update finished: 1 cycles"
32
32
  And Exit code is zero
33
+
34
+ Scenario: The update fails when a bug in a judge
35
+ Given I make a temp directory
36
+ Then I have a "mypacks/mypack/broken.rb" file with content:
37
+ """
38
+ a < 1
39
+ """
40
+ Then I run bin/judges with "update mypacks simple.fb"
41
+ Then Stdout contains "Failed to update correctly"
42
+ And Exit code is not zero
43
+
44
+ Scenario: The update fails when a broken Ruby syntax in a judge
45
+ Given I make a temp directory
46
+ Then I have a "mypacks/mypack/broken.rb" file with content:
47
+ """
48
+ invalid$ruby$syntax$here
49
+ """
50
+ Then I run bin/judges with "update mypacks simple.fb"
51
+ Then Stdout contains "Failed to update correctly"
52
+ And Exit code is not zero
@@ -0,0 +1,28 @@
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
+ $loog.info("Trying to guess a number (judge=#{$judge})...")
24
+ $fb.txn do |fbt|
25
+ n = fbt.insert
26
+ n.number = Random.rand(100)
27
+ n.time = Time.now
28
+ end
@@ -18,17 +18,8 @@
18
18
  # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19
19
  # SOFTWARE.
20
20
  ---
21
- input:
22
- -
23
- kind: bug was accepted
24
- reporter: yegor256
25
- time: 2024-01-01T03:15:45
26
- seen:
27
- - one
28
- - two
29
- - three
21
+ input: []
30
22
  expected:
31
- - /fb[count(f)=2]
32
- - /fb/f[kind='nominate for good bug']
33
- - /fb/f[payee='yegor256']
34
- - /fb/f[amount='15']
23
+ - /fb[count(f)=1]
24
+ - /fb/f/number
25
+ - /fb/f/time
@@ -0,0 +1,24 @@
1
+ # Copyright (c) 2024 Yegor Bugayenko
2
+ #
3
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ # of this software and associated documentation files (the 'Software'), to deal
5
+ # in the Software without restriction, including without limitation the rights
6
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ # copies of the Software, and to permit persons to whom the Software is
8
+ # furnished to do so, subject to the following conditions:
9
+ #
10
+ # The above copyright notice and this permission notice shall be included in all
11
+ # copies or substantial portions of the Software.
12
+ #
13
+ # THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19
+ # SOFTWARE.
20
+ ---
21
+ skip: true
22
+ input: []
23
+ expected:
24
+ - /should-never-reach-this-point
@@ -20,12 +20,8 @@
20
20
  ---
21
21
  input:
22
22
  -
23
- kind: bug was accepted
24
- reporter: yegor256
23
+ number: 42
25
24
  time: 2024-01-01T03:15:45
26
- seen:
27
- - one
28
- - reward_for_good_bug
29
- - two
30
25
  expected:
31
- - /fb[count(f)=1]
26
+ - /fb[count(f)=2]
27
+ - /fb/f/guess
@@ -20,13 +20,7 @@
20
20
  # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
21
  # SOFTWARE.
22
22
 
23
- $loog.info("Trying to reward a good reported bug (judge=#{$judge})...")
24
-
25
- once($fb).query("(eq kind 'bug was accepted')").each do |f|
26
- $loog.info('Good candidate found!')
23
+ once($fb).query("(and (exists number) (lt time #{Time.now.utc.iso8601}))").each do |f|
27
24
  n = $fb.insert
28
- n.kind = 'nominate for good bug'
29
- n.payee = f.reporter
30
- n.amount = 15
31
- n.message = 'thanks for reporting a bug; you get +15 points for this'
25
+ n.guess = f.number
32
26
  end
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.30'
29
+ s.version = '0.0.32'
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.29'
45
+ s.add_runtime_dependency 'factbase', '~>0.0.30'
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,13 +20,10 @@
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 'backtrace'
24
23
  require 'factbase/looged'
25
24
  require_relative '../../judges'
26
- require_relative '../../judges/to_rel'
27
- require_relative '../../judges/packs'
28
- require_relative '../../judges/options'
29
25
  require_relative '../../judges/impex'
26
+ require_relative '../../judges/elapsed'
30
27
 
31
28
  # Eval.
32
29
  # Author:: Yegor Bugayenko (yegor256@gmail.com)
@@ -40,12 +37,15 @@ class Judges::Eval
40
37
  def run(_opts, args)
41
38
  raise 'Exactly two arguments required' unless args.size == 2
42
39
  impex = Judges::Impex.new(@loog, args[0])
43
- $fb = impex.import(strict: false)
44
- $fb = Factbase::Looged.new($fb, @loog)
45
- expr = args[1]
46
- # rubocop:disable Security/Eval
47
- eval(expr)
48
- # rubocop:enable Security/Eval
49
- impex.export($fb)
40
+ elapsed(@loog) do
41
+ $fb = impex.import(strict: false)
42
+ $fb = Factbase::Looged.new($fb, @loog)
43
+ expr = args[1]
44
+ # rubocop:disable Security/Eval
45
+ eval(expr)
46
+ # rubocop:enable Security/Eval
47
+ impex.export($fb)
48
+ throw :'Evaluated successfully'
49
+ end
50
50
  end
51
51
  end
@@ -25,6 +25,7 @@ require 'factbase/looged'
25
25
  require_relative '../../judges'
26
26
  require_relative '../../judges/impex'
27
27
  require_relative '../../judges/to_rel'
28
+ require_relative '../../judges/elapsed'
28
29
 
29
30
  # Import.
30
31
  # Author:: Yegor Bugayenko (yegor256@gmail.com)
@@ -38,19 +39,20 @@ class Judges::Import
38
39
  def run(_opts, args)
39
40
  raise 'Exactly two arguments required' unless args.size == 2
40
41
  raise "File not found #{args[0].to_rel}" unless File.exist?(args[0])
41
- start = Time.now
42
- yaml = YAML.load_file(args[0], permitted_classes: [Time])
43
- @loog.info("YAML loaded from #{args[0].to_rel} (#{yaml.size} facts)")
44
- impex = Judges::Impex.new(@loog, args[1])
45
- fb = impex.import(strict: false)
46
- fb = Factbase::Looged.new(fb, @loog)
47
- yaml.each do |i|
48
- f = fb.insert
49
- i.each do |p, v|
50
- f.send("#{p}=", v)
42
+ elapsed(@loog) do
43
+ yaml = YAML.load_file(args[0], permitted_classes: [Time])
44
+ @loog.info("YAML loaded from #{args[0].to_rel} (#{yaml.size} facts)")
45
+ impex = Judges::Impex.new(@loog, args[1])
46
+ fb = impex.import(strict: false)
47
+ fb = Factbase::Looged.new(fb, @loog)
48
+ yaml.each do |i|
49
+ f = fb.insert
50
+ i.each do |p, v|
51
+ f.send("#{p}=", v)
52
+ end
51
53
  end
54
+ impex.export(fb)
55
+ throw :"Import of #{yaml.size} facts finished"
52
56
  end
53
- impex.export(fb)
54
- @loog.info("Import finished in #{format('%.02f', Time.now - start)}s")
55
57
  end
56
58
  end
@@ -22,6 +22,7 @@
22
22
 
23
23
  require_relative '../../judges'
24
24
  require_relative '../../judges/impex'
25
+ require_relative '../../judges/elapsed'
25
26
 
26
27
  # Join.
27
28
  # Author:: Yegor Bugayenko (yegor256@gmail.com)
@@ -36,9 +37,11 @@ class Judges::Join
36
37
  raise 'Exactly two arguments required' unless args.size == 2
37
38
  master = Judges::Impex.new(@loog, args[0])
38
39
  slave = Judges::Impex.new(@loog, args[1])
39
- fb = master.import
40
- slave.import_to(fb)
41
- master.export(fb)
42
- @loog.info('Two factbases joined')
40
+ elapsed(@loog) do
41
+ fb = master.import
42
+ slave.import_to(fb)
43
+ master.export(fb)
44
+ throw :'Two factbases joined'
45
+ end
43
46
  end
44
47
  end
@@ -24,6 +24,7 @@ require 'fileutils'
24
24
  require 'factbase'
25
25
  require_relative '../../judges'
26
26
  require_relative '../../judges/impex'
27
+ require_relative '../../judges/elapsed'
27
28
 
28
29
  # Update.
29
30
  # Author:: Yegor Bugayenko (yegor256@gmail.com)
@@ -53,20 +54,21 @@ class Judges::Print
53
54
  end
54
55
  @loog.debug("The factbase #{f.to_rel} is younger than the target #{o.to_rel}, need to print")
55
56
  end
56
- start = Time.now
57
- output =
58
- case opts[:format].downcase
59
- when 'yaml'
60
- require 'factbase/to_yaml'
61
- Factbase::ToYAML.new(fb).yaml
62
- when 'json'
63
- require 'factbase/to_json'
64
- Factbase::ToJSON.new(fb).json
65
- when 'xml'
66
- require 'factbase/to_xml'
67
- Factbase::ToXML.new(fb).xml
68
- end
69
- File.binwrite(o, output)
70
- @loog.info("Factbase printed to #{o.to_rel} (#{File.size(o)} bytes) in #{format('%.02f', Time.now - start)}s")
57
+ elapsed(@loog) do
58
+ output =
59
+ case opts[:format].downcase
60
+ when 'yaml'
61
+ require 'factbase/to_yaml'
62
+ Factbase::ToYAML.new(fb).yaml
63
+ when 'json'
64
+ require 'factbase/to_json'
65
+ Factbase::ToJSON.new(fb).json
66
+ when 'xml'
67
+ require 'factbase/to_xml'
68
+ Factbase::ToXML.new(fb).xml
69
+ end
70
+ File.binwrite(o, output)
71
+ throw :"Factbase printed to #{o.to_rel} (#{File.size(o)} bytes)"
72
+ end
71
73
  end
72
74
  end
@@ -29,6 +29,7 @@ require_relative '../../judges'
29
29
  require_relative '../../judges/to_rel'
30
30
  require_relative '../../judges/packs'
31
31
  require_relative '../../judges/options'
32
+ require_relative '../../judges/elapsed'
32
33
 
33
34
  # Test.
34
35
  # Author:: Yegor Bugayenko (yegor256@gmail.com)
@@ -45,34 +46,32 @@ class Judges::Test
45
46
  @loog.info("Testing judges in #{dir.to_rel}...")
46
47
  errors = []
47
48
  done = 0
48
- global = {}
49
- start = Time.now
50
- Judges::Packs.new(dir, opts['lib'], @loog).each_with_index do |p, i|
51
- local = {}
52
- next unless include?(opts, p.name)
53
- @loog.info("\n👉 Testing #{p.script} (##{i}) in #{p.dir.to_rel}...")
54
- p.tests.each do |f|
55
- yaml = YAML.load_file(f, permitted_classes: [Time])
56
- @loog.info("Testing #{f.to_rel}:")
57
- begin
58
- test_one(p, global, local, yaml)
59
- rescue StandardError => e
60
- @loog.warn(Backtrace.new(e))
61
- errors << f
49
+ elapsed(@loog) do
50
+ Judges::Packs.new(dir, opts['lib'], @loog).each_with_index do |p, i|
51
+ next unless include?(opts, p.name)
52
+ @loog.info("\n👉 Testing #{p.script} (##{i}) in #{p.dir.to_rel}...")
53
+ p.tests.each do |f|
54
+ yaml = YAML.load_file(f, permitted_classes: [Time])
55
+ if yaml['skip']
56
+ @loog.info("Skippped #{f.to_rel}")
57
+ next
58
+ end
59
+ @loog.info("Testing #{f.to_rel}:")
60
+ begin
61
+ test_one(p, yaml)
62
+ rescue StandardError => e
63
+ @loog.warn(Backtrace.new(e))
64
+ errors << f
65
+ end
62
66
  end
67
+ done += 1
63
68
  end
64
- done += 1
65
- end
66
- lapse = "in #{format('%.02f', Time.now - start)}s"
67
- if done.zero?
68
- raise 'No judges tested :(' unless opts['quiet']
69
- @loog.warn("\n👍 No judges tested #{lapse}")
70
- elsif errors.empty?
71
- @loog.info("\n👍 All #{done} judge(s) tested successfully #{lapse}")
72
- else
73
- @loog.info("\n❌ #{done} judge(s) tested, #{errors.size} of them failed #{lapse}")
74
- raise "#{errors.size} tests failed" unless opts['quiet']
69
+ throw :'👍 No judges tested' if done.zero?
70
+ throw :"👍 All #{done} judge(s) tested successfully" if errors.empty?
71
+ throw :" #{done} judge(s) tested, #{errors.size} of them failed"
75
72
  end
73
+ raise "#{errors.size} tests failed" unless opts['quiet'] || errors.empty?
74
+ raise 'No judges tested :(' unless opts['quiet'] || !done.zero?
76
75
  end
77
76
 
78
77
  private
@@ -83,7 +82,7 @@ class Judges::Test
83
82
  packs.include?(name)
84
83
  end
85
84
 
86
- def test_one(pack, global, local, yaml)
85
+ def test_one(pack, yaml)
87
86
  fb = Factbase.new
88
87
  yaml['input'].each do |i|
89
88
  f = fb.insert
@@ -97,7 +96,7 @@ class Judges::Test
97
96
  end
98
97
  end
99
98
  end
100
- pack.run(Factbase::Looged.new(fb, @loog), global, local, Judges::Options.new(yaml['options']))
99
+ pack.run(Factbase::Looged.new(fb, @loog), {}, {}, Judges::Options.new(yaml['options']))
101
100
  xml = Nokogiri::XML.parse(Factbase::ToXML.new(fb).xml)
102
101
  yaml['expected'].each do |xp|
103
102
  raise "#{pack.script} doesn't match '#{xp}':\n#{xml}" if xml.xpath(xp).empty?
@@ -23,6 +23,7 @@
23
23
  require 'time'
24
24
  require_relative '../../judges'
25
25
  require_relative '../../judges/impex'
26
+ require_relative '../../judges/elapsed'
26
27
 
27
28
  # Trim.
28
29
  # Author:: Yegor Bugayenko (yegor256@gmail.com)
@@ -46,14 +47,11 @@ class Judges::Trim
46
47
  else
47
48
  raise 'Specify either --days or --query' unless opts['days'].nil?
48
49
  end
49
- start = Time.now
50
- deleted = fb.query(query).delete!
51
- lapse = "in #{format('%.02f', Time.now - start)}s"
52
- if deleted.zero?
53
- @loog.info("No facts deleted #{lapse}")
54
- else
55
- @loog.info("🗑 #{deleted} fact(s) deleted #{lapse}")
50
+ elapsed(@loog) do
51
+ deleted = fb.query(query).delete!
52
+ throw :'No facts deleted' if deleted.zero?
56
53
  impex.export(fb)
54
+ throw :"🗑 #{deleted} fact(s) deleted"
57
55
  end
58
56
  end
59
57
  end
@@ -27,6 +27,7 @@ require_relative '../../judges/to_rel'
27
27
  require_relative '../../judges/packs'
28
28
  require_relative '../../judges/options'
29
29
  require_relative '../../judges/impex'
30
+ require_relative '../../judges/elapsed'
30
31
 
31
32
  # Update.
32
33
  # Author:: Yegor Bugayenko (yegor256@gmail.com)
@@ -48,23 +49,27 @@ class Judges::Update
48
49
  @loog.debug("The following options provided:\n\t#{options.to_s.gsub("\n", "\n\t")}")
49
50
  packs = Judges::Packs.new(dir, opts['lib'], @loog)
50
51
  c = 0
51
- start = Time.now
52
- loop do
53
- c += 1
54
- diff = cycle(opts, packs, fb, options)
55
- impex.export(fb)
56
- break if diff.zero?
57
- if !opts['max-cycles'].nil? && c >= opts['max-cycles']
58
- @loog.info('Too many cycles already, as set by --max-cycles, breaking')
59
- break
52
+ elapsed(@loog) do
53
+ loop do
54
+ c += 1
55
+ if c > 1
56
+ @loog.info("\n\nStarting cycle ##{c}#{opts['max-cycles'] ? " (out of #{opts['max-cycles']})" : ''}...")
57
+ end
58
+ diff = cycle(opts, packs, fb, options)
59
+ impex.export(fb)
60
+ break if diff.zero?
61
+ if !opts['max-cycles'].nil? && c >= opts['max-cycles']
62
+ @loog.info('Too many cycles already, as set by --max-cycles, breaking')
63
+ break
64
+ end
65
+ @loog.info(
66
+ "By #{diff} facts the factbase " \
67
+ "#{diff.positive? ? 'increased' : 'decreased'} " \
68
+ "its size at the cycle ##{c}"
69
+ )
60
70
  end
61
- @loog.info(
62
- "By #{diff} facts the factbase " \
63
- "#{diff.positive? ? 'increased' : 'decreased'} " \
64
- "its size at the cycle ##{c}"
65
- )
71
+ throw :"Update finished: #{c} cycles"
66
72
  end
67
- @loog.info("Update finished: #{c} cycles in #{format('%.02f', Time.now - start)}s")
68
73
  end
69
74
 
70
75
  private
@@ -73,25 +78,27 @@ class Judges::Update
73
78
  errors = []
74
79
  diff = 0
75
80
  global = {}
76
- done = packs.each_with_index do |p, i|
77
- local = {}
78
- @loog.info("👉 Running #{p.name} (##{i}) at #{p.dir.to_rel}...")
79
- before = fb.size
80
- begin
81
- p.run(fb, global, local, options)
82
- rescue StandardError => e
83
- @loog.warn(Backtrace.new(e))
84
- errors << p.script
81
+ elapsed(@loog) do
82
+ done = packs.each_with_index do |p, i|
83
+ local = {}
84
+ @loog.info("👉 Running #{p.name} (##{i}) at #{p.dir.to_rel}...")
85
+ before = fb.size
86
+ begin
87
+ p.run(fb, global, local, options)
88
+ rescue StandardError, SyntaxError => e
89
+ @loog.warn(Backtrace.new(e))
90
+ errors << p.script
91
+ end
92
+ after = fb.size
93
+ @loog.info("👍 The judge #{p.dir.to_rel} added #{after - before} facts") if after > before
94
+ diff += after - before
85
95
  end
86
- after = fb.size
87
- @loog.info("👍 Pack #{p.dir.to_rel} added #{after - before} facts") if after > before
88
- diff += after - before
96
+ throw :"👍 #{done} judge(s) processed" if errors.empty?
97
+ throw :" #{done} judge(s) processed with #{errors.size} errors"
89
98
  end
90
- if errors.empty?
91
- @loog.info("👍 #{done} judge(s) processed")
92
- else
93
- @loog.info("❌ #{done} judge(s) processed with #{errors.size} errors")
99
+ unless errors.empty?
94
100
  raise "Failed to update correctly (#{errors.size} errors)" unless opts['quiet']
101
+ @loog.info('Not failing because of the --quiet flag provided')
95
102
  end
96
103
  diff
97
104
  end
@@ -0,0 +1,32 @@
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
+ def elapsed(loog)
24
+ start = Time.now
25
+ begin
26
+ yield
27
+ rescue UncaughtThrowError => e
28
+ tag = e.tag
29
+ throw e unless tag.is_a?(Symbol)
30
+ loog.info("#{tag} in #{format('%.02f', Time.now - start)}s")
31
+ end
32
+ end
data/lib/judges/pack.rb CHANGED
@@ -22,6 +22,7 @@
22
22
 
23
23
  require_relative '../judges'
24
24
  require_relative '../judges/to_rel'
25
+ require_relative '../judges/elapsed'
25
26
  require_relative '../judges/fb/once'
26
27
  require_relative '../judges/fb/if_absent'
27
28
 
@@ -55,8 +56,9 @@ class Judges::Pack
55
56
  end
56
57
  s = File.join(@dir, script)
57
58
  raise "Can't load '#{s}'" unless File.exist?(s)
58
- begin
59
+ elapsed(@loog) do
59
60
  load(s, true)
61
+ throw :"#{name} finished"
60
62
  ensure
61
63
  $fb = $judge = $options = $loog = nil
62
64
  end
@@ -62,9 +62,19 @@ class TestUpdate < Minitest::Test
62
62
 
63
63
  def test_update_with_error
64
64
  Dir.mktmpdir do |d|
65
- File.write(File.join(d, 'foo.rb'), 'this is a broken Ruby script')
65
+ File.write(File.join(d, 'foo.rb'), 'this$is$a$broken$Ruby$script')
66
66
  file = File.join(d, 'base.fb')
67
67
  Judges::Update.new(Loog::NULL).run({ 'quiet' => true }, [d, file])
68
68
  end
69
69
  end
70
+
71
+ def test_update_with_error_no_quiet
72
+ assert_raises do
73
+ Dir.mktmpdir do |d|
74
+ File.write(File.join(d, 'foo.rb'), 'a < 1')
75
+ file = File.join(d, 'base.fb')
76
+ Judges::Update.new(Loog::NULL).run({ 'quiet' => false }, [d, file])
77
+ end
78
+ end
79
+ end
70
80
  end
data/test/test_pack.rb CHANGED
@@ -107,4 +107,28 @@ class TestPack < Minitest::Test
107
107
  assert_equal(42, fb.query('()').each.to_a.first.bar)
108
108
  end
109
109
  end
110
+
111
+ def test_with_broken_ruby_syntax
112
+ assert_raises do
113
+ Dir.mktmpdir do |d|
114
+ dir = File.join(d, 'packs')
115
+ FileUtils.mkdir_p(dir)
116
+ File.write(File.join(dir, 'x.rb'), 'this$is$broken$syntax')
117
+ pack = Judges::Pack.new(dir, lib, Loog::NULL)
118
+ pack.run(Factbase.new, {}, {}, {})
119
+ end
120
+ end
121
+ end
122
+
123
+ def test_with_runtime_ruby_error
124
+ assert_raises do
125
+ Dir.mktmpdir do |d|
126
+ dir = File.join(d, 'packs')
127
+ FileUtils.mkdir_p(dir)
128
+ File.write(File.join(dir, 'x.rb'), 'a < 1')
129
+ pack = Judges::Pack.new(dir, lib, Loog::NULL)
130
+ pack.run(Factbase.new, {}, {}, {})
131
+ end
132
+ end
133
+ end
110
134
  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.30
4
+ version: 0.0.32
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-21 00:00:00.000000000 Z
11
+ date: 2024-05-24 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.29
33
+ version: 0.0.30
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.29
40
+ version: 0.0.30
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: gli
43
43
  requirement: !ruby/object:Gem::Requirement
@@ -96,6 +96,7 @@ files:
96
96
  - ".gitattributes"
97
97
  - ".github/workflows/actionlint.yml"
98
98
  - ".github/workflows/codecov.yml"
99
+ - ".github/workflows/license.yml"
99
100
  - ".github/workflows/markdown-lint.yml"
100
101
  - ".github/workflows/pdd.yml"
101
102
  - ".github/workflows/rake.yml"
@@ -123,10 +124,11 @@ files:
123
124
  - features/test.feature
124
125
  - features/trim.feature
125
126
  - features/update.feature
126
- - fixtures/reward_for_good_bug/README.md
127
- - fixtures/reward_for_good_bug/no-reward.yml
128
- - fixtures/reward_for_good_bug/reward_it.rb
129
- - fixtures/reward_for_good_bug/simple-reward.yml
127
+ - fixtures/guess/guess.rb
128
+ - fixtures/guess/guess_made.yml
129
+ - fixtures/guess/skipped.yml
130
+ - fixtures/try/tried.yml
131
+ - fixtures/try/try.rb
130
132
  - judges.gemspec
131
133
  - lib/judges.rb
132
134
  - lib/judges/commands/eval.rb
@@ -137,6 +139,7 @@ files:
137
139
  - lib/judges/commands/test.rb
138
140
  - lib/judges/commands/trim.rb
139
141
  - lib/judges/commands/update.rb
142
+ - lib/judges/elapsed.rb
140
143
  - lib/judges/fb/if_absent.rb
141
144
  - lib/judges/fb/once.rb
142
145
  - lib/judges/impex.rb
@@ -1,8 +0,0 @@
1
- # Why bugs reports are rewarded?
2
-
3
- Every bug reported and accepted deserves a reward, which
4
- are given to the reporter of the bug. A bug is considered as
5
- "accepted" only if it has the `bug`, `enhancement`, or `question` label
6
- attached to it. Such a reward encourages programmers to report
7
- more bugs, thus revealing problems that will be fixed before they
8
- are shipped to a customer.