Skip to content

Commit

Permalink
Merge pull request #51 from QWYNG/refactor_use_task_sources_interface…
Browse files Browse the repository at this point in the history
…_for_spec

Refactor Contest and Task Creation for Improved Testability
  • Loading branch information
QWYNG committed May 5, 2024
2 parents d923992 + a156ba4 commit 8781a5e
Show file tree
Hide file tree
Showing 12 changed files with 1,461 additions and 68 deletions.
6 changes: 6 additions & 0 deletions lib/green_day/atcoder_client.rb
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,12 @@ def initialize

def get_parsed_body(path)
res = conn.get(path)
if res.status == 429
puts "429 error with #{path} retrying..."
sleep 1
return get_parsed_body(path)
end

Nokogiri::HTML.parse(res.body)
end

Expand Down
29 changes: 2 additions & 27 deletions lib/green_day/cli.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
require 'io/console'
require_relative 'atcoder_client'
require_relative 'contest'
require_relative 'test_builder'
require_relative 'task_source_to_file_worker'

module GreenDay
class Cli < Thor
Expand All @@ -28,33 +28,8 @@ def new(contest_name)
contest = Contest.new(contest_name)
FileUtils.makedirs("#{contest.name}/spec")

contest.tasks.map do |task|
create_files_in_thread(task)
end.each(&:join)

TaskSourceToFileWorker.run_threads(contest.task_sources).each(&:join)
puts "Successfully created #{contest.name} directory".colorize(:green)
end

private

def create_files_in_thread(task)
Thread.new do
create_task_file(task)
create_task_spec_file(task)
end
end

def create_task_file(task)
FileUtils.touch(task_file_name(task))
end

def create_task_spec_file(task)
test_content = TestBuilder.build_test(task_file_name(task), task.sample_answers)
File.write("#{task.contest.name}/spec/#{task.name}_spec.rb", test_content)
end

def task_file_name(task)
"#{task.contest.name}/#{task.name}.rb"
end
end
end
16 changes: 5 additions & 11 deletions lib/green_day/contest.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,15 @@

module GreenDay
class Contest
attr_reader :name, :tasks
TaskSource = Struct.new(:name, :path, :contest_name)
attr_reader :name, :task_sources

def initialize(contest_name)
@name = contest_name

@tasks = fetch_task_names_and_paths.map.with_index do |(task_name, task_path), i|
if !i.zero? && (i % 10).zero? && !ENV['CI']
puts 'Sleeping 2 second to avoid 429 error'
sleep 2
end

Thread.new do
Task.new(self, task_name, task_path)
end
end.map(&:value)
@task_sources = fetch_task_names_and_paths.map do |name, path|
TaskSource.new(name, path, @name)
end
end

private
Expand Down
30 changes: 24 additions & 6 deletions lib/green_day/task.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,35 @@

module GreenDay
class Task
attr_reader :contest, :name, :path, :sample_answers
SampleAnswer = Struct.new(:input, :output)
attr_reader :name, :path, :contest_name

def initialize(contest, name, path)
@contest = contest
def initialize(name, path, contest_name)
@name = name
@path = path
@sample_answers = create_sample_answers_hash
@contest_name = contest_name
end

def create_file
FileUtils.touch(file_name)
end

def create_spec_file
test_content = TestBuilder.build_test(
file_name,
sample_answers
)
File.write("#{contest_name}/spec/#{name}_spec.rb", test_content)
end

private

def create_sample_answers_hash
def sample_answers
input_samples, output_samples = fetch_inputs_and_outputs

input_samples.zip(output_samples).to_h
input_samples.zip(output_samples).map do |input, output|
SampleAnswer.new(input, output)
end
end

def fetch_inputs_and_outputs
Expand All @@ -27,5 +41,9 @@ def fetch_inputs_and_outputs

[inputs, outputs]
end

def file_name
"#{contest_name}/#{name}.rb"
end
end
end
30 changes: 30 additions & 0 deletions lib/green_day/task_source_to_file_worker.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# frozen_string_literal: true

require_relative 'test_builder'

module GreenDay
class TaskSourceToFileWorker
def self.run_threads(task_sources)
new(task_sources).run_threads
end

def initialize(task_sources)
@task_sources = task_sources
end

def run_threads
@task_sources.map.with_index do |task_source, i|
# avoid 429 error
sleep 1 if (i % 7).zero? && !i.zero?

Thread.new do
task = Task.new(task_source.name,
task_source.path,
task_source.contest_name)
task.create_file
task.create_spec_file
end
end
end
end
end
4 changes: 2 additions & 2 deletions lib/green_day/test_builder.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@ module GreenDay
module TestBuilder
module_function

def build_test(submit_file_path, input_output_hash)
def build_test(submit_file_path, sample_answers)
<<~SPEC
RSpec.describe '#{submit_file_path}' do
#{input_output_hash.map { |input, output| build_example(submit_file_path, input, output) }.join("\n")}
#{sample_answers.map { |sample_answer| build_example(submit_file_path, sample_answer.input, sample_answer.output) }.join("\n")}
end
SPEC
end
Expand Down
Loading

0 comments on commit 8781a5e

Please sign in to comment.