-
Notifications
You must be signed in to change notification settings - Fork 2
Implement the evaluator skeleton #1
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
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) |
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 |
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 |
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 |
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 |
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 |
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 |
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 |
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 | ||
subject { Coursemology::Evaluator::Models::Base } | ||
|
||
describe '.api_user_email' do | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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) } | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 \ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 \ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
class Coursemology::Evaluator::Client | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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)) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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)) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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)) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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)) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe 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 |
There was a problem hiding this comment.
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.