git-contest 0.0.1

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.
Files changed (61) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +17 -0
  3. data/.rspec +2 -0
  4. data/.travis.yml +15 -0
  5. data/Gemfile +5 -0
  6. data/LICENSE.txt +24 -0
  7. data/README.md +217 -0
  8. data/Rakefile +4 -0
  9. data/bin/git-contest +43 -0
  10. data/bin/git-contest-finish +163 -0
  11. data/bin/git-contest-init +77 -0
  12. data/bin/git-contest-rebase +76 -0
  13. data/bin/git-contest-start +68 -0
  14. data/bin/git-contest-submit +188 -0
  15. data/git-contest.gemspec +34 -0
  16. data/lib/contest/driver.rb +15 -0
  17. data/lib/contest/driver/aizu_online_judge.rb +159 -0
  18. data/lib/contest/driver/base.rb +103 -0
  19. data/lib/contest/driver/codeforces.rb +196 -0
  20. data/lib/contest/driver/common.rb +72 -0
  21. data/lib/contest/driver/driver_event.rb +30 -0
  22. data/lib/contest/driver/uva_online_judge.rb +131 -0
  23. data/lib/git/contest.rb +14 -0
  24. data/lib/git/contest/common.rb +48 -0
  25. data/lib/git/contest/git.rb +189 -0
  26. data/lib/git/contest/test.rb +10 -0
  27. data/lib/git/contest/version.rb +12 -0
  28. data/spec/bin/t004_git_contest_submit_spec.rb +143 -0
  29. data/spec/bin/t005_git_contest_branching_spec.rb +83 -0
  30. data/spec/bin/t007_git_contest_start_spec.rb +121 -0
  31. data/spec/bin/t008_git_contest_finish_spec.rb +229 -0
  32. data/spec/bin/t009_git_contest_init_spec.rb +82 -0
  33. data/spec/lib/contest/driver/t001_aizu_online_judge_spec.rb +177 -0
  34. data/spec/lib/contest/driver/t002_codeforces_spec.rb +34 -0
  35. data/spec/lib/contest/driver/t003_uva_online_judge_spec.rb +33 -0
  36. data/spec/mock/default_config/config.yml +0 -0
  37. data/spec/mock/default_config/plugins/driver_dummy.rb +113 -0
  38. data/spec/mock/t001/002.status_log.xml +55 -0
  39. data/spec/mock/t001/config.yml +5 -0
  40. data/spec/mock/t001/description.html +48 -0
  41. data/spec/mock/t001/status.html +49 -0
  42. data/spec/mock/t001/status_log.xml +29 -0
  43. data/spec/mock/t002/my_submissions.html +58 -0
  44. data/spec/mock/t003/after_submit.html +28 -0
  45. data/spec/mock/t003/my_submissions.compile_error.html +160 -0
  46. data/spec/mock/t003/my_submissions.sent_to_judge.html +358 -0
  47. data/spec/mock/t004/config.yml +17 -0
  48. data/spec/mock/t005/001/config.yml +5 -0
  49. data/spec/mock/t006/001/001/001/config.yml +8 -0
  50. data/spec/mock/t006/001/001/002/config.yml +8 -0
  51. data/spec/mock/t006/001/001/003/config.yml +8 -0
  52. data/spec/mock/t006/001/002/001/config.yml +8 -0
  53. data/spec/mock/t006/001/002/002/config.yml +8 -0
  54. data/spec/mock/t006/001/002/003/config.yml +8 -0
  55. data/spec/mock/t006/001/003/001/config.yml +9 -0
  56. data/spec/mock/t006/001/003/002/config.yml +9 -0
  57. data/spec/mock/t006/001/003/003/config.yml +9 -0
  58. data/spec/spec_helper.rb +45 -0
  59. data/spec/spec_list.txt +1 -0
  60. data/spec/t006_config_spec.rb +168 -0
  61. metadata +269 -0
@@ -0,0 +1,82 @@
1
+ require "spec_helper"
2
+
3
+ # Don't forget --defaults option
4
+
5
+ describe "T009: git-contest-init" do
6
+
7
+ before do
8
+ init_env
9
+ @test_dir = "#{ENV['GIT_CONTEST_TEMP_DIR']}/t009"
10
+ Dir.mkdir @test_dir
11
+ Dir.chdir @test_dir
12
+ # debug_on
13
+ end
14
+
15
+ after do
16
+ Dir.chdir '..'
17
+ Dir.rmdir @test_dir
18
+ end
19
+
20
+ describe "001: --force" do
21
+ before do
22
+ Dir.mkdir "001"
23
+ Dir.chdir "001"
24
+ end
25
+
26
+ after do
27
+ FileUtils.remove_dir ".git", :force => true
28
+ Dir.chdir ".."
29
+ Dir.rmdir "001"
30
+ end
31
+
32
+ it "001: init -> init" do
33
+ ret1 = bin_exec "init --defaults"
34
+ ret_config1 = git_do("config --get git.contest.branch.master")
35
+ ret2 = bin_exec "init --defaults"
36
+
37
+ ret_config1.should === "master"
38
+ ret1.include?("Error: unknown argument").should === false
39
+ ret2.include?("Error: unknown argument").should === false
40
+ ret1.include?("Already initialized for git-contest.").should === false
41
+ ret1.include?("use: git contest init -f").should === false
42
+ ret2.include?("Already initialized for git-contest.").should === true
43
+ ret2.include?("use: git contest init -f").should === true
44
+ end
45
+
46
+ it "002: init -> init -f -> init --force" do
47
+ ret1 = bin_exec "init --defaults"
48
+ ret_config1 = git_do("config --get git.contest.branch.master")
49
+ ret2 = bin_exec "init --defaults -f"
50
+ ret3 = bin_exec "init --defaults --force"
51
+ ret_config1.should === "master"
52
+ ret1.include?("Error: unknown argument").should === false
53
+ ret2.include?("Error: unknown argument").should === false
54
+ ret3.include?("Error: unknown argument").should === false
55
+ ret1.include?("Already initialized for git-contest.").should === false
56
+ ret1.include?("use: git contest init -f").should === false
57
+ ret2.include?("Already initialized for git-contest.").should === false
58
+ ret2.include?("use: git contest init -f").should === false
59
+ ret3.include?("Already initialized for git-contest.").should === false
60
+ ret3.include?("use: git contest init -f").should === false
61
+ end
62
+
63
+ it "003: init -f -> init -f -> init --force" do
64
+ ret1 = bin_exec "init --defaults -f"
65
+ ret_config1 = git_do("config --get git.contest.branch.master")
66
+ ret2 = bin_exec "init --defaults -f"
67
+ ret3 = bin_exec "init --defaults --force"
68
+ ret_config1.should === "master"
69
+ ret1.include?("Error: unknown argument").should === false
70
+ ret2.include?("Error: unknown argument").should === false
71
+ ret3.include?("Error: unknown argument").should === false
72
+ ret1.include?("Already initialized for git-contest.").should === false
73
+ ret1.include?("use: git contest init -f").should === false
74
+ ret2.include?("Already initialized for git-contest.").should === false
75
+ ret2.include?("use: git contest init -f").should === false
76
+ ret3.include?("Already initialized for git-contest.").should === false
77
+ ret3.include?("use: git contest init -f").should === false
78
+ end
79
+ end
80
+
81
+ end
82
+
@@ -0,0 +1,177 @@
1
+ require 'spec_helper'
2
+
3
+ require 'mechanize'
4
+ require 'contest/driver/aizu_online_judge'
5
+
6
+ describe "T001: Contest::Driver::AizuOnlineJudge" do
7
+ before do
8
+ # setup driver
9
+ @driver = Contest::Driver::AizuOnlineJudge.new
10
+ @driver.stub(:sleep).and_return(0)
11
+ @driver.client = Mechanize.new {|agent|
12
+ agent.user_agent_alias = 'Windows IE 7'
13
+ }
14
+ ENV['GIT_CONTEST_CONFIG'] = get_path('/mock/t001/config.yml')
15
+ init
16
+
17
+ # basic status_log
18
+ WebMock
19
+ .stub_request(
20
+ :get,
21
+ /http:\/\/judge\.u-aizu\.ac\.jp\/onlinejudge\/webservice\/status_log/,
22
+ )
23
+ .to_return(
24
+ :status => 200,
25
+ :body => read_file('/mock/t001/status_log.xml'),
26
+ :headers => {
27
+ 'Content-Type' => 'text/xml',
28
+ },
29
+ )
30
+
31
+ # status.jsp: http://judge.u-aizu.ac.jp/onlinejudge/status.jsp
32
+ WebMock
33
+ .stub_request(
34
+ :get,
35
+ /http:\/\/judge\.u-aizu\.ac\.jp\/onlinejudge\/status/,
36
+ )
37
+ .to_return(
38
+ :status => 200,
39
+ :body => read_file('/mock/t001/status.html'),
40
+ :headers => {
41
+ 'Content-Type' => 'text/html',
42
+ },
43
+ )
44
+
45
+ # description
46
+ WebMock
47
+ .stub_request(
48
+ :get,
49
+ /http:\/\/judge\.u-aizu\.ac\.jp\/onlinejudge\/description\.jsp\?id=/,
50
+ )
51
+ .to_return(
52
+ :status => 200,
53
+ :body => read_file('/mock/t001/description.html'),
54
+ :headers => {
55
+ 'Content-Type' => 'text/html',
56
+ },
57
+ )
58
+
59
+ # servlet/Submit
60
+ WebMock
61
+ .stub_request(
62
+ :post,
63
+ /http:\/\/judge\.u-aizu\.ac\.jp\/onlinejudge\/servlet\/Submit/,
64
+ )
65
+ .to_return(
66
+ :status => 200,
67
+ :body => '',
68
+ :headers => {
69
+ 'Content-Type' => 'text/html',
70
+ },
71
+ )
72
+ end
73
+
74
+ describe "001: #get_status_wait" do
75
+ it "001: Check Status" do
76
+ ret = @driver.get_status_wait 'test_user', '111'
77
+ ret.should === "Wrong Answer"
78
+ end
79
+ it "002: Check Timeout" do
80
+ @flag = false
81
+ proc = Proc.new do
82
+ @flag = true
83
+ end
84
+ @driver.on 'timeout', proc
85
+ @driver.get_status_wait 'test_user', '999'
86
+ @driver.off 'timeout', proc
87
+ @flag.should === true
88
+ end
89
+ it "002: Check Timeout noset" do
90
+ @flag = false
91
+ proc = Proc.new do
92
+ @flag = true
93
+ end
94
+ @driver.on 'timeout', proc
95
+ @driver.off 'timeout', proc
96
+ @driver.get_status_wait 'test_user', '999'
97
+ @flag.should === false
98
+ end
99
+ end
100
+
101
+ describe "002: #get_status_wait" do
102
+ before do
103
+ # has 2 statuses
104
+ WebMock.stub_request(
105
+ :get,
106
+ /http:\/\/judge\.u-aizu\.ac\.jp\/onlinejudge\/webservice\/status_log\??.*/
107
+ ).to_return(
108
+ :status => 200,
109
+ :body => read_file('/mock/t001/002.status_log.xml'),
110
+ :headers => {
111
+ 'Content-Type' => 'text/xml',
112
+ },
113
+ )
114
+ end
115
+ it "001: Check Status" do
116
+ ret = @driver.get_status_wait 'test_user', '111'
117
+ ret.should === "Wrong Answer"
118
+ ret = @driver.get_status_wait 'test_user', '112'
119
+ ret.should === "Accepted"
120
+ end
121
+ end
122
+
123
+ describe "003: #submit" do
124
+ it "001: Check Event" do
125
+ FileUtils.touch '/tmp/main.rb'
126
+
127
+ @flag_start = false
128
+ @flag_before_submit = false
129
+ @flag_after_submit = false
130
+ @flag_before_wait = false
131
+ @flag_after_wait = false
132
+ @flag_finish = false
133
+
134
+ proc_start = Proc.new do
135
+ @flag_start = true
136
+ end
137
+ proc_before_submit = Proc.new do |info|
138
+ @flag_before_submit = true
139
+ end
140
+ proc_after_submit = Proc.new do
141
+ @flag_after_submit = true
142
+ end
143
+ proc_before_wait = Proc.new do
144
+ @flag_before_wait = true
145
+ end
146
+ proc_after_wait = Proc.new do
147
+ @flag_after_wait = true
148
+ end
149
+ proc_finish = Proc.new do
150
+ @flag_finish = true
151
+ end
152
+
153
+ @driver.on 'start', proc_start
154
+ @driver.on 'before_submit', proc_before_submit
155
+ @driver.on 'after_submit', proc_after_submit
156
+ @driver.on 'before_wait', proc_before_wait
157
+ @driver.on 'after_wait', proc_after_wait
158
+ @driver.on 'finish', proc_finish
159
+
160
+ @driver.submit(
161
+ {
162
+ "user" => "test_user",
163
+ "password" => "password",
164
+ },
165
+ '/tmp/main.rb',
166
+ {
167
+ :contest_id => '11111',
168
+ :problem_id => '22222',
169
+ },
170
+ )
171
+
172
+ @flag = @flag_start && @flag_before_submit && @flag_after_submit && @flag_before_wait && @flag_after_wait && @flag_finish
173
+ @flag.should === true
174
+ end
175
+ end
176
+ end
177
+
@@ -0,0 +1,34 @@
1
+ require 'spec_helper'
2
+
3
+ require 'contest/driver/codeforces'
4
+ require 'mechanize'
5
+
6
+ describe "T002: Contest::Driver::Codeforces" do
7
+ before do
8
+ @driver = Contest::Driver::Codeforces.new
9
+ @driver.stub(:sleep).and_return(0)
10
+ @driver.client = Mechanize.new {|agent|
11
+ agent.user_agent_alias = 'Windows IE 7'
12
+ }
13
+
14
+ # basic status_log
15
+ WebMock.stub_request(
16
+ :get,
17
+ /http:\/\/codeforces.com\/contest\/[0-9A-Z]*\/my/
18
+ ).to_return(
19
+ :status => 200,
20
+ :body => read_file('/mock/t002/my_submissions.html'),
21
+ :header => {
22
+ 'Content-Type' => 'text/html',
23
+ },
24
+ )
25
+ end
26
+
27
+ describe '001: #get_status_wait' do
28
+ it '001: Check Status' do
29
+ ret = @driver.get_status_wait 11111, 22222
30
+ ret.should === "Accepted"
31
+ end
32
+ end
33
+ end
34
+
@@ -0,0 +1,33 @@
1
+ require 'spec_helper'
2
+
3
+ require 'contest/driver/codeforces'
4
+ require 'mechanize'
5
+
6
+ describe "T003: Contest::Driver::UvaOnlineJudge" do
7
+ before do
8
+ @driver = Contest::Driver::UvaOnlineJudge.new
9
+ @driver.stub(:sleep).and_return(0)
10
+ @driver.client = Mechanize.new {|agent|
11
+ agent.user_agent_alias = 'Windows IE 7'
12
+ }
13
+ end
14
+
15
+ describe '001: #get_submission_id' do
16
+ it '001' do
17
+ ret = @driver.get_submission_id(read_file('/mock/t003/after_submit.html'))
18
+ ret.should eq '99999'
19
+ end
20
+ end
21
+
22
+ describe '002: #get_submission_status' do
23
+ it '001: Sent to Judge' do
24
+ ret = @driver.get_submission_status('99999', read_file('/mock/t003/my_submissions.sent_to_judge.html'))
25
+ ret.should eq 'Sent to judge'
26
+ end
27
+ it '002: Compile Error' do
28
+ ret = @driver.get_submission_status('99999', read_file('/mock/t003/my_submissions.compile_error.html'))
29
+ ret.should eq 'Compilation error'
30
+ end
31
+ end
32
+ end
33
+
File without changes
@@ -0,0 +1,113 @@
1
+ require 'contest/driver/common'
2
+ require 'rexml/document'
3
+
4
+ module Contest
5
+ module Driver
6
+ class Dummy < DriverBase
7
+ def get_opts_ext
8
+ define_options do
9
+ opt(
10
+ :problem_id,
11
+ "Problem ID (Ex: 1000, 123, 0123, etc...)",
12
+ :type => :string,
13
+ :required => true,
14
+ )
15
+ opt(
16
+ :contest_id,
17
+ "Contest ID (Ex: 1000, 123, 0123, etc...)",
18
+ :type => :string,
19
+ :required => true,
20
+ )
21
+ end
22
+ end
23
+
24
+ def get_site_name
25
+ "Dummy"
26
+ end
27
+
28
+ def get_problem_id(options)
29
+ "#{options[:contest_id]}#{options[:problem_id]}"
30
+ end
31
+
32
+ def get_desc
33
+ "This is Dummy"
34
+ end
35
+
36
+ def resolve_language(label)
37
+ case label
38
+ when "clang"
39
+ return "C"
40
+ when "cpp"
41
+ return "C++"
42
+ when "java"
43
+ return "JAVA"
44
+ when "cpp11"
45
+ return "C++11"
46
+ when "cs"
47
+ return "C#"
48
+ when "dlang"
49
+ return "D"
50
+ when "golang"
51
+ return "Go"
52
+ when "ruby"
53
+ return "Ruby"
54
+ when "python2"
55
+ return "Python2"
56
+ when "python3"
57
+ return "Python"
58
+ when "php"
59
+ return "PHP"
60
+ when "javascript"
61
+ return "JavaScript"
62
+ else
63
+ abort "unknown languag"
64
+ end
65
+ end
66
+
67
+ def submit_ext(config, source_path, options)
68
+ # start
69
+ trigger 'start'
70
+
71
+ # submit
72
+ trigger(
73
+ 'before_submit',
74
+ {
75
+ :source => source_path
76
+ },
77
+ )
78
+ trigger 'after_submit'
79
+
80
+ # need to get the newest waiting submissionId
81
+ trigger 'before_wait'
82
+
83
+ # wait result
84
+ status = ''
85
+ File.open source_path, 'r' do |file|
86
+ line = file.read
87
+ if line == 'wa-code'
88
+ status = 'Wrong Answer'
89
+ elsif line == 'ac-code'
90
+ status = 'Accepted'
91
+ elsif line == 'tle-code'
92
+ status = 'Time Limit Exceeded'
93
+ end
94
+ end
95
+ trigger(
96
+ 'after_wait',
97
+ {
98
+ :submission_id => '99999',
99
+ :status => status,
100
+ :result => get_commit_message($config["submit_rules"]["message"], status, options),
101
+ }
102
+ )
103
+ trigger 'finish'
104
+
105
+ status
106
+ end
107
+
108
+ if ENV['TEST_MODE'] === 'TRUE'
109
+ attr_writer :client
110
+ end
111
+ end
112
+ end
113
+ end
@@ -0,0 +1,55 @@
1
+ <?xml version="1.0"?>
2
+ <status_list>
3
+ <status>
4
+ <run_id>
5
+ 112
6
+ </run_id>
7
+ <user_id>
8
+ test_user
9
+ </user_id>
10
+ <problem_id>
11
+ 222
12
+ </problem_id>
13
+ <status>
14
+ Accepted
15
+ </status>
16
+ <language>
17
+ Ruby
18
+ </language>
19
+ <cputime>
20
+ 333
21
+ </cputime>
22
+ <memory>
23
+ 444
24
+ </memory>
25
+ <code_size>
26
+ 555
27
+ </code_size>
28
+ </status>
29
+ <status>
30
+ <run_id>
31
+ 111
32
+ </run_id>
33
+ <user_id>
34
+ test_user
35
+ </user_id>
36
+ <problem_id>
37
+ 222
38
+ </problem_id>
39
+ <status>
40
+ Wrong Answer
41
+ </status>
42
+ <language>
43
+ Ruby
44
+ </language>
45
+ <cputime>
46
+ 333
47
+ </cputime>
48
+ <memory>
49
+ 444
50
+ </memory>
51
+ <code_size>
52
+ 555
53
+ </code_size>
54
+ </status>
55
+ </status_list>