judges 0.20.0 ā†’ 0.22.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -51,9 +51,14 @@ class Judges::Pull
51
51
  )
52
52
  name = args[0]
53
53
  elapsed(@loog) do
54
+ baza.lock(name, opts['owner'])
54
55
  if baza.name_exists?(name)
55
- baza.lock(name, opts['owner'])
56
- fb.import(baza.pull(wait(name, baza, baza.recent(name), opts['wait'])))
56
+ jid = baza.recent(name)
57
+ unless baza.exit_code(jid).zero?
58
+ @loog.warn("STDOUT of the job ##{jid} (from the server):\n#{baza.stdout(jid)}")
59
+ raise "The job ##{jid} ('#{name}') is broken, maybe you should expire it"
60
+ end
61
+ fb.import(baza.pull(wait(name, baza, jid, opts['wait'])))
57
62
  Judges::Impex.new(@loog, args[1]).export(fb)
58
63
  throw :"Pulled #{fb.size} facts by the name '#{name}'"
59
64
  else
@@ -48,7 +48,8 @@ class Judges::Push
48
48
  ssl: opts['ssl'],
49
49
  timeout: (opts['timeout'] || 30).to_i,
50
50
  loog: @loog,
51
- retries: (opts['retries'] || 3).to_i
51
+ retries: (opts['retries'] || 3).to_i,
52
+ compression: opts.fetch('zip', true)
52
53
  )
53
54
  elapsed(@loog) do
54
55
  baza.lock(name, opts['owner'])
@@ -82,6 +82,12 @@ class Judges::Test
82
82
  test_one(fb, opts, j, n, yaml, assert: false)
83
83
  end
84
84
  test_one(fb, opts, judge, tname, yaml)
85
+ yaml['after']&.each do |rb|
86
+ @loog.info("Running #{rb} assertion script...")
87
+ $fb = fb
88
+ $loog = @loog
89
+ load(File.join(judge.dir, rb), true)
90
+ end
85
91
  tests += 1
86
92
  rescue StandardError => e
87
93
  @loog.warn(Backtrace.new(e))
@@ -64,7 +64,7 @@ class Judges::Update
64
64
  loop do
65
65
  c += 1
66
66
  if c > 1
67
- @loog.info("\n\nStarting cycle ##{c}#{opts['max-cycles'] ? " (out of #{opts['max-cycles']})" : ''}...")
67
+ @loog.info("\nStarting cycle ##{c}#{opts['max-cycles'] ? " (out of #{opts['max-cycles']})" : ''}...")
68
68
  end
69
69
  delta = cycle(opts, judges, fb, options)
70
70
  churn += delta
@@ -103,17 +103,18 @@ class Judges::Update
103
103
  churn = Judges::Churn.new(0, 0)
104
104
  global = {}
105
105
  elapsed(@loog) do
106
- done = judges.each_with_index do |p, i|
107
- @loog.info("\nšŸ‘‰ Running #{p.name} (##{i}) at #{p.dir.to_rel}...")
108
- elapsed(@loog) do
109
- c = one_judge(fb, p, global, options)
110
- churn += c
111
- throw :"šŸ‘ The judge #{p.name} modified #{c} facts out of #{fb.size}"
106
+ done =
107
+ judges.each_with_index do |p, i|
108
+ @loog.info("\nšŸ‘‰ Running #{p.name} (##{i}) at #{p.dir.to_rel}...")
109
+ elapsed(@loog) do
110
+ c = one_judge(fb, p, global, options)
111
+ churn += c
112
+ throw :"šŸ‘ The judge #{p.name} modified #{c} facts out of #{fb.size}"
113
+ end
114
+ rescue StandardError, SyntaxError => e
115
+ @loog.warn(Backtrace.new(e))
116
+ churn << e.message
112
117
  end
113
- rescue StandardError, SyntaxError => e
114
- @loog.warn(Backtrace.new(e))
115
- churn << e.message
116
- end
117
118
  throw :"šŸ‘ #{done} judge(s) processed" if churn.errors.empty?
118
119
  throw :"āŒ #{done} judge(s) processed with #{churn.errors.size} errors"
119
120
  end
data/lib/judges/judge.rb CHANGED
@@ -70,9 +70,10 @@ class Judges::Judge
70
70
 
71
71
  # Get the name of the .rb script in the judge.
72
72
  def script
73
- s = Dir.glob(File.join(@dir, '*.rb')).first
74
- raise "No *.rb scripts in #{@dir.to_rel}" if s.nil?
75
- File.basename(s)
73
+ b = "#{File.basename(@dir)}.rb"
74
+ files = Dir.glob(File.join(@dir, '*.rb')).map { |f| File.basename(f) }
75
+ raise "No #{b} script in #{@dir.to_rel} among #{files}" unless files.include?(b)
76
+ b
76
77
  end
77
78
 
78
79
  # Return all .yml tests files.
data/lib/judges/judges.rb CHANGED
@@ -24,6 +24,20 @@ require_relative '../judges'
24
24
  require_relative 'judge'
25
25
 
26
26
  # Collection of all judges to run.
27
+ #
28
+ # In the directory +dir+ the following structure must be maintained:
29
+ #
30
+ # dir/
31
+ # judge-one/
32
+ # judge-one.rb
33
+ # other files...
34
+ # judge-two/
35
+ # judge-two.rb
36
+ # other files...
37
+ #
38
+ # The name of a directory of a judge must be exactly the same as the
39
+ # name of the +.rb+ script inside the directory.
40
+ #
27
41
  # Author:: Yegor Bugayenko (yegor256@gmail.com)
28
42
  # Copyright:: Copyright (c) 2024 Yegor Bugayenko
29
43
  # License:: MIT
@@ -45,9 +59,12 @@ class Judges::Judges
45
59
  # Iterate over them all.
46
60
  # @yield [Judge]
47
61
  def each
48
- Dir.glob(File.join(@dir, '**/*.rb')).each do |f|
49
- d = File.dirname(File.absolute_path(f))
50
- yield Judges::Judge.new(d, @lib, @loog)
62
+ return to_enum(__method__) unless block_given?
63
+ Dir.glob(File.join(@dir, '*')).each do |d|
64
+ next unless File.directory?(d)
65
+ b = File.basename(d)
66
+ next unless File.exist?(File.join(d, "#{b}.rb"))
67
+ yield Judges::Judge.new(File.absolute_path(d), @lib, @loog)
51
68
  end
52
69
  end
53
70
 
@@ -50,34 +50,35 @@ class Judges::Options
50
50
  def to_s
51
51
  to_h.map do |k, v|
52
52
  v = v.to_s
53
- v = "#{v[0..3]}#{'*' * (v.length - 4)}" if v.length > 8
53
+ v = "#{v[0..3]}#{'*' * (v.length - 8)}#{v[-4..]}" if v.length > 8
54
54
  "#{k} ā†’ \"#{v}\""
55
- end.join("\n")
55
+ end.sort.join("\n")
56
56
  end
57
57
 
58
58
  def to_h
59
- @to_h ||= begin
60
- pp = @pairs || []
61
- pp = pp.split(',') if pp.is_a?(String)
62
- if pp.is_a?(Array)
63
- pp = pp
64
- .compact
65
- .map(&:strip)
66
- .reject(&:empty?)
67
- .map { |s| s.split('=', 2) }
68
- .map { |a| a.size == 1 ? [a[0], nil] : a }
69
- .reject { |a| a[0].empty? }
59
+ @to_h ||=
60
+ begin
61
+ pp = @pairs || []
62
+ pp = pp.split(',') if pp.is_a?(String)
63
+ if pp.is_a?(Array)
64
+ pp = pp
65
+ .compact
66
+ .map(&:strip)
67
+ .reject(&:empty?)
68
+ .map { |s| s.split('=', 2) }
69
+ .map { |a| a.size == 1 ? [a[0], nil] : a }
70
+ .reject { |a| a[0].empty? }
71
+ .to_h
72
+ end
73
+ pp
74
+ .reject { |k, _| k.nil? }
75
+ .reject { |k, _| k.is_a?(String) && k.empty? }
70
76
  .to_h
77
+ .transform_values { |v| v.nil? ? 'true' : v }
78
+ .transform_values { |v| v.is_a?(String) ? v.strip : v }
79
+ .transform_values { |v| v.is_a?(String) && v.match?(/^[0-9]+$/) ? v.to_i : v }
80
+ .transform_keys { |k| k.to_s.strip.upcase.to_sym }
71
81
  end
72
- pp
73
- .reject { |k, _| k.nil? }
74
- .reject { |k, _| k.is_a?(String) && k.empty? }
75
- .to_h
76
- .transform_values { |v| v.nil? ? 'true' : v }
77
- .transform_values { |v| v.is_a?(String) ? v.strip : v }
78
- .transform_values { |v| v.is_a?(String) && v.match?(/^[0-9]+$/) ? v.to_i : v }
79
- .transform_keys { |k| k.to_s.strip.upcase.to_sym }
80
- end
81
82
  end
82
83
 
83
84
  # Get option by name.
data/lib/judges.rb CHANGED
@@ -25,5 +25,5 @@
25
25
  # Copyright:: Copyright (c) 2024 Yegor Bugayenko
26
26
  # License:: MIT
27
27
  module Judges
28
- VERSION = '0.20.0'
28
+ VERSION = '0.22.0'
29
29
  end
@@ -36,7 +36,7 @@ class TestImport < Minitest::Test
36
36
  Dir.mktmpdir do |d|
37
37
  file = File.join(d, 'base.fb')
38
38
  yaml = File.join(d, 'input.yml')
39
- File.write(
39
+ save_it(
40
40
  yaml,
41
41
  <<-YAML
42
42
  -
@@ -38,6 +38,7 @@ class TestPull < Minitest::Test
38
38
  stub_request(:get, 'http://example.org/exists/foo').to_return(body: 'yes')
39
39
  stub_request(:get, 'http://example.org/recent/foo.txt').to_return(body: '42')
40
40
  stub_request(:get, 'http://example.org/finished/42').to_return(body: 'yes')
41
+ stub_request(:get, 'http://example.org/exit/42').to_return(body: '0')
41
42
  fb = Factbase.new
42
43
  fb.insert.foo = 42
43
44
  stub_request(:get, 'http://example.org/pull/42.fb').to_return(body: fb.export)
@@ -58,4 +59,32 @@ class TestPull < Minitest::Test
58
59
  fb.import(File.binread(file))
59
60
  end
60
61
  end
62
+
63
+ def test_fail_pull_when_job_is_broken
64
+ WebMock.disable_net_connect!
65
+ stub_request(:get, 'http://example.org/lock/foo?owner=none').to_return(status: 302)
66
+ stub_request(:get, 'http://example.org/exists/foo').to_return(body: 'yes')
67
+ stub_request(:get, 'http://example.org/recent/foo.txt').to_return(body: '42')
68
+ stub_request(:get, 'http://example.org/finished/42').to_return(body: 'yes')
69
+ stub_request(:get, 'http://example.org/exit/42').to_return(body: '1')
70
+ stub_request(:get, 'http://example.org/stdout/42').to_return(body: 'oops, some trouble here')
71
+ Dir.mktmpdir do |d|
72
+ file = File.join(d, 'base.fb')
73
+ e =
74
+ assert_raises do
75
+ Judges::Pull.new(Loog::NULL).run(
76
+ {
77
+ 'token' => '000',
78
+ 'host' => 'example.org',
79
+ 'port' => 80,
80
+ 'ssl' => false,
81
+ 'wait' => 10,
82
+ 'owner' => 'none'
83
+ },
84
+ ['foo', file]
85
+ )
86
+ end
87
+ assert(e.message.include?('expire it'), e)
88
+ end
89
+ end
61
90
  end
@@ -32,9 +32,9 @@ require_relative '../../lib/judges/commands/test'
32
32
  class TestTest < Minitest::Test
33
33
  def test_positive
34
34
  Dir.mktmpdir do |d|
35
- File.write(File.join(d, 'foo.rb'), '$fb.query("(eq foo 42)").each { |f| f.bar = 4 }')
36
- File.write(
37
- File.join(d, 'something.yml'),
35
+ save_it(File.join(d, 'foo/foo.rb'), '$fb.query("(eq foo 42)").each { |f| f.bar = 4 }')
36
+ save_it(
37
+ File.join(d, 'foo/something.yml'),
38
38
  <<-YAML
39
39
  input:
40
40
  -
@@ -51,9 +51,9 @@ class TestTest < Minitest::Test
51
51
 
52
52
  def test_negative
53
53
  Dir.mktmpdir do |d|
54
- File.write(File.join(d, 'foo.rb'), '$fb.query("(eq foo 42)").each { |f| f.bar = 4 }')
55
- File.write(
56
- File.join(d, 'something.yml'),
54
+ save_it(File.join(d, 'foo/foo.rb'), '$fb.query("(eq foo 42)").each { |f| f.bar = 4 }')
55
+ save_it(
56
+ File.join(d, 'foo/something.yml'),
57
57
  <<-YAML
58
58
  input:
59
59
  -
@@ -72,9 +72,9 @@ class TestTest < Minitest::Test
72
72
 
73
73
  def test_with_options
74
74
  Dir.mktmpdir do |d|
75
- File.write(File.join(d, 'foo.rb'), '$fb.insert.foo = $options.bar')
76
- File.write(
77
- File.join(d, 'something.yml'),
75
+ save_it(File.join(d, 'foo/foo.rb'), '$fb.insert.foo = $options.bar')
76
+ save_it(
77
+ File.join(d, 'foo/something.yml'),
78
78
  <<-YAML
79
79
  input: []
80
80
  options:
@@ -90,13 +90,10 @@ class TestTest < Minitest::Test
90
90
 
91
91
  def test_with_before
92
92
  Dir.mktmpdir do |d|
93
- home = File.join(d, 'judges')
94
- FileUtils.mkdir_p(File.join(home, 'first'))
95
- File.write(File.join(d, 'judges/first/the-first.rb'), 'x = $fb.size; $fb.insert.foo = x')
96
- FileUtils.mkdir_p(File.join(home, 'second'))
97
- File.write(File.join(d, 'judges/second/the-second.rb'), '$fb.insert.bar = 55')
98
- File.write(
99
- File.join(d, 'judges/second/something.yml'),
93
+ save_it(File.join(d, 'first/first.rb'), 'x = $fb.size; $fb.insert.foo = x')
94
+ save_it(File.join(d, 'second/second.rb'), '$fb.insert.bar = 55')
95
+ save_it(
96
+ File.join(d, 'second/something.yml'),
100
97
  <<-YAML
101
98
  input:
102
99
  -
@@ -110,15 +107,15 @@ class TestTest < Minitest::Test
110
107
  - /fb/f[bar=55]
111
108
  YAML
112
109
  )
113
- Judges::Test.new(Loog::NULL).run({}, [home])
110
+ Judges::Test.new(Loog::NULL).run({}, [d])
114
111
  end
115
112
  end
116
113
 
117
114
  def test_one_judge_negative
118
115
  Dir.mktmpdir do |d|
119
- File.write(File.join(d, 'foo.rb'), '')
120
- File.write(
121
- File.join(d, 'x.yml'),
116
+ save_it(File.join(d, 'foo/foo.rb'), '')
117
+ save_it(
118
+ File.join(d, 'foo/x.yml'),
122
119
  <<-YAML
123
120
  input: []
124
121
  expected:
@@ -130,4 +127,20 @@ class TestTest < Minitest::Test
130
127
  end
131
128
  end
132
129
  end
130
+
131
+ def test_with_after_assertion
132
+ Dir.mktmpdir do |d|
133
+ save_it(File.join(d, 'foo/foo.rb'), '$fb.insert.foo = 42;')
134
+ save_it(File.join(d, 'foo/assert.rb'), 'raise unless $fb.size == 1')
135
+ save_it(
136
+ File.join(d, 'foo/x.yml'),
137
+ <<-YAML
138
+ input: []
139
+ after:
140
+ - assert.rb
141
+ YAML
142
+ )
143
+ Judges::Test.new(Loog::NULL).run({}, [d])
144
+ end
145
+ end
133
146
  end
@@ -34,7 +34,7 @@ require_relative '../../lib/judges/commands/update'
34
34
  class TestUpdate < Minitest::Test
35
35
  def test_build_factbase_from_scratch
36
36
  Dir.mktmpdir do |d|
37
- File.write(File.join(d, 'foo.rb'), 'return if $fb.size > 2; $fb.insert.zzz = $options.foo_bar + 1')
37
+ save_it(File.join(d, 'foo/foo.rb'), 'return if $fb.size > 2; $fb.insert.zzz = $options.foo_bar + 1')
38
38
  file = File.join(d, 'base.fb')
39
39
  Judges::Update.new(Loog::NULL).run({ 'option' => ['foo_bar=42'] }, [d, file])
40
40
  fb = Factbase.new
@@ -50,7 +50,7 @@ class TestUpdate < Minitest::Test
50
50
  fb = Factbase.new
51
51
  fb.insert.foo_bar = 42
52
52
  File.binwrite(file, fb.export)
53
- File.write(File.join(d, 'foo.rb'), '$fb.insert.tt = 4')
53
+ save_it(File.join(d, 'foo/foo.rb'), '$fb.insert.tt = 4')
54
54
  Judges::Update.new(Loog::NULL).run({ 'max-cycles' => 1 }, [d, file])
55
55
  fb = Factbase.new
56
56
  fb.import(File.binread(file))
@@ -62,7 +62,7 @@ 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
+ save_it(File.join(d, 'foo/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, 'max-cycles' => 2 }, [d, file])
68
68
  end
@@ -71,7 +71,7 @@ class TestUpdate < Minitest::Test
71
71
  def test_update_with_error_no_quiet
72
72
  assert_raises do
73
73
  Dir.mktmpdir do |d|
74
- File.write(File.join(d, 'foo.rb'), 'a < 1')
74
+ save_it(File.join(d, 'foo/foo.rb'), 'a < 1')
75
75
  file = File.join(d, 'base.fb')
76
76
  Judges::Update.new(Loog::NULL).run({ 'quiet' => false }, [d, file])
77
77
  end
@@ -80,7 +80,7 @@ class TestUpdate < Minitest::Test
80
80
 
81
81
  def test_update_with_error_and_summary
82
82
  Dir.mktmpdir do |d|
83
- File.write(File.join(d, 'foo.rb'), 'this$is$a$broken$Ruby$script')
83
+ save_it(File.join(d, 'foo/foo.rb'), 'this$is$a$broken$Ruby$script')
84
84
  file = File.join(d, 'base.fb')
85
85
  2.times do
86
86
  Judges::Update.new(Loog::NULL).run(
data/test/test__helper.rb CHANGED
@@ -32,3 +32,11 @@ require 'minitest/autorun'
32
32
 
33
33
  require 'minitest/reporters'
34
34
  Minitest::Reporters.use! [Minitest::Reporters::SpecReporter.new]
35
+
36
+ class Minitest::Test
37
+ def save_it(file, content)
38
+ require 'fileutils'
39
+ FileUtils.mkdir_p(File.dirname(file))
40
+ File.binwrite(file, content)
41
+ end
42
+ end
data/test/test_baza.rb CHANGED
@@ -22,8 +22,10 @@
22
22
 
23
23
  require 'minitest/autorun'
24
24
  require 'webmock/minitest'
25
+ require 'webrick'
25
26
  require 'loog'
26
27
  require 'socket'
28
+ require 'stringio'
27
29
  require 'random-port'
28
30
  require_relative '../lib/judges'
29
31
  require_relative '../lib/judges/baza'
@@ -76,53 +78,75 @@ class TestBaza < Minitest::Test
76
78
  end
77
79
 
78
80
  def test_real_http
79
- req = with_http_server(200, 'yes') do |baza|
80
- baza.name_exists?('simple')
81
- end
82
- assert(req.include?("User-Agent: judges #{Judges::VERSION}\r\n"))
81
+ req =
82
+ with_http_server(200, 'yes') do |baza|
83
+ baza.name_exists?('simple')
84
+ end
85
+ assert_equal("judges #{Judges::VERSION}", req['user-agent'])
83
86
  end
84
87
 
85
88
  def test_push_with_meta
86
- req = with_http_server(200, 'yes') do |baza|
87
- baza.push('simple', 'hello, world!', ['boom!', 'хŠµŠ¹!'])
88
- end
89
- assert(req.include?("X-Zerocracy-Meta: Ym9vbSE= 0YXQtdC5IQ==\r\n"))
89
+ req =
90
+ with_http_server(200, 'yes') do |baza|
91
+ baza.push('simple', 'hello, world!', ['boom!', 'хŠµŠ¹!'])
92
+ end
93
+ assert_equal('Ym9vbSE= 0YXQtdC5IQ==', req['x-zerocracy-meta'])
90
94
  end
91
95
 
92
96
  def test_push_with_big_meta
93
- req = with_http_server(200, 'yes') do |baza|
94
- baza.push(
95
- 'simple',
96
- 'hello, world!',
97
- [
98
- 'pages_url:https://zerocracy.github.io/zerocracy.html',
99
- 'others:https://zerocracy.github.io/zerocracy.html',
100
- 'duration:59595'
101
- ]
102
- )
103
- end
104
- assert(req.join.include?('X-Zerocracy-Meta: '))
97
+ req =
98
+ with_http_server(200, 'yes') do |baza|
99
+ baza.push(
100
+ 'simple',
101
+ 'hello, world!',
102
+ [
103
+ 'pages_url:https://zerocracy.github.io/zerocracy.html',
104
+ 'others:https://zerocracy.github.io/zerocracy.html',
105
+ 'duration:59595'
106
+ ]
107
+ )
108
+ end
109
+ assert(req['x-zerocracy-meta'])
110
+ end
111
+
112
+ def test_push_compressed_content
113
+ req =
114
+ with_http_server(200, 'yes') do |baza|
115
+ baza.push('simple', 'hello, world!', %w[meta1 meta2 meta3])
116
+ end
117
+ assert_equal('application/zip', req.content_type)
118
+ assert_equal('gzip', req['content-encoding'])
119
+ body = Zlib::GzipReader.zcat(StringIO.new(req.body))
120
+ assert_equal('hello, world!', body)
121
+ end
122
+
123
+ def test_push_compression_disabled
124
+ req =
125
+ with_http_server(200, 'yes', compression: false) do |baza|
126
+ baza.push('simple', 'hello, world!', %w[meta1 meta2 meta3])
127
+ end
128
+ assert_equal('application/octet-stream', req.content_type)
129
+ assert_equal('hello, world!', req.body)
105
130
  end
106
131
 
107
132
  private
108
133
 
109
- def with_http_server(code, response)
134
+ def with_http_server(code, response, opts = {})
135
+ opts = { ssl: false, timeout: 1 }.merge(opts)
110
136
  WebMock.enable_net_connect!
111
- req = []
137
+ req = WEBrick::HTTPRequest.new(WEBrick::Config::HTTP)
112
138
  host = '127.0.0.1'
113
139
  RandomPort::Pool::SINGLETON.acquire do |port|
114
140
  server = TCPServer.new(host, port)
115
- t = Thread.new do
116
- socket = server.accept
117
- loop do
118
- line = socket.gets
119
- break if line == "\r\n"
120
- req << line
141
+ t =
142
+ Thread.new do
143
+ socket = server.accept
144
+ req.parse(socket)
145
+ req.body
146
+ socket.puts "HTTP/1.1 #{code} OK\r\nContent-Length: #{response.length}\r\n\r\n#{response}"
147
+ socket.close
121
148
  end
122
- socket.puts "HTTP/1.1 #{code} OK\r\nContent-Length: #{response.length}\r\n\r\n#{response}"
123
- socket.close
124
- end
125
- yield Judges::Baza.new(host, port, '0000', ssl: false, timeout: 1)
149
+ yield Judges::Baza.new(host, port, '0000', **opts)
126
150
  t.join
127
151
  end
128
152
  req
data/test/test_judge.rb CHANGED
@@ -34,7 +34,7 @@ require_relative '../lib/judges/judge'
34
34
  class TestJudge < Minitest::Test
35
35
  def test_basic_run
36
36
  Dir.mktmpdir do |d|
37
- File.write(File.join(d, 'foo.rb'), '$fb.insert')
37
+ save_it(File.join(d, "#{File.basename(d)}.rb"), '$fb.insert')
38
38
  judge = Judges::Judge.new(d, nil, Loog::NULL)
39
39
  fb = Factbase.new
40
40
  judge.run(fb, {}, {}, {})
@@ -44,7 +44,7 @@ class TestJudge < Minitest::Test
44
44
 
45
45
  def test_run_isolated
46
46
  Dir.mktmpdir do |d|
47
- File.write(File.join(d, 'bar.rb'), '$fb.insert')
47
+ save_it(File.join(d, "#{File.basename(d)}.rb"), '$fb.insert')
48
48
  judge = Judges::Judge.new(d, nil, Loog::NULL)
49
49
  fb1 = Factbase.new
50
50
  judge.run(fb1, {}, {}, {})
@@ -57,8 +57,8 @@ class TestJudge < Minitest::Test
57
57
 
58
58
  def test_passes_local_vars_between_tests
59
59
  Dir.mktmpdir do |d|
60
- File.write(
61
- File.join(d, 'x.rb'),
60
+ save_it(
61
+ File.join(d, "#{File.basename(d)}.rb"),
62
62
  '
63
63
  $local[:foo] = 42 if $local[:foo].nil?
64
64
  $local[:foo] = $local[:foo] + 1
@@ -77,8 +77,7 @@ class TestJudge < Minitest::Test
77
77
  Dir.mktmpdir do |d|
78
78
  j = 'this_is_it'
79
79
  dir = File.join(d, j)
80
- FileUtils.mkdir(dir)
81
- File.write(File.join(dir, 'foo.rb'), '$loog.info("judge=" + $judge)')
80
+ save_it(File.join(dir, "#{j}.rb"), '$loog.info("judge=" + $judge)')
82
81
  log = Loog::Buffer.new
83
82
  Judges::Judge.new(dir, nil, log).run(Factbase.new, {}, {}, {})
84
83
  assert(log.to_s.include?("judge=#{j}"))
@@ -89,8 +88,7 @@ class TestJudge < Minitest::Test
89
88
  assert_raises do
90
89
  Dir.mktmpdir do |d|
91
90
  dir = File.join(d, 'judges')
92
- FileUtils.mkdir_p(dir)
93
- File.write(File.join(dir, 'x.rb'), 'this$is$broken$syntax')
91
+ save_it(File.join(dir, "#{File.basename(d)}.rb"), 'this$is$broken$syntax')
94
92
  judge = Judges::Judge.new(dir, lib, Loog::NULL)
95
93
  judge.run(Factbase.new, {}, {}, {})
96
94
  end
@@ -101,8 +99,7 @@ class TestJudge < Minitest::Test
101
99
  assert_raises do
102
100
  Dir.mktmpdir do |d|
103
101
  dir = File.join(d, 'judges')
104
- FileUtils.mkdir_p(dir)
105
- File.write(File.join(dir, 'x.rb'), 'a < 1')
102
+ save_it(File.join(dir, "#{File.basename(d)}.rb"), 'a < 1')
106
103
  judge = Judges::Judge.new(dir, lib, Loog::NULL)
107
104
  judge.run(Factbase.new, {}, {}, {})
108
105
  end
data/test/test_judges.rb CHANGED
@@ -33,8 +33,9 @@ require_relative '../lib/judges/judges'
33
33
  class TestJudges < Minitest::Test
34
34
  def test_basic
35
35
  Dir.mktmpdir do |d|
36
- File.write(File.join(d, 'foo.rb'), 'hey')
37
- File.write(File.join(d, 'something.yml'), "---\nfoo: 42")
36
+ dir = File.join(d, 'foo')
37
+ save_it(File.join(dir, 'foo.rb'), 'hey')
38
+ save_it(File.join(dir, 'something.yml'), "---\nfoo: 42")
38
39
  found = 0
39
40
  Judges::Judges.new(d, nil, Loog::NULL).each do |p|
40
41
  assert_equal('foo.rb', p.script)
@@ -47,11 +48,32 @@ class TestJudges < Minitest::Test
47
48
 
48
49
  def test_get_one
49
50
  Dir.mktmpdir do |d|
50
- f = File.join(d, 'boo/foo.rb')
51
- FileUtils.mkdir_p(File.dirname(f))
52
- File.write(f, 'hey')
51
+ save_it(File.join(d, 'boo/boo.rb'), 'hey')
53
52
  j = Judges::Judges.new(d, nil, Loog::NULL).get('boo')
54
- assert_equal('foo.rb', j.script)
53
+ assert_equal('boo.rb', j.script)
54
+ end
55
+ end
56
+
57
+ def test_list_only_direct_subdirs
58
+ Dir.mktmpdir do |d|
59
+ save_it(File.join(d, 'first/first.rb'), '')
60
+ save_it(File.join(d, 'second/second.rb'), '')
61
+ save_it(File.join(d, 'second/just-file.rb'), '')
62
+ save_it(File.join(d, 'wrong.rb'), '')
63
+ save_it(File.join(d, 'another/wrong/wrong.rb'), '')
64
+ save_it(File.join(d, 'bad/hello.rb'), '')
65
+ list = Judges::Judges.new(d, nil, Loog::NULL).each.to_a
66
+ assert_equal(2, list.size)
67
+ end
68
+ end
69
+
70
+ def test_list_with_empty_dir
71
+ Dir.mktmpdir do |d|
72
+ save_it(File.join(d, 'wrong.rb'), '')
73
+ save_it(File.join(d, 'another/wrong/wrong.rb'), '')
74
+ save_it(File.join(d, 'bad/hello.rb'), '')
75
+ list = Judges::Judges.new(d, nil, Loog::NULL).each.to_a
76
+ assert(list.empty?)
55
77
  end
56
78
  end
57
79
  end
data/test/test_options.rb CHANGED
@@ -81,7 +81,7 @@ class TestOptions < Minitest::Test
81
81
  opts = Judges::Options.new('foo' => 44, 'bar' => 'long-string-maybe-secret')
82
82
  s = opts.to_s
83
83
  assert(s.include?('FOO ā†’ "44"'), s)
84
- assert(s.include?('"long********************"'))
84
+ assert(s.include?('"long****************cret"'), s)
85
85
  end
86
86
 
87
87
  def test_merge
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.20.0
4
+ version: 0.22.0
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-07-22 00:00:00.000000000 Z
11
+ date: 2024-08-05 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: backtrace