gfobh_scorer 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
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
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in gfobh_scorer.gemspec
4
+ gemspec
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
@@ -0,0 +1,6 @@
1
+ require "gfobh_scorer/version"
2
+ require "gfobh_scorer/scorer"
3
+
4
+ module GfobhScorer
5
+ # Your code goes here...
6
+ end
@@ -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,3 @@
1
+ module GfobhScorer
2
+ VERSION = "0.0.1"
3
+ 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
@@ -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: