1# frozen_string_literal: true
2
3require "rake/testtask"
4require "rubocop/rake_task"
5require "json"
6require "tempfile"
7
8
9Rake::TestTask.new(:unit) do |t|
10 ENV["ENV"] = "test"
11 ENV["COVERAGE_NAME"] = "unit"
12
13 t.libs << "test"
14 t.libs << "lib"
15 t.test_files = FileList["test/**/test_*.rb"].exclude("test/property/**")
16 t.warning = false
17end
18
19Rake::TestTask.new(:_run_property) do |t|
20 t.libs << "test"
21 t.libs << "test/property"
22 t.libs << "lib"
23 t.test_files = FileList["test/property/**/test_*.rb"] +
24 FileList["test/stubs/seed_*.rb"]
25 t.ruby_opts << "-r failure_reporter"
26 t.warning = false
27end
28Rake::Task[:_run_property].clear_comments
29
30desc "Run property tests (optional seed: rake property[SEED,no-stubs])"
31task :property, [:seed, :no_stubs] do |_t, args|
32 ENV["SEED"] = (args[:seed] || rand(0xFFFF)).to_i.to_s
33 ENV["COVERAGE_NAME"] = "property"
34 srand(ENV["SEED"].to_i)
35
36 warn "Property seed: #{ENV['SEED']}"
37
38 stub_path = "test/stubs/seed_#{ENV['SEED']}.rb"
39 if args[:seed] && File.exist?(stub_path)
40 ENV["TESTOPTS"] = "--seed=#{ENV['SEED']}"
41 Rake::TestTask.new(:_run_stub) do |t|
42 t.libs << "test"
43 t.libs << "test/property"
44 t.libs << "lib"
45 t.test_files = [stub_path]
46 t.warning = false
47 end
48 Rake::Task[:_run_stub].clear_comments
49 Rake::Task[:_run_stub].invoke
50 next
51 end
52
53 report = Tempfile.new(["failures", ".json"])
54 begin
55 ENV["FAILURE_REPORT_PATH"] = report.path
56 ENV["TESTOPTS"] = "--seed=#{ENV['SEED']}"
57
58 Rake::Task[:_run_property].invoke
59 rescue RuntimeError
60 unless args[:no_stubs]
61 failing = JSON.parse(File.read(report.path))
62
63 mkdir_p "test/stubs"
64 comment = failing.map { |n| "# - #{n}" }.join("\n")
65 File.write(stub_path, <<~RUBY)
66 # frozen_string_literal: true
67
68 # Failing tests:
69 #{comment}
70
71 srand(#{ENV['SEED']})
72 require_relative "../property/test_webhook_handler"
73 RUBY
74 warn "\nStub written: #{stub_path}"
75 warn "Reproduce: bundle exec ruby -Itest -Itest/property -Ilib #{stub_path}"
76 end
77 exit 1
78 ensure
79 report&.close
80 report&.unlink
81 end
82end
83
84task :test => [:unit, :property]
85
86RuboCop::RakeTask.new(:lint)
87
88task :entr do
89 sh "sh", "-c", "git ls-files | entr -s 'rake test && rubocop'"
90end
91
92task default: :test