Skip to content
This repository was archived by the owner on Sep 25, 2019. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,23 @@ PATH
remote: .
specs:
coursemology-evaluator (0.0.0)
active_rest_client (~> 1.2)
activesupport (~> 4.2.0)

GEM
remote: https://rubygems.org/
specs:
active_rest_client (1.2.0)
activesupport
crack
faraday
multi_json
activesupport (4.2.5)
i18n (~> 0.7)
json (~> 1.7, >= 1.7.7)
minitest (~> 5.1)
thread_safe (~> 0.3, >= 0.3.4)
tzinfo (~> 1.1)
codeclimate-test-reporter (0.4.8)
simplecov (>= 0.7.1, < 1.0.0)
coveralls (0.8.10)
Expand All @@ -15,14 +28,22 @@ GEM
term-ansicolor (~> 1.3)
thor (~> 0.19.1)
tins (~> 1.6.0)
crack (0.4.3)
safe_yaml (~> 1.0.0)
diff-lcs (1.2.5)
docile (1.1.5)
domain_name (0.5.25)
unf (>= 0.0.5, < 1.0.0)
faraday (0.9.2)
multipart-post (>= 1.2, < 3)
http-cookie (1.0.2)
domain_name (~> 0.5)
i18n (0.7.0)
json (1.8.3)
mime-types (2.99)
minitest (5.8.3)
multi_json (1.11.2)
multipart-post (2.0.0)
netrc (0.11.0)
rake (10.4.2)
rest-client (1.8.0)
Expand All @@ -42,6 +63,7 @@ GEM
diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.4.0)
rspec-support (3.4.1)
safe_yaml (1.0.4)
simplecov (0.11.1)
docile (~> 1.1.0)
json (~> 1.8)
Expand All @@ -50,7 +72,10 @@ GEM
term-ansicolor (1.3.2)
tins (~> 1.0)
thor (0.19.1)
thread_safe (0.3.5)
tins (1.6.0)
tzinfo (1.2.2)
thread_safe (~> 0.1)
unf (0.1.4)
unf_ext
unf_ext (0.0.7.1)
Expand Down
5 changes: 5 additions & 0 deletions bin/evaluator
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#!/usr/bin/env ruby
require 'bundler/setup'
require 'coursemology/evaluator'

Coursemology::Evaluator::CLI.start(ARGV)
3 changes: 3 additions & 0 deletions coursemology-evaluator.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,7 @@ Gem::Specification.new do |spec|
spec.add_development_dependency 'simplecov'
spec.add_development_dependency 'coveralls'
spec.add_development_dependency 'codeclimate-test-reporter'

spec.add_dependency 'activesupport', '~> 4.2.0'
spec.add_dependency 'active_rest_client', '~> 1.2'
end
12 changes: 8 additions & 4 deletions lib/coursemology/evaluator.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
require 'active_support/all'
require 'active_rest_client'
require 'coursemology/evaluator/version'

module Coursemology
module Evaluator
# Your code goes here...
end
module Coursemology::Evaluator
extend ActiveSupport::Autoload

autoload :Client
autoload :CLI
autoload :Models
end
47 changes: 47 additions & 0 deletions lib/coursemology/evaluator/cli.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
require 'optparse'

class Coursemology::Evaluator::CLI
Options = Struct.new(:host, :api_token, :api_user_email)

def self.start(argv)
new.start(argv)
end

def start(argv)
run(argv)
end

def run(argv)
options = optparse!(argv)
Coursemology::Evaluator::Client.initialize(options.host, options.api_user_email,
options.api_token)
Coursemology::Evaluator::Client.new.run
end

private

# Parses the options specified on the command line.
#
# @param [Array<String>] argv The arguments specified on the command line.
# @return [Coursemology::Evaluator::CLI::Options]
def optparse!(argv) # rubocop:disable Metrics/MethodLength
options = Options.new
option_parser = OptionParser.new do |parser|
parser.banner = "Usage: #{parser.program_name} [options]"
parser.on('-hHOST', '--host=HOST', 'Coursemology host to connect to') do |host|
options.host = host
end

parser.on('-tTOKEN', '--api-token=TOKEN') do |token|
options.api_token = token
end

parser.on('-uUSER', '--api-user-email=USER') do |user|
options.api_user_email = user
end
end

option_parser.parse!(argv)
options
end
end
13 changes: 13 additions & 0 deletions lib/coursemology/evaluator/client.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
class Coursemology::Evaluator::Client
def self.initialize(host, api_user_email, api_token)
Coursemology::Evaluator::Models::Base.base_url = host
Coursemology::Evaluator::Models::Base.api_user_email = api_user_email
Coursemology::Evaluator::Models::Base.api_token = api_token
end

def initialize
end

def run
end
end
6 changes: 6 additions & 0 deletions lib/coursemology/evaluator/models.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
module Coursemology::Evaluator::Models
extend ActiveSupport::Autoload

autoload :Base
autoload :ProgrammingEvaluation
end
16 changes: 16 additions & 0 deletions lib/coursemology/evaluator/models/base.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
class Coursemology::Evaluator::Models::Base < ActiveRestClient::Base
class << self
attr_accessor :api_user_email
attr_accessor :api_token
end

before_request :add_authentication

private

# Adds the authentication email and token to the request.
def add_authentication(_, request)
request.headers['X-User-Email'] = self.class.api_user_email
request.headers['X-User-Token'] = self.class.api_token
end
end
60 changes: 60 additions & 0 deletions spec/coursemology/evaluator/cli_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
RSpec.describe Coursemology::Evaluator::CLI do
let(:host) { 'http://localhost:3000' }
let(:api_token) { 'abcd' }
let(:api_user_email) { 'test@example.org' }
let(:argv) do
["--host=#{host}", "--api-token=#{api_token}", "--api-user-email=#{api_user_email}"]
end

describe Coursemology::Evaluator::CLI::Options do
it { is_expected.to have_attributes(host: nil, api_token: nil, api_user_email: nil) }
end

with_mock_client do
describe '.start' do
subject { Coursemology::Evaluator::CLI }
it 'calls #start' do
expect(subject).to receive_message_chain(:new, :start)
subject.start(argv)
end
end

describe '#start' do
subject { Coursemology::Evaluator::CLI.new }
it 'calls #run' do
expect(subject).to receive(:run).and_call_original
subject.start(argv)
end
end

describe '#run' do
subject { Coursemology::Evaluator::CLI.new.run(argv) }

it 'creates a client' do
expect(Coursemology::Evaluator::Client).to receive(:new).and_call_original
subject
end

it 'runs the client' do
expect(Coursemology::Evaluator::Client).to receive_message_chain(:new, :run)
subject
end
end
end

describe '#optparse!' do
subject { Coursemology::Evaluator::CLI.new.send(:optparse!, argv) }

it 'parses --host' do
expect(subject.host).to eq(host)
end

it 'parses --api-token' do
expect(subject.api_token).to eq(api_token)
end

it 'parses api-user-email' do
expect(subject.api_user_email).to eq(api_user_email)
end
end
end
18 changes: 18 additions & 0 deletions spec/coursemology/evaluator/client_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
RSpec.describe Coursemology::Evaluator::Client do
with_mock_client do
describe '.initialize' do
let(:base_url) { 'http://localhost:3000' }
let(:api_token) { 'abcd' }
let(:api_user_email) { 'test@example.org' }

subject { Coursemology::Evaluator::Client }

it 'sets the API parameters' do
subject.initialize(base_url, api_user_email, api_token)
expect(Coursemology::Evaluator::Models::Base.base_url).to eq(base_url)
expect(Coursemology::Evaluator::Models::Base.api_user_email).to eq(api_user_email)
expect(Coursemology::Evaluator::Models::Base.api_token).to eq(api_token)
end
end
end
end
37 changes: 37 additions & 0 deletions spec/coursemology/evaluator/models/base_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
RSpec.describe Coursemology::Evaluator::Models::Base do
describe 'class attributes' do

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Prefer double-quoted strings unless you need single quotes to avoid extra backslashes for escaping.

subject { Coursemology::Evaluator::Models::Base }

describe '.api_user_email' do

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Prefer double-quoted strings unless you need single quotes to avoid extra backslashes for escaping.

it { is_expected.to have_attributes(api_user_email: nil) }
end

describe '.api_token' do

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Prefer double-quoted strings unless you need single quotes to avoid extra backslashes for escaping.

it { is_expected.to have_attributes(api_token: nil) }
end
end

describe '#adds_authentication' do
with_mock_client(api_user_email: 'email', api_token: 'token') do

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Prefer double-quoted strings unless you need single quotes to avoid extra backslashes for escaping.

let(:request) do
headers = {}
double.tap do |double|
expect(double).to receive(:headers).and_return(headers).at_least(:once)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Line is too long. [81/80]

end
end
subject { Coursemology::Evaluator::Models::Base.new.send(:add_authentication, nil, request) }

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Line is too long. [99/80]


it 'adds the X-User-Email header' do

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Prefer double-quoted strings unless you need single quotes to avoid extra backslashes for escaping.

subject
expect(request.headers['X-User-Email']).to \

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Prefer double-quoted strings unless you need single quotes to avoid extra backslashes for escaping.

eq(Coursemology::Evaluator::Models::Base.api_user_email)
end

it 'adds the X-User-Token header' do

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Prefer double-quoted strings unless you need single quotes to avoid extra backslashes for escaping.

subject
expect(request.headers['X-User-Token']).to \

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Prefer double-quoted strings unless you need single quotes to avoid extra backslashes for escaping.

eq(Coursemology::Evaluator::Models::Base.api_token)
end
end
end
end
4 changes: 0 additions & 4 deletions spec/coursemology/evaluator_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,4 @@
it 'has a version number' do
expect(Coursemology::Evaluator::VERSION).not_to be nil
end

it 'does something useful' do
expect(false).to eq(true)
end
end
1 change: 1 addition & 0 deletions spec/spec_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
$LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
require 'coverage_helper'
require 'coursemology/evaluator'
Dir["#{__dir__}/support/**/*"].each { |file| require file }

RSpec.configure do |config|
# rspec-expectations config goes here. You can use an alternate
Expand Down
50 changes: 50 additions & 0 deletions spec/support/client_stub.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
class Coursemology::Evaluator::Client

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use nested module/class definitions instead of compact style.

module TestGroupHelperMethods
def self.client_options_description(host, api_user_email, api_token)
result = []
result << "host: #{host}" if host
result << "api_user_email: #{api_user_email}" if api_user_email
result << "api_token: #{api_token}" if api_token

result
end

def self.mock_client(host, api_user_email, api_token)
proc do
base_model = Coursemology::Evaluator::Models::Base
instance_exec(base_model, :base_url, host,
&TestGroupHelperMethods.instance_method(:mock_property).bind(self))

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Line is too long. [89/80]

instance_exec(base_model, :api_user_email, api_user_email,
&TestGroupHelperMethods.instance_method(:mock_property).bind(self))

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Line is too long. [89/80]

instance_exec(base_model, :api_token, api_token,
&TestGroupHelperMethods.instance_method(:mock_property).bind(self))

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Line is too long. [89/80]

end
end

def mock_property(object, property, value)
allow(object).to receive(property) do
value
end
allow(object).to receive("#{property}=".to_s) do |new_value|
value = new_value
end
end
end

module TestGroupHelpers
def with_mock_client(host: nil, api_user_email: nil, api_token: nil, &block)
client_description = TestGroupHelperMethods.
client_options_description(host, api_user_email, api_token).to_sentence

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Line is too long. [98/80]


context "with client: #{client_description}" do
before(:each, &TestGroupHelperMethods.mock_client(host, api_user_email, api_token))

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Line is too long. [91/80]


module_eval(&block)
end
end
end
end

RSpec.configure do |config|
config.extend Coursemology::Evaluator::Client::TestGroupHelpers
end