gfobh_scorer 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.
- checksums.yaml +7 -0
- data/.gitignore +17 -0
- data/Gemfile +4 -0
- data/Guardfile +81 -0
- data/LICENSE.txt +22 -0
- data/README.md +29 -0
- data/Rakefile +1 -0
- data/bin/gfobh_scorer +26 -0
- data/gfobh_scorer.gemspec +26 -0
- data/lib/gfobh_scorer.rb +6 -0
- data/lib/gfobh_scorer/scorer.rb +211 -0
- data/lib/gfobh_scorer/version.rb +3 -0
- data/spec/lib/scorer_spec.rb +180 -0
- data/spec/spec_helper.rb +1 -0
- metadata +117 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 080e26edf9074f022c3bd6612767c60f5bab2afd
|
4
|
+
data.tar.gz: cc72592bb673faf93e3b0fc7dc989e238b4afbf8
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 5a2dde201e4cb2ca82a1736e7b0b5d5cc1147c74661320571b458b340ae0bf96c6d112431fb9852f413ab5736172e60b73ee06fd38ce84166607446ef157021f
|
7
|
+
data.tar.gz: 3ad564bfccebc15bf0e88b324935b12529733eb4a5cd838830567c4602130b92c36d6549631e24ec017e9f4e77c3aad9821c00346d8dc56afd85fb1b957804e2
|
data/.gitignore
ADDED
data/Gemfile
ADDED
data/Guardfile
ADDED
@@ -0,0 +1,81 @@
|
|
1
|
+
# A sample Guardfile
|
2
|
+
# More info at https://github.com/guard/guard#readme
|
3
|
+
|
4
|
+
## Uncomment and set this to only include directories you want to watch
|
5
|
+
# directories %w(app lib config test spec feature)
|
6
|
+
|
7
|
+
## Uncomment to clear the screen before every task
|
8
|
+
# clearing :on
|
9
|
+
|
10
|
+
## Guard internally checks for changes in the Guardfile and exits.
|
11
|
+
## If you want Guard to automatically start up again, run guard in a
|
12
|
+
## shell loop, e.g.:
|
13
|
+
##
|
14
|
+
## $ while bundle exec guard; do echo "Restarting Guard..."; done
|
15
|
+
##
|
16
|
+
## Note: if you are using the `directories` clause above and you are not
|
17
|
+
## watching the project directory ('.'), the you will want to move the Guardfile
|
18
|
+
## to a watched dir and symlink it back, e.g.
|
19
|
+
#
|
20
|
+
# $ mkdir config
|
21
|
+
# $ mv Guardfile config/
|
22
|
+
# $ ln -s config/Guardfile .
|
23
|
+
#
|
24
|
+
# and, you'll have to watch "config/Guardfile" instead of "Guardfile"
|
25
|
+
|
26
|
+
# Note: The cmd option is now required due to the increasing number of ways
|
27
|
+
# rspec may be run, below are examples of the most common uses.
|
28
|
+
# * bundler: 'bundle exec rspec'
|
29
|
+
# * bundler binstubs: 'bin/rspec'
|
30
|
+
# * spring: 'bin/rspec' (This will use spring if running and you have
|
31
|
+
# installed the spring binstubs per the docs)
|
32
|
+
# * zeus: 'zeus rspec' (requires the server to be started separately)
|
33
|
+
# * 'just' rspec: 'rspec'
|
34
|
+
|
35
|
+
guard :rspec, cmd: "bundle exec rspec" do
|
36
|
+
require "guard/rspec/dsl"
|
37
|
+
dsl = Guard::RSpec::Dsl.new(self)
|
38
|
+
|
39
|
+
# Feel free to open issues for suggestions and improvements
|
40
|
+
|
41
|
+
# RSpec files
|
42
|
+
rspec = dsl.rspec
|
43
|
+
watch(rspec.spec_helper) { rspec.spec_dir }
|
44
|
+
watch(rspec.spec_support) { rspec.spec_dir }
|
45
|
+
watch(rspec.spec_files)
|
46
|
+
|
47
|
+
# Ruby files
|
48
|
+
ruby = dsl.ruby
|
49
|
+
dsl.watch_spec_files_for(ruby.lib_files)
|
50
|
+
|
51
|
+
watch(%r{lib/gfobh_scorer/(.*)\.rb}) do |m|
|
52
|
+
rspec.spec.("lib/#{m[1]}_spec.rb")
|
53
|
+
end
|
54
|
+
|
55
|
+
# Rails files
|
56
|
+
rails = dsl.rails(view_extensions: %w(erb haml slim))
|
57
|
+
dsl.watch_spec_files_for(rails.app_files)
|
58
|
+
dsl.watch_spec_files_for(rails.views)
|
59
|
+
|
60
|
+
watch(rails.controllers) do |m|
|
61
|
+
[
|
62
|
+
rspec.spec.("routing/#{m[1]}_routing"),
|
63
|
+
rspec.spec.("controllers/#{m[1]}_controller"),
|
64
|
+
rspec.spec.("acceptance/#{m[1]}")
|
65
|
+
]
|
66
|
+
end
|
67
|
+
|
68
|
+
# Rails config changes
|
69
|
+
watch(rails.spec_helper) { rspec.spec_dir }
|
70
|
+
watch(rails.routes) { "#{rspec.spec_dir}/routing" }
|
71
|
+
watch(rails.app_controller) { "#{rspec.spec_dir}/controllers" }
|
72
|
+
|
73
|
+
# Capybara features specs
|
74
|
+
watch(rails.view_dirs) { |m| rspec.spec.("features/#{m[1]}") }
|
75
|
+
|
76
|
+
# Turnip features and steps
|
77
|
+
watch(%r{^spec/acceptance/(.+)\.feature$})
|
78
|
+
watch(%r{^spec/acceptance/steps/(.+)_steps\.rb$}) do |m|
|
79
|
+
Dir[File.join("**/#{m[1]}.feature")][0] || "spec/acceptance"
|
80
|
+
end
|
81
|
+
end
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2015 Dan Langevin
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,29 @@
|
|
1
|
+
# GfobhScorer
|
2
|
+
|
3
|
+
TODO: Write a gem description
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
gem 'gfobh_scorer'
|
10
|
+
|
11
|
+
And then execute:
|
12
|
+
|
13
|
+
$ bundle
|
14
|
+
|
15
|
+
Or install it yourself as:
|
16
|
+
|
17
|
+
$ gem install gfobh_scorer
|
18
|
+
|
19
|
+
## Usage
|
20
|
+
|
21
|
+
TODO: Write usage instructions here
|
22
|
+
|
23
|
+
## Contributing
|
24
|
+
|
25
|
+
1. Fork it
|
26
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
27
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
28
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
29
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
data/bin/gfobh_scorer
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'gfobh_scorer'
|
4
|
+
require 'yaml'
|
5
|
+
|
6
|
+
config = begin
|
7
|
+
YAML.load_file(".config.yml")
|
8
|
+
rescue
|
9
|
+
{}
|
10
|
+
end
|
11
|
+
|
12
|
+
# symoblize_keys
|
13
|
+
symbolized = {}
|
14
|
+
config.each_pair do |k,v|
|
15
|
+
symbolized[k.to_sym] ||= v
|
16
|
+
end
|
17
|
+
|
18
|
+
config.merge!(symbolized)
|
19
|
+
|
20
|
+
scorer = GfobhScorer::Scorer.new(ARGV[0], config: config)
|
21
|
+
|
22
|
+
if scorer.run
|
23
|
+
Kernel.exit(0)
|
24
|
+
else
|
25
|
+
Kernel.exit(1)
|
26
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'gfobh_scorer/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "gfobh_scorer"
|
8
|
+
spec.version = GfobhScorer::VERSION
|
9
|
+
spec.authors = ["Dan Langevin"]
|
10
|
+
spec.email = ["dan.langevin@gmail.com"]
|
11
|
+
spec.description = %q{Scoring tool for Get Fit Or Be Hacking}
|
12
|
+
spec.summary = %q{Scoring tool}
|
13
|
+
spec.homepage = ""
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files`.split($/)
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_dependency 'rest-client'
|
22
|
+
|
23
|
+
spec.add_development_dependency "bundler", "~> 1.3"
|
24
|
+
spec.add_development_dependency "rake"
|
25
|
+
spec.add_development_dependency "guard-rspec"
|
26
|
+
end
|
data/lib/gfobh_scorer.rb
ADDED
@@ -0,0 +1,211 @@
|
|
1
|
+
require 'json'
|
2
|
+
require 'restclient'
|
3
|
+
|
4
|
+
module GfobhScorer
|
5
|
+
class Scorer
|
6
|
+
BASE_URL = 'https://gfobh.herokuapp.com'
|
7
|
+
|
8
|
+
def initialize(track_name, opts = {})
|
9
|
+
@track_name = track_name
|
10
|
+
@stdout = opts[:stdout] || STDOUT
|
11
|
+
@stderr = opts[:stderr] || STDERR
|
12
|
+
@config = opts[:config] || {}
|
13
|
+
@current_example = 1
|
14
|
+
end
|
15
|
+
|
16
|
+
def run
|
17
|
+
# grab our inital seed value for this example se
|
18
|
+
curr = fetch_initial_seed
|
19
|
+
|
20
|
+
# loop through til we get a wrong answer (curr is false) or
|
21
|
+
# we have reached the end (curr is true)
|
22
|
+
while (curr = run_current_example(curr)) && is_seed_value(curr)
|
23
|
+
report_success
|
24
|
+
@current_example += 1
|
25
|
+
end
|
26
|
+
|
27
|
+
report_results(curr)
|
28
|
+
curr
|
29
|
+
end
|
30
|
+
|
31
|
+
private
|
32
|
+
|
33
|
+
attr_reader :config, :current_example, :stdout, :stderr, :track_name
|
34
|
+
|
35
|
+
def base_url
|
36
|
+
config[:base_url] || BASE_URL
|
37
|
+
end
|
38
|
+
|
39
|
+
#
|
40
|
+
# Run the current example script, benchmarking the
|
41
|
+
# amount of time it takes
|
42
|
+
#
|
43
|
+
# @param seed [String]
|
44
|
+
#
|
45
|
+
# @return [String] Result of the script
|
46
|
+
def benchmark_current_example(seed)
|
47
|
+
start = Time.now
|
48
|
+
log("running #{current_example_script} #{seed}")
|
49
|
+
ret = begin
|
50
|
+
`#{current_example_script} #{seed}`
|
51
|
+
rescue Errno::ENOENT
|
52
|
+
log("#{current_example_script} does not exist")
|
53
|
+
"" # blank output is considered a failure
|
54
|
+
end
|
55
|
+
timings[current_example] = (Time.now - start).to_f
|
56
|
+
ret.to_s.strip
|
57
|
+
end
|
58
|
+
|
59
|
+
#
|
60
|
+
# Get the name of the current example to run
|
61
|
+
#
|
62
|
+
# @return [type] [description]
|
63
|
+
def current_example_script
|
64
|
+
config["example_#{current_example}".to_sym] ||
|
65
|
+
"./bin/example_#{current_example}"
|
66
|
+
end
|
67
|
+
|
68
|
+
|
69
|
+
#
|
70
|
+
# alias for verify_current_answer with no args
|
71
|
+
#
|
72
|
+
# @return [String]
|
73
|
+
def fetch_initial_seed
|
74
|
+
verify_current_answer
|
75
|
+
end
|
76
|
+
|
77
|
+
def headers
|
78
|
+
{ 'Accept' => 'application/json' }
|
79
|
+
end
|
80
|
+
|
81
|
+
def is_seed_value(curr)
|
82
|
+
![true, false, nil].include?(curr)
|
83
|
+
end
|
84
|
+
|
85
|
+
#
|
86
|
+
# Log a message
|
87
|
+
# @param msg [String] The message
|
88
|
+
#
|
89
|
+
# @return [String] The message
|
90
|
+
def log(msg)
|
91
|
+
stdout.puts(msg) if config[:debug]
|
92
|
+
end
|
93
|
+
|
94
|
+
#
|
95
|
+
# Wrapper method to handle track-level reporting
|
96
|
+
#
|
97
|
+
# @param success [Boolean]
|
98
|
+
#
|
99
|
+
# @return [nil]
|
100
|
+
def report_results(success)
|
101
|
+
if success
|
102
|
+
|
103
|
+
else
|
104
|
+
report_failure
|
105
|
+
end
|
106
|
+
|
107
|
+
report_total_time
|
108
|
+
|
109
|
+
nil
|
110
|
+
end
|
111
|
+
|
112
|
+
#
|
113
|
+
# Helper function to print the total time it took
|
114
|
+
#
|
115
|
+
# @return [String]
|
116
|
+
def report_total_time
|
117
|
+
stdout.puts(
|
118
|
+
sprintf(
|
119
|
+
"Total time for all examples: %.4f seconds",
|
120
|
+
timings.values.reduce(0, :+)
|
121
|
+
)
|
122
|
+
)
|
123
|
+
end
|
124
|
+
|
125
|
+
#
|
126
|
+
# Helper function to print a failure message
|
127
|
+
#
|
128
|
+
# @return [nil]
|
129
|
+
def report_failure
|
130
|
+
stderr.puts(
|
131
|
+
"Your answer for example #{current_example} was incorrect"
|
132
|
+
)
|
133
|
+
nil
|
134
|
+
end
|
135
|
+
|
136
|
+
#
|
137
|
+
# Helper function to print a success message
|
138
|
+
#
|
139
|
+
# @return [nil]
|
140
|
+
def report_success
|
141
|
+
stdout.puts(
|
142
|
+
sprintf(
|
143
|
+
"Finished example #{current_example} in %.4f seconds.",
|
144
|
+
timings[current_example]
|
145
|
+
)
|
146
|
+
)
|
147
|
+
nil
|
148
|
+
end
|
149
|
+
|
150
|
+
#
|
151
|
+
# Runs current example and verifies the
|
152
|
+
# retsult
|
153
|
+
#
|
154
|
+
# @param seed [String] Seed value from the last example
|
155
|
+
#
|
156
|
+
# @return [Boolean, String] True if it was correct and this
|
157
|
+
# is the last example, false if incorrect, String value if there
|
158
|
+
# are more examples to run
|
159
|
+
def run_current_example(seed)
|
160
|
+
log("Running example #{current_example} with #{seed}")
|
161
|
+
answer = benchmark_current_example(seed)
|
162
|
+
return false if answer.empty?
|
163
|
+
verify_current_answer(answer)
|
164
|
+
end
|
165
|
+
|
166
|
+
#
|
167
|
+
# Hashmap of example timings
|
168
|
+
#
|
169
|
+
# @return [Hash]
|
170
|
+
def timings
|
171
|
+
@timings ||= {}
|
172
|
+
end
|
173
|
+
|
174
|
+
|
175
|
+
#
|
176
|
+
# Verify the answer from a script against our server
|
177
|
+
#
|
178
|
+
# @param answer = nil [String] Answer to the current example
|
179
|
+
#
|
180
|
+
# @return [Boolean, String] True if it was correct and this
|
181
|
+
# is the last example, false if incorrect, String value if there
|
182
|
+
# are more examples to run
|
183
|
+
def verify_current_answer(answer = nil)
|
184
|
+
full_url = [base_url, track_name, answer].compact.join('/')
|
185
|
+
log("Verifying #{full_url}")
|
186
|
+
RestClient.get(full_url, headers) do |response|
|
187
|
+
case response.code
|
188
|
+
# success
|
189
|
+
when 200
|
190
|
+
log(
|
191
|
+
"Retrieved new seed value #{JSON.parse(response.body)['seed']}"
|
192
|
+
)
|
193
|
+
JSON.parse(response.body)['seed']
|
194
|
+
# success and it's the last example
|
195
|
+
when 204
|
196
|
+
log("End of problem set")
|
197
|
+
true
|
198
|
+
# failure
|
199
|
+
when 404
|
200
|
+
log("Incorrect answer")
|
201
|
+
false
|
202
|
+
else
|
203
|
+
stderr.puts(
|
204
|
+
"Something has gone wrong. Please try again"
|
205
|
+
)
|
206
|
+
Kernel.exit(1)
|
207
|
+
end
|
208
|
+
end
|
209
|
+
end
|
210
|
+
end
|
211
|
+
end
|
@@ -0,0 +1,180 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe GfobhScorer::Scorer do
|
4
|
+
subject(:scorer) do
|
5
|
+
described_class.new(
|
6
|
+
track,
|
7
|
+
stdout: stdout,
|
8
|
+
stderr: stderr
|
9
|
+
)
|
10
|
+
end
|
11
|
+
|
12
|
+
let(:response1) do
|
13
|
+
double(
|
14
|
+
:response1,
|
15
|
+
code: 200,
|
16
|
+
body: JSON.unparse({
|
17
|
+
seed: 'seed-for-problem-1'
|
18
|
+
})
|
19
|
+
)
|
20
|
+
end
|
21
|
+
|
22
|
+
let(:response2) do
|
23
|
+
double(
|
24
|
+
:response2,
|
25
|
+
code: 200,
|
26
|
+
body: JSON.unparse({
|
27
|
+
seed: 'seed-for-problem-2'
|
28
|
+
})
|
29
|
+
)
|
30
|
+
end
|
31
|
+
|
32
|
+
let(:final_response) do
|
33
|
+
double(:final_response, code: 204)
|
34
|
+
end
|
35
|
+
|
36
|
+
let(:generic_response) do
|
37
|
+
double(
|
38
|
+
:generic_response,
|
39
|
+
code: 200,
|
40
|
+
body: JSON.unparse({ seed: 'foo' })
|
41
|
+
)
|
42
|
+
end
|
43
|
+
|
44
|
+
let(:headers) do
|
45
|
+
{ 'Accept' => 'application/json' }
|
46
|
+
end
|
47
|
+
|
48
|
+
let(:not_found_response) do
|
49
|
+
double(
|
50
|
+
:not_found_response,
|
51
|
+
code: 404
|
52
|
+
)
|
53
|
+
end
|
54
|
+
|
55
|
+
let(:stderr) { StringIO.new }
|
56
|
+
|
57
|
+
let(:stdout) { StringIO.new }
|
58
|
+
|
59
|
+
let(:track) { 'problem_set_1' }
|
60
|
+
|
61
|
+
def make_url(seed = nil, base = GfobhScorer::Scorer::BASE_URL)
|
62
|
+
[base, track, seed]
|
63
|
+
.compact
|
64
|
+
.join('/')
|
65
|
+
end
|
66
|
+
|
67
|
+
describe 'When configuring a custom url and example path' do
|
68
|
+
subject(:scorer) do
|
69
|
+
described_class.new(
|
70
|
+
track,
|
71
|
+
stdout: stdout,
|
72
|
+
stderr: stderr,
|
73
|
+
config: {
|
74
|
+
base_url: 'http://foo.bar/baz',
|
75
|
+
example_1: '/path/to/example'
|
76
|
+
}
|
77
|
+
)
|
78
|
+
end
|
79
|
+
|
80
|
+
it 'hits the correct urls and scripts' do
|
81
|
+
expect(RestClient).to receive(:get)
|
82
|
+
.with(make_url(nil, 'http://foo.bar/baz'), headers)
|
83
|
+
.and_yield(response1)
|
84
|
+
expect(subject).to receive(:`)
|
85
|
+
.with('/path/to/example seed-for-problem-1')
|
86
|
+
.and_return('answer-for-problem-1')
|
87
|
+
expect(RestClient).to receive(:get)
|
88
|
+
.with(
|
89
|
+
make_url('answer-for-problem-1', 'http://foo.bar/baz'), headers
|
90
|
+
)
|
91
|
+
.and_yield(final_response)
|
92
|
+
|
93
|
+
expect(subject.run).to eql true
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
describe 'When fetching the initial example' do
|
98
|
+
before do
|
99
|
+
allow(RestClient).to receive(:get)
|
100
|
+
.and_yield(generic_response)
|
101
|
+
allow(subject).to receive(:`)
|
102
|
+
.and_return("")
|
103
|
+
expect(RestClient).to receive(:get)
|
104
|
+
.with(make_url, headers)
|
105
|
+
.and_yield(response1)
|
106
|
+
allow(stdout).to receive(:puts)
|
107
|
+
allow(stderr).to receive(:puts)
|
108
|
+
|
109
|
+
allow(subject).to receive(:`)
|
110
|
+
.with('./bin/example_1 seed-for-problem-1')
|
111
|
+
.and_return('answer-for-problem-1')
|
112
|
+
end
|
113
|
+
|
114
|
+
it 'loads the data based on the track of work' do
|
115
|
+
subject.run
|
116
|
+
end
|
117
|
+
|
118
|
+
describe 'with a correct first answer' do
|
119
|
+
before do
|
120
|
+
expect(RestClient).to receive(:get)
|
121
|
+
.with(make_url('answer-for-problem-1'), headers)
|
122
|
+
.and_yield(response2)
|
123
|
+
end
|
124
|
+
|
125
|
+
it 'hits the second url' do
|
126
|
+
subject.run
|
127
|
+
end
|
128
|
+
|
129
|
+
it 'reports the status of the first example' do
|
130
|
+
subject.run
|
131
|
+
expect(stdout).to have_received(:puts)
|
132
|
+
.with(/Finished example 1 in [\d\.]+ seconds/)
|
133
|
+
end
|
134
|
+
|
135
|
+
it 'reports the total elapsed time' do
|
136
|
+
subject.run
|
137
|
+
expect(stdout).to have_received(:puts)
|
138
|
+
.with(/Total time for all examples: [\d\.]+ seconds/)
|
139
|
+
end
|
140
|
+
|
141
|
+
describe 'with a correct second answer' do
|
142
|
+
before do
|
143
|
+
allow(subject).to receive(:`)
|
144
|
+
.with('./bin/example_2 seed-for-problem-2')
|
145
|
+
.and_return('answer-for-problem-2')
|
146
|
+
end
|
147
|
+
|
148
|
+
describe 'when the second example is the last one' do
|
149
|
+
before do
|
150
|
+
expect(RestClient).to receive(:get)
|
151
|
+
.with(make_url('answer-for-problem-2'), headers)
|
152
|
+
.and_yield(final_response)
|
153
|
+
end
|
154
|
+
|
155
|
+
it 'returns true' do
|
156
|
+
expect(subject.run).to eql true
|
157
|
+
end
|
158
|
+
end
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
describe 'with an incorrect first answer' do
|
163
|
+
before do
|
164
|
+
expect(RestClient).to receive(:get)
|
165
|
+
.with(make_url('answer-for-problem-1'), headers)
|
166
|
+
.and_yield(not_found_response)
|
167
|
+
end
|
168
|
+
|
169
|
+
it 'reports the error to stderr' do
|
170
|
+
subject.run
|
171
|
+
expect(stderr).to have_received(:puts)
|
172
|
+
.with("Your answer for example 1 was incorrect")
|
173
|
+
end
|
174
|
+
|
175
|
+
it 'returns false' do
|
176
|
+
expect(subject.run).to eql false
|
177
|
+
end
|
178
|
+
end
|
179
|
+
end
|
180
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require 'gfobh_scorer'
|
metadata
ADDED
@@ -0,0 +1,117 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: gfobh_scorer
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Dan Langevin
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2015-04-05 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rest-client
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - '>='
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - '>='
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: bundler
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ~>
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '1.3'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ~>
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '1.3'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rake
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - '>='
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: guard-rspec
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - '>='
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
description: Scoring tool for Get Fit Or Be Hacking
|
70
|
+
email:
|
71
|
+
- dan.langevin@gmail.com
|
72
|
+
executables:
|
73
|
+
- gfobh_scorer
|
74
|
+
extensions: []
|
75
|
+
extra_rdoc_files: []
|
76
|
+
files:
|
77
|
+
- .gitignore
|
78
|
+
- Gemfile
|
79
|
+
- Guardfile
|
80
|
+
- LICENSE.txt
|
81
|
+
- README.md
|
82
|
+
- Rakefile
|
83
|
+
- bin/gfobh_scorer
|
84
|
+
- gfobh_scorer.gemspec
|
85
|
+
- lib/gfobh_scorer.rb
|
86
|
+
- lib/gfobh_scorer/scorer.rb
|
87
|
+
- lib/gfobh_scorer/version.rb
|
88
|
+
- spec/lib/scorer_spec.rb
|
89
|
+
- spec/spec_helper.rb
|
90
|
+
homepage: ''
|
91
|
+
licenses:
|
92
|
+
- MIT
|
93
|
+
metadata: {}
|
94
|
+
post_install_message:
|
95
|
+
rdoc_options: []
|
96
|
+
require_paths:
|
97
|
+
- lib
|
98
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
99
|
+
requirements:
|
100
|
+
- - '>='
|
101
|
+
- !ruby/object:Gem::Version
|
102
|
+
version: '0'
|
103
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
104
|
+
requirements:
|
105
|
+
- - '>='
|
106
|
+
- !ruby/object:Gem::Version
|
107
|
+
version: '0'
|
108
|
+
requirements: []
|
109
|
+
rubyforge_project:
|
110
|
+
rubygems_version: 2.0.3
|
111
|
+
signing_key:
|
112
|
+
specification_version: 4
|
113
|
+
summary: Scoring tool
|
114
|
+
test_files:
|
115
|
+
- spec/lib/scorer_spec.rb
|
116
|
+
- spec/spec_helper.rb
|
117
|
+
has_rdoc:
|