lightside 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +3 -0
- data/.rspec +2 -0
- data/Gemfile +3 -0
- data/Guardfile +5 -0
- data/README.md +4 -0
- data/lib/lightside.rb +6 -0
- data/lib/lightside/config.rb +23 -0
- data/lib/lightside/exceptions.rb +12 -0
- data/lib/lightside/models/answer.rb +12 -0
- data/lib/lightside/models/answer_set.rb +12 -0
- data/lib/lightside/models/assignment_icon.rb +12 -0
- data/lib/lightside/models/assignment_tile_color.rb +12 -0
- data/lib/lightside/models/author.rb +12 -0
- data/lib/lightside/models/corpus.rb +16 -0
- data/lib/lightside/models/human_score.rb +12 -0
- data/lib/lightside/models/prediction_result.rb +12 -0
- data/lib/lightside/models/prediction_task.rb +25 -0
- data/lib/lightside/models/prompt.rb +12 -0
- data/lib/lightside/models/resolved_score.rb +12 -0
- data/lib/lightside/models/tag_answer_set.rb +12 -0
- data/lib/lightside/models/tag_prompt.rb +12 -0
- data/lib/lightside/models/trained_model.rb +12 -0
- data/lib/lightside/models/trained_model_evaluation.rb +12 -0
- data/lib/lightside/models/training_answer.rb +12 -0
- data/lib/lightside/models/training_task.rb +25 -0
- data/lib/lightside/pager.rb +72 -0
- data/lib/lightside/resources.rb +171 -0
- data/lib/lightside/version.rb +4 -0
- data/lightside.gemspec +27 -0
- data/spec/config_spec.rb +36 -0
- data/spec/fixtures/prompts.json +1 -0
- data/spec/fixtures/prompts/2.json +1 -0
- data/spec/fixtures/prompts_1.json +1 -0
- data/spec/fixtures/prompts_2.json +1 -0
- data/spec/fixtures/prompts_3.json +1 -0
- data/spec/fixtures/prompts_4.json +1 -0
- data/spec/pager_spec.rb +104 -0
- data/spec/resources_spec.rb +228 -0
- data/spec/spec_helper.rb +22 -0
- metadata +206 -0
data/.gitignore
ADDED
data/.rspec
ADDED
data/Gemfile
ADDED
data/Guardfile
ADDED
data/README.md
ADDED
data/lib/lightside.rb
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
module LightSide
|
2
|
+
|
3
|
+
def self.configure
|
4
|
+
@configuration ||= LightSide::Config
|
5
|
+
yield @configuration if block_given?
|
6
|
+
@configuration
|
7
|
+
end
|
8
|
+
|
9
|
+
class Config
|
10
|
+
singleton_class.class_eval do
|
11
|
+
attr_accessor :auth_token, :base_url
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.headers
|
15
|
+
{ "Authorization" => "Token #{auth_token}", "Content-Type" => "application/json" }
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.configured?
|
19
|
+
auth_token && base_url
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
module LightSide
|
2
|
+
class Answer
|
3
|
+
include LightSide::Resources
|
4
|
+
|
5
|
+
setup do
|
6
|
+
self.resource_base = "answers"
|
7
|
+
self.readonly_attributes = %w( url predicted prediction_results created modified )
|
8
|
+
self.writable_attributes = %w( parent author answer_set text author_comments reviewer_commentss submission viewed auth_token )
|
9
|
+
end
|
10
|
+
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
module LightSide
|
2
|
+
class AnswerSet
|
3
|
+
include LightSide::Resources
|
4
|
+
|
5
|
+
setup do
|
6
|
+
self.resource_base = "answer-sets"
|
7
|
+
self.readonly_attributes = %w( url owner answers prediction_tasks created modified )
|
8
|
+
self.writable_attributes = %w( prompt icon tile_color auth_token trained_models tags )
|
9
|
+
end
|
10
|
+
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
module LightSide
|
2
|
+
class Author
|
3
|
+
include LightSide::Resources
|
4
|
+
|
5
|
+
setup do
|
6
|
+
self.resource_base = "authors"
|
7
|
+
self.readonly_attributes = %w( url owner answers created modified )
|
8
|
+
self.writable_attributes = %w( designator email auth_token active )
|
9
|
+
end
|
10
|
+
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
module LightSide
|
2
|
+
class Corpus
|
3
|
+
include LightSide::Resources
|
4
|
+
|
5
|
+
setup do
|
6
|
+
self.resource_base = "corpora"
|
7
|
+
self.readonly_attributes = %w( url owner training_answers created modified )
|
8
|
+
self.writable_attributes = %w( prompt description active )
|
9
|
+
end
|
10
|
+
|
11
|
+
def training_answer_ids
|
12
|
+
training_answers.map { |url| url.split("/").last }
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
module LightSide
|
2
|
+
class PredictionResult
|
3
|
+
include LightSide::Resources
|
4
|
+
|
5
|
+
setup do
|
6
|
+
self.resource_base = "prediction-results"
|
7
|
+
self.readonly_attributes = %w( url answer prediction_task trained_model distribution label possible_labels created modified )
|
8
|
+
self.writable_attributes = %w( )
|
9
|
+
end
|
10
|
+
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module LightSide
|
2
|
+
class PredictionTask
|
3
|
+
include LightSide::Resources
|
4
|
+
|
5
|
+
setup do
|
6
|
+
self.resource_base = "prediction-tasks"
|
7
|
+
self.readonly_attributes = %w( url process task_id owner status messages prediction_results created modified )
|
8
|
+
self.writable_attributes = %w( answer_set )
|
9
|
+
end
|
10
|
+
|
11
|
+
def process_start
|
12
|
+
RestClient.post(process, "", Config.headers) do |response, request, result|
|
13
|
+
case response.code
|
14
|
+
when 200, 202
|
15
|
+
return JSON.parse(response)
|
16
|
+
when 404
|
17
|
+
raise ResourceNotFound, "could not find #{name} with ID=#{id}"
|
18
|
+
else
|
19
|
+
raise JSON.parse(response)["detail"]
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
module LightSide
|
2
|
+
class Prompt
|
3
|
+
include LightSide::Resources
|
4
|
+
|
5
|
+
setup do
|
6
|
+
self.resource_base = "prompts"
|
7
|
+
self.readonly_attributes = %w( url owner parent corpora answer_sets created modified )
|
8
|
+
self.writable_attributes = %w( title text instructions description lower upper default_models alignments tags active )
|
9
|
+
end
|
10
|
+
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
module LightSide
|
2
|
+
class ResolvedScore
|
3
|
+
include LightSide::Resources
|
4
|
+
|
5
|
+
setup do
|
6
|
+
self.resource_base = "resolved-scores"
|
7
|
+
self.readonly_attributes = %w( url created modified )
|
8
|
+
self.writable_attributes = %w( training_answer label )
|
9
|
+
end
|
10
|
+
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
module LightSide
|
2
|
+
class TrainedModel
|
3
|
+
include LightSide::Resources
|
4
|
+
|
5
|
+
setup do
|
6
|
+
self.resource_base = "trained-models"
|
7
|
+
self.readonly_attributes = %w( url corpus learner feature_set creation_method recipe_file active created modified )
|
8
|
+
self.writable_attributes = %w( name evaluations predictions )
|
9
|
+
end
|
10
|
+
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
module LightSide
|
2
|
+
class TrainedModelEvaluation
|
3
|
+
include LightSide::Resources
|
4
|
+
|
5
|
+
setup do
|
6
|
+
self.resource_base = "trained-model-evaluations"
|
7
|
+
self.readonly_attributes = %w( url trained_model accuracy entropy kappa weighted_kappa label created modified )
|
8
|
+
self.writable_attributes = %w( )
|
9
|
+
end
|
10
|
+
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
module LightSide
|
2
|
+
class TrainingTask
|
3
|
+
include LightSide::Resources
|
4
|
+
|
5
|
+
setup do
|
6
|
+
self.resource_base = "training-tasks"
|
7
|
+
self.readonly_attributes = %w( url process task_id owner status messages trained_model created modified )
|
8
|
+
self.writable_attributes = %w( corpus )
|
9
|
+
end
|
10
|
+
|
11
|
+
def process_start
|
12
|
+
RestClient.post(process, "", Config.headers) do |response, request, result|
|
13
|
+
case response.code
|
14
|
+
when 200, 202
|
15
|
+
yield JSON.parse(response)
|
16
|
+
when 404
|
17
|
+
raise ResourceNotFound, "could not find #{name} with ID=#{id}"
|
18
|
+
else
|
19
|
+
raise JSON.parse(response)["detail"]
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
module LightSide
|
2
|
+
class Pager
|
3
|
+
include Enumerable
|
4
|
+
|
5
|
+
attr_accessor :collection, :next_url, :params, :previous_url, :resource_builder, :resource_url, :url
|
6
|
+
|
7
|
+
def initialize(model_class, params={})
|
8
|
+
self.resource_url = model_class.resource_url
|
9
|
+
self.resource_builder = lambda { |hash| model_class.new(hash) }
|
10
|
+
self.params = { page: 1 }.merge(params)
|
11
|
+
self.collection = []
|
12
|
+
self.url = resource_path
|
13
|
+
end
|
14
|
+
|
15
|
+
def count
|
16
|
+
collection.length
|
17
|
+
end
|
18
|
+
|
19
|
+
def each
|
20
|
+
collection.each { |instance| yield instance }
|
21
|
+
end
|
22
|
+
|
23
|
+
def fetch
|
24
|
+
self.collection = []
|
25
|
+
fetch_page
|
26
|
+
self
|
27
|
+
end
|
28
|
+
|
29
|
+
def fetch_page
|
30
|
+
RestClient.get(url, Config.headers) do |response, request, result|
|
31
|
+
case response.code
|
32
|
+
when 200
|
33
|
+
parsed_response = JSON.parse(response)
|
34
|
+
self.next_url = parsed_response["next"]
|
35
|
+
self.previous_url = parsed_response["previous"]
|
36
|
+
parsed_response["results"].each do |resource|
|
37
|
+
collection << resource_builder.call(resource)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def less?
|
44
|
+
!!previous_url
|
45
|
+
end
|
46
|
+
|
47
|
+
def more?
|
48
|
+
!!next_url
|
49
|
+
end
|
50
|
+
|
51
|
+
def next
|
52
|
+
raise "no more results" unless more?
|
53
|
+
self.url = next_url
|
54
|
+
fetch
|
55
|
+
end
|
56
|
+
|
57
|
+
def page_number
|
58
|
+
params.fetch(:page, 1).to_i
|
59
|
+
end
|
60
|
+
|
61
|
+
def previous
|
62
|
+
raise "no more results" unless less?
|
63
|
+
self.url = previous_url
|
64
|
+
fetch
|
65
|
+
end
|
66
|
+
|
67
|
+
def resource_path
|
68
|
+
URI.join(resource_url, "?#{URI.encode_www_form(params)}").to_s
|
69
|
+
end
|
70
|
+
|
71
|
+
end
|
72
|
+
end
|
@@ -0,0 +1,171 @@
|
|
1
|
+
module LightSide
|
2
|
+
module Resources
|
3
|
+
|
4
|
+
def initialize(hash={})
|
5
|
+
set_attributes_from_hash(hash)
|
6
|
+
end
|
7
|
+
|
8
|
+
def attributes
|
9
|
+
self.class.attributes.inject({}) do |memo, attr|
|
10
|
+
memo.merge(attr => self.__send__(attr))
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
def delete
|
15
|
+
self.class.delete_resource(id)
|
16
|
+
end
|
17
|
+
|
18
|
+
def id
|
19
|
+
url && url.split("/").last
|
20
|
+
end
|
21
|
+
|
22
|
+
def reload
|
23
|
+
self.class.resource(id) do |hash|
|
24
|
+
set_attributes_from_hash(hash)
|
25
|
+
end
|
26
|
+
self
|
27
|
+
end
|
28
|
+
|
29
|
+
def update
|
30
|
+
save
|
31
|
+
end
|
32
|
+
|
33
|
+
def save
|
34
|
+
json = JSON.generate(writable_attributes)
|
35
|
+
if id
|
36
|
+
self.class.update_resource(id, json) { |hash| set_attributes_from_hash(hash) }
|
37
|
+
else
|
38
|
+
self.class.create_resource(json) { |hash| set_attributes_from_hash(hash) }
|
39
|
+
end
|
40
|
+
self
|
41
|
+
end
|
42
|
+
|
43
|
+
def set_attributes_from_hash(hash)
|
44
|
+
self.class.attributes.each do |attr|
|
45
|
+
self.__send__("#{attr.to_s}=", hash.fetch(attr, nil))
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
def to_s
|
50
|
+
%w(id url errors).map(&:to_sym).inject("#{self.class.name}") do |memo, attr|
|
51
|
+
val = self.__send__(attr)
|
52
|
+
memo << " #{attr}:#{val}" if val
|
53
|
+
memo
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def writable_attributes
|
58
|
+
self.class.writable_attributes.inject({}) do |memo, attr|
|
59
|
+
memo.merge(attr => self.__send__(attr))
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def self.included(base)
|
64
|
+
base.extend(ClassMethods)
|
65
|
+
base.singleton_class.class_eval { attr_accessor :resource_base, :readonly_attributes, :writable_attributes }
|
66
|
+
end
|
67
|
+
|
68
|
+
module ClassMethods
|
69
|
+
def all
|
70
|
+
resources
|
71
|
+
end
|
72
|
+
|
73
|
+
def attributes
|
74
|
+
@readonly_attributes.to_a + @writable_attributes.to_a + ["errors"]
|
75
|
+
end
|
76
|
+
|
77
|
+
def create(data)
|
78
|
+
create_resource(data) { |hash| new(hash) }
|
79
|
+
end
|
80
|
+
|
81
|
+
def create_resource(data)
|
82
|
+
RestClient.post(resource_url, data, Config.headers) do |response, request, result|
|
83
|
+
case response.code
|
84
|
+
when 201
|
85
|
+
yield JSON.parse(response)
|
86
|
+
when 400
|
87
|
+
yield JSON.parse(data).merge!("errors" => JSON.parse(response))
|
88
|
+
else
|
89
|
+
raise response
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
def delete(id)
|
95
|
+
delete_resource(id)
|
96
|
+
end
|
97
|
+
|
98
|
+
def delete_resource(id)
|
99
|
+
RestClient.delete(resource_url(id), Config.headers) do |response, request, result|
|
100
|
+
case response.code
|
101
|
+
when 204
|
102
|
+
return true
|
103
|
+
when 404
|
104
|
+
raise ResourceNotFound, "could not find #{name} with ID=#{id}"
|
105
|
+
else
|
106
|
+
raise response
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
def find(id)
|
112
|
+
resource(id) { |hash| new(hash) }
|
113
|
+
end
|
114
|
+
|
115
|
+
def page(page_num)
|
116
|
+
LightSide::Pager.new(self, { page: Integer(page_num) }).fetch
|
117
|
+
end
|
118
|
+
|
119
|
+
def query(query_params)
|
120
|
+
resources(query_params)
|
121
|
+
end
|
122
|
+
|
123
|
+
def resource_url(id=nil)
|
124
|
+
raise LightSide::NotConfigured unless Config.configured?
|
125
|
+
[Config.base_url, "#{resource_base}/#{id}"].join("/")
|
126
|
+
end
|
127
|
+
|
128
|
+
def resources(params={})
|
129
|
+
LightSide::Pager.new(self, params).fetch
|
130
|
+
end
|
131
|
+
|
132
|
+
def resource(id)
|
133
|
+
RestClient.get(resource_url(id), Config.headers) do |response, request, result|
|
134
|
+
case response.code
|
135
|
+
when 200
|
136
|
+
yield JSON.parse(response)
|
137
|
+
when 404
|
138
|
+
raise ResourceNotFound, "could not find #{name} with ID=#{id}"
|
139
|
+
else
|
140
|
+
raise response
|
141
|
+
end
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
def setup
|
146
|
+
yield
|
147
|
+
attributes.each { |attr| attr_accessor attr.to_s }
|
148
|
+
end
|
149
|
+
|
150
|
+
def update(id, data)
|
151
|
+
update_resource(id, data) { |hash| new(hash) }
|
152
|
+
end
|
153
|
+
|
154
|
+
def update_resource(id, data)
|
155
|
+
RestClient.put(resource_url(id), data, Config.headers) do |response, request, result|
|
156
|
+
case response.code
|
157
|
+
when 200
|
158
|
+
yield JSON.parse(response)
|
159
|
+
when 400
|
160
|
+
yield ({"errors" => JSON.parse(response)})
|
161
|
+
when 404
|
162
|
+
raise ResourceNotFound, "could not find #{name} with ID=#{id}"
|
163
|
+
else
|
164
|
+
raise response
|
165
|
+
end
|
166
|
+
end
|
167
|
+
end
|
168
|
+
end
|
169
|
+
|
170
|
+
end
|
171
|
+
end
|
data/lightside.gemspec
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
require File.expand_path('../lib/lightside/version', __FILE__)
|
2
|
+
|
3
|
+
Gem::Specification.new do |s|
|
4
|
+
s.name = 'lightside'
|
5
|
+
s.version = LightSide::VERSION
|
6
|
+
s.date = '2013-12-02'
|
7
|
+
s.summary = 'LightSide API'
|
8
|
+
s.description = 'Ruby wrapper for LightSide Web API'
|
9
|
+
s.authors = ['Tom Head']
|
10
|
+
s.email = 'tom.head@revolutionprep.com'
|
11
|
+
s.homepage = 'http://github.com/RevolutionK12/lightside'
|
12
|
+
s.files = `git ls-files`.split("\n")
|
13
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
14
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
15
|
+
s.homepage = ""
|
16
|
+
s.license = 'MIT'
|
17
|
+
s.require_paths = ["lib"]
|
18
|
+
|
19
|
+
s.add_dependency 'rest-client'
|
20
|
+
|
21
|
+
s.add_development_dependency 'rspec'
|
22
|
+
s.add_development_dependency 'webmock'
|
23
|
+
s.add_development_dependency 'pry'
|
24
|
+
s.add_development_dependency 'pry-nav'
|
25
|
+
s.add_development_dependency 'guard'
|
26
|
+
s.add_development_dependency 'guard-rspec'
|
27
|
+
end
|
data/spec/config_spec.rb
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe LightSide::Config do
|
4
|
+
let(:auth_token) { "abc123" }
|
5
|
+
let(:base_url) { "https://api.example.com/api/" }
|
6
|
+
|
7
|
+
it "can set auth_token" do
|
8
|
+
LightSide.configure do |config|
|
9
|
+
config.auth_token = auth_token
|
10
|
+
end
|
11
|
+
expect( LightSide::Config.auth_token ).to eq auth_token
|
12
|
+
end
|
13
|
+
|
14
|
+
it "can set base_url" do
|
15
|
+
LightSide.configure do |config|
|
16
|
+
config.base_url = base_url
|
17
|
+
end
|
18
|
+
expect( LightSide::Config.base_url ).to eq base_url
|
19
|
+
end
|
20
|
+
|
21
|
+
context ".configured?" do
|
22
|
+
context "when auth_token is missing" do
|
23
|
+
it "returns false" do
|
24
|
+
LightSide::Config.auth_token = nil
|
25
|
+
expect( LightSide::Config.configured? ).to be_false
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
context "when base_url is missing" do
|
30
|
+
it "returns false" do
|
31
|
+
LightSide::Config.base_url = nil
|
32
|
+
expect( LightSide::Config.configured? ).to be_false
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
{"count": 2, "next": null, "previous": null, "results": [{"url": "https://api.example.com/api/prompts/2", "owner": 2, "parent": null, "title": "ASAP Dataset #2: Persuasive Essay on Censorship", "text": "ASAP Dataset #2: Persuasive Essay on Censorship", "instructions": "", "description": "<blockquote>\"All of us can think of a book that we hope none of our children or any other children have taken off the shelf. But if I have the right to remove that book from the shelf -- that work I abhor -- then you also have exactly the same right and so does everyone else. And then we have no books left on the shelf for any of us.\" <footer>— Katherine Paterson, Author</footer></blockquote>\r\n\r\n<p>Write a persuasive essay to a newspaper reflecting your vies on censorship in libraries. Do you believe that certain materials, such as books, music, movies, magazines, etc., should be removed from the shelves if they are found offensive? Support your position with convincing arguments from your own experience, observations, and/or reading.</p>", "lower": null, "upper": null, "alignments": "", "default_models": ["https://api.example.com/api/trained-models/2", "https://api.example.com/api/trained-models/3"], "tags": [], "corpora": ["https://api.example.com/api/corpora/2"], "answer_sets": ["https://api.example.com/api/answer-sets/2"], "active": true, "created": "2013-10-03T00:00:00", "modified": "2013-10-03T00:00:00"}, {"url": "https://api.example.com/api/prompts/1", "owner": 2, "parent": null, "title": "ASAP Dataset #1: Persuasive Essay on Computers", "text": "ASAP Dataset #1: Persuasive Essay on Computers", "instructions": "", "description": "More and more people use computers, but not everyone agrees that this benefits society. Those who support advances in technology believe that computers have a positive effect on people. They teach hand-eye coordination, give people the ability to learn about faraway places and people, and even allow people to talk online with other people. Others have different ideas. Some experts are concerned that people are spending too much time on their computers and less time exercising, enjoying nature, and interacting with family and friends. \n\nWrite a letter to your local newspaper in which you state your opinion on the effects computers have on people. Persuade the readers to agree with you.", "lower": null, "upper": null, "alignments": "", "default_models": ["https://api.example.com/api/trained-models/1"], "tags": [], "corpora": ["https://api.example.com/api/corpora/1"], "answer_sets": ["https://api.example.com/api/answer-sets/1"], "active": true, "created": "2013-10-03T00:00:00", "modified": "2013-10-03T00:00:00"}]}
|
@@ -0,0 +1 @@
|
|
1
|
+
{"url": "https://api.example.com/api/prompts/2", "owner": 2, "parent": null, "title": "ASAP Dataset #2: Persuasive Essay on Censorship", "text": "ASAP Dataset #2: Persuasive Essay on Censorship", "instructions": "", "description": "<blockquote>\"All of us can think of a book that we hope none of our children or any other children have taken off the shelf. But if I have the right to remove that book from the shelf -- that work I abhor -- then you also have exactly the same right and so does everyone else. And then we have no books left on the shelf for any of us.\" <footer>— Katherine Paterson, Author</footer></blockquote>\r\n\r\n<p>Write a persuasive essay to a newspaper reflecting your vies on censorship in libraries. Do you believe that certain materials, such as books, music, movies, magazines, etc., should be removed from the shelves if they are found offensive? Support your position with convincing arguments from your own experience, observations, and/or reading.</p>", "lower": null, "upper": null, "alignments": "", "default_models": ["https://api.example.com/api/trained-models/2", "https://api.example.com/api/trained-models/3"], "tags": [], "corpora": ["https://api.example.com/api/corpora/2"], "answer_sets": ["https://api.example.com/api/answer-sets/2"], "active": true, "created": "2013-10-03T00:00:00", "modified": "2013-10-03T00:00:00"}
|
@@ -0,0 +1 @@
|
|
1
|
+
{"count": 2, "next": "https://api.example.com/api/prompts/?page=2", "previous": null, "results": [{"url": "https://api.example.com/api/prompts/2", "owner": 2, "parent": null, "title": "ASAP Dataset #2: Persuasive Essay on Censorship", "text": "ASAP Dataset #2: Persuasive Essay on Censorship", "instructions": "", "description": "<blockquote>\"All of us can think of a book that we hope none of our children or any other children have taken off the shelf. But if I have the right to remove that book from the shelf -- that work I abhor -- then you also have exactly the same right and so does everyone else. And then we have no books left on the shelf for any of us.\" <footer>— Katherine Paterson, Author</footer></blockquote>\r\n\r\n<p>Write a persuasive essay to a newspaper reflecting your vies on censorship in libraries. Do you believe that certain materials, such as books, music, movies, magazines, etc., should be removed from the shelves if they are found offensive? Support your position with convincing arguments from your own experience, observations, and/or reading.</p>", "lower": null, "upper": null, "alignments": "", "default_models": ["https://api.example.com/api/trained-models/2", "https://api.example.com/api/trained-models/3"], "tags": [], "corpora": ["https://api.example.com/api/corpora/2"], "answer_sets": ["https://api.example.com/api/answer-sets/2"], "active": true, "created": "2013-10-03T00:00:00", "modified": "2013-10-03T00:00:00"}, {"url": "https://api.example.com/api/prompts/1", "owner": 2, "parent": null, "title": "ASAP Dataset #1: Persuasive Essay on Computers", "text": "ASAP Dataset #1: Persuasive Essay on Computers", "instructions": "", "description": "More and more people use computers, but not everyone agrees that this benefits society. Those who support advances in technology believe that computers have a positive effect on people. They teach hand-eye coordination, give people the ability to learn about faraway places and people, and even allow people to talk online with other people. Others have different ideas. Some experts are concerned that people are spending too much time on their computers and less time exercising, enjoying nature, and interacting with family and friends. \n\nWrite a letter to your local newspaper in which you state your opinion on the effects computers have on people. Persuade the readers to agree with you.", "lower": null, "upper": null, "alignments": "", "default_models": ["https://api.example.com/api/trained-models/1"], "tags": [], "corpora": ["https://api.example.com/api/corpora/1"], "answer_sets": ["https://api.example.com/api/answer-sets/1"], "active": true, "created": "2013-10-03T00:00:00", "modified": "2013-10-03T00:00:00"}]}
|
@@ -0,0 +1 @@
|
|
1
|
+
{"count": 2, "next": "https://api.example.com/api/prompts/?page=2", "previous": "https://api.example.com/api/prompts/?page=1", "results": [{"url": "https://api.example.com/api/prompts/2", "owner": 2, "parent": null, "title": "ASAP Dataset #2: Persuasive Essay on Censorship", "text": "ASAP Dataset #2: Persuasive Essay on Censorship", "instructions": "", "description": "<blockquote>\"All of us can think of a book that we hope none of our children or any other children have taken off the shelf. But if I have the right to remove that book from the shelf -- that work I abhor -- then you also have exactly the same right and so does everyone else. And then we have no books left on the shelf for any of us.\" <footer>— Katherine Paterson, Author</footer></blockquote>\r\n\r\n<p>Write a persuasive essay to a newspaper reflecting your vies on censorship in libraries. Do you believe that certain materials, such as books, music, movies, magazines, etc., should be removed from the shelves if they are found offensive? Support your position with convincing arguments from your own experience, observations, and/or reading.</p>", "lower": null, "upper": null, "alignments": "", "default_models": ["https://api.example.com/api/trained-models/2", "https://api.example.com/api/trained-models/3"], "tags": [], "corpora": ["https://api.example.com/api/corpora/2"], "answer_sets": ["https://api.example.com/api/answer-sets/2"], "active": true, "created": "2013-10-03T00:00:00", "modified": "2013-10-03T00:00:00"}, {"url": "https://api.example.com/api/prompts/1", "owner": 2, "parent": null, "title": "ASAP Dataset #1: Persuasive Essay on Computers", "text": "ASAP Dataset #1: Persuasive Essay on Computers", "instructions": "", "description": "More and more people use computers, but not everyone agrees that this benefits society. Those who support advances in technology believe that computers have a positive effect on people. They teach hand-eye coordination, give people the ability to learn about faraway places and people, and even allow people to talk online with other people. Others have different ideas. Some experts are concerned that people are spending too much time on their computers and less time exercising, enjoying nature, and interacting with family and friends. \n\nWrite a letter to your local newspaper in which you state your opinion on the effects computers have on people. Persuade the readers to agree with you.", "lower": null, "upper": null, "alignments": "", "default_models": ["https://api.example.com/api/trained-models/1"], "tags": [], "corpora": ["https://api.example.com/api/corpora/1"], "answer_sets": ["https://api.example.com/api/answer-sets/1"], "active": true, "created": "2013-10-03T00:00:00", "modified": "2013-10-03T00:00:00"}]}
|
@@ -0,0 +1 @@
|
|
1
|
+
{"count": 2, "next": null, "previous": "https://api.example.com/api/prompts/?page=2", "results": [{"url": "https://api.example.com/api/prompts/2", "owner": 2, "parent": null, "title": "ASAP Dataset #2: Persuasive Essay on Censorship", "text": "ASAP Dataset #2: Persuasive Essay on Censorship", "instructions": "", "description": "<blockquote>\"All of us can think of a book that we hope none of our children or any other children have taken off the shelf. But if I have the right to remove that book from the shelf -- that work I abhor -- then you also have exactly the same right and so does everyone else. And then we have no books left on the shelf for any of us.\" <footer>— Katherine Paterson, Author</footer></blockquote>\r\n\r\n<p>Write a persuasive essay to a newspaper reflecting your vies on censorship in libraries. Do you believe that certain materials, such as books, music, movies, magazines, etc., should be removed from the shelves if they are found offensive? Support your position with convincing arguments from your own experience, observations, and/or reading.</p>", "lower": null, "upper": null, "alignments": "", "default_models": ["https://api.example.com/api/trained-models/2", "https://api.example.com/api/trained-models/3"], "tags": [], "corpora": ["https://api.example.com/api/corpora/2"], "answer_sets": ["https://api.example.com/api/answer-sets/2"], "active": true, "created": "2013-10-03T00:00:00", "modified": "2013-10-03T00:00:00"}, {"url": "https://api.example.com/api/prompts/1", "owner": 2, "parent": null, "title": "ASAP Dataset #1: Persuasive Essay on Computers", "text": "ASAP Dataset #1: Persuasive Essay on Computers", "instructions": "", "description": "More and more people use computers, but not everyone agrees that this benefits society. Those who support advances in technology believe that computers have a positive effect on people. They teach hand-eye coordination, give people the ability to learn about faraway places and people, and even allow people to talk online with other people. Others have different ideas. Some experts are concerned that people are spending too much time on their computers and less time exercising, enjoying nature, and interacting with family and friends. \n\nWrite a letter to your local newspaper in which you state your opinion on the effects computers have on people. Persuade the readers to agree with you.", "lower": null, "upper": null, "alignments": "", "default_models": ["https://api.example.com/api/trained-models/1"], "tags": [], "corpora": ["https://api.example.com/api/corpora/1"], "answer_sets": ["https://api.example.com/api/answer-sets/1"], "active": true, "created": "2013-10-03T00:00:00", "modified": "2013-10-03T00:00:00"}]}
|
@@ -0,0 +1 @@
|
|
1
|
+
{"count": 2, "next": "https://api.example.com/api/prompts/?page=2&all=true", "previous": "https://api.example.com/api/prompts/?page=1&all=true", "results": [{"url": "https://api.example.com/api/prompts/2", "owner": 2, "parent": null, "title": "ASAP Dataset #2: Persuasive Essay on Censorship", "text": "ASAP Dataset #2: Persuasive Essay on Censorship", "instructions": "", "description": "<blockquote>\"All of us can think of a book that we hope none of our children or any other children have taken off the shelf. But if I have the right to remove that book from the shelf -- that work I abhor -- then you also have exactly the same right and so does everyone else. And then we have no books left on the shelf for any of us.\" <footer>— Katherine Paterson, Author</footer></blockquote>\r\n\r\n<p>Write a persuasive essay to a newspaper reflecting your vies on censorship in libraries. Do you believe that certain materials, such as books, music, movies, magazines, etc., should be removed from the shelves if they are found offensive? Support your position with convincing arguments from your own experience, observations, and/or reading.</p>", "lower": null, "upper": null, "alignments": "", "default_models": ["https://api.example.com/api/trained-models/2", "https://api.example.com/api/trained-models/3"], "tags": [], "corpora": ["https://api.example.com/api/corpora/2"], "answer_sets": ["https://api.example.com/api/answer-sets/2"], "active": true, "created": "2013-10-03T00:00:00", "modified": "2013-10-03T00:00:00"}, {"url": "https://api.example.com/api/prompts/1", "owner": 2, "parent": null, "title": "ASAP Dataset #1: Persuasive Essay on Computers", "text": "ASAP Dataset #1: Persuasive Essay on Computers", "instructions": "", "description": "More and more people use computers, but not everyone agrees that this benefits society. Those who support advances in technology believe that computers have a positive effect on people. They teach hand-eye coordination, give people the ability to learn about faraway places and people, and even allow people to talk online with other people. Others have different ideas. Some experts are concerned that people are spending too much time on their computers and less time exercising, enjoying nature, and interacting with family and friends. \n\nWrite a letter to your local newspaper in which you state your opinion on the effects computers have on people. Persuade the readers to agree with you.", "lower": null, "upper": null, "alignments": "", "default_models": ["https://api.example.com/api/trained-models/1"], "tags": [], "corpora": ["https://api.example.com/api/corpora/1"], "answer_sets": ["https://api.example.com/api/answer-sets/1"], "active": true, "created": "2013-10-03T00:00:00", "modified": "2013-10-03T00:00:00"}]}
|
data/spec/pager_spec.rb
ADDED
@@ -0,0 +1,104 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe LightSide::Pager do
|
4
|
+
let(:auth_token) { "abc123" }
|
5
|
+
let(:base_url) { "https://api.example.com/api" }
|
6
|
+
let(:headers) { {
|
7
|
+
"Accept" => "*/*; q=0.5, application/xml",
|
8
|
+
"Accept-Encoding" => "gzip, deflate",
|
9
|
+
"Authorization" => "Token #{auth_token}",
|
10
|
+
"Content-Type" => "application/json",
|
11
|
+
"User-Agent" => "Ruby"
|
12
|
+
} }
|
13
|
+
|
14
|
+
before do
|
15
|
+
LightSide.configure do |config|
|
16
|
+
config.auth_token = auth_token
|
17
|
+
config.base_url = base_url
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
context "when url is not supplied" do
|
22
|
+
let(:page_url) { "https://api.example.com/api/prompts/?page=1" }
|
23
|
+
let(:pager) { LightSide::Pager.new(LightSide::Prompt) }
|
24
|
+
|
25
|
+
it "starts at page 1" do
|
26
|
+
expect(pager.page_number).to eq 1
|
27
|
+
expect(pager.resource_path).to eq page_url
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
context "when retrieving by page number" do
|
32
|
+
let(:path) { "https://api.example.com/api/prompts/" }
|
33
|
+
let(:pager) { LightSide::Pager.new(LightSide::Prompt, params) }
|
34
|
+
|
35
|
+
context "without query params" do
|
36
|
+
let(:params) { {page: 2} }
|
37
|
+
let(:response_body) { File.new("spec/fixtures/prompts_2.json") }
|
38
|
+
|
39
|
+
before do
|
40
|
+
stub_request(:get, "#{base_url}/prompts/?page=2").with(:headers => headers).
|
41
|
+
to_return(:status => 200, :body => response_body, :headers => {})
|
42
|
+
end
|
43
|
+
|
44
|
+
it "starts at page 2" do
|
45
|
+
expect(pager.page_number).to eq 2
|
46
|
+
end
|
47
|
+
|
48
|
+
it "sets the next url" do
|
49
|
+
pager.fetch
|
50
|
+
expect(pager.next_url).to eq "#{base_url}/prompts/?page=2"
|
51
|
+
expect(pager.collection.map(&:class)).to eq [LightSide::Prompt]*2
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
context "with query params" do
|
56
|
+
let(:params) { {page: 2, all: true} }
|
57
|
+
let(:response_body) { File.new("spec/fixtures/prompts_4.json") }
|
58
|
+
|
59
|
+
before do
|
60
|
+
stub_request(:get, "#{base_url}/prompts/?page=2&all=true").with(:headers => headers).
|
61
|
+
to_return(:status => 200, :body => response_body, :headers => {})
|
62
|
+
end
|
63
|
+
|
64
|
+
it "starts at page 2" do
|
65
|
+
expect(pager.page_number).to eq 2
|
66
|
+
end
|
67
|
+
|
68
|
+
it "sets the next url" do
|
69
|
+
pager.fetch
|
70
|
+
expect(pager.next_url).to eq "#{base_url}/prompts/?page=2&all=true"
|
71
|
+
expect(pager.collection.map(&:class)).to eq [LightSide::Prompt]*2
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
context "#next" do
|
76
|
+
let(:params) { {page: 2} }
|
77
|
+
let(:response_body) { File.new("spec/fixtures/prompts_2.json") }
|
78
|
+
|
79
|
+
context "when next_url is missing" do
|
80
|
+
it "raises an exception" do
|
81
|
+
expect(pager.page_number).to eq 2
|
82
|
+
expect(pager.next_url).to be_nil
|
83
|
+
expect { pager.next }.to raise_error("no more results")
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
context "when next_url is present" do
|
88
|
+
let(:response_body_2) { File.new("spec/fixtures/prompts_3.json") }
|
89
|
+
let(:page_3_url) { "#{base_url}/prompts/?page=3" }
|
90
|
+
|
91
|
+
before do
|
92
|
+
stub_request(:get, "#{base_url}/prompts/?page=3").with(:headers => headers).
|
93
|
+
to_return(:status => 200, :body => response_body_2, :headers => {})
|
94
|
+
end
|
95
|
+
|
96
|
+
it "fetches the next set of results" do
|
97
|
+
pager.next_url = page_3_url
|
98
|
+
pager.next
|
99
|
+
expect(pager.collection).not_to be_empty
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
@@ -0,0 +1,228 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe LightSide::Resources do
|
4
|
+
let(:auth_token) { "abc123" }
|
5
|
+
let(:base_url) { "https://api.example.com/api" }
|
6
|
+
let(:prompts) { LightSide::Prompt.all }
|
7
|
+
let(:prompt) { prompts.first }
|
8
|
+
let(:headers) { {
|
9
|
+
"Accept" => "*/*; q=0.5, application/xml",
|
10
|
+
"Accept-Encoding" => "gzip, deflate",
|
11
|
+
"Authorization" => "Token #{auth_token}",
|
12
|
+
"Content-Type" => "application/json",
|
13
|
+
"User-Agent" => "Ruby"
|
14
|
+
} }
|
15
|
+
|
16
|
+
before do
|
17
|
+
LightSide.configure do |config|
|
18
|
+
config.auth_token = auth_token
|
19
|
+
config.base_url = base_url
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
context ".all" do
|
24
|
+
let(:response_body) { File.new("spec/fixtures/prompts.json") }
|
25
|
+
|
26
|
+
before do
|
27
|
+
stub_request(:get, "#{base_url}/prompts/?page=1").with(:headers => headers).
|
28
|
+
to_return(:status => 200, :body => response_body, :headers => {})
|
29
|
+
end
|
30
|
+
|
31
|
+
it "gets the first page of prompts" do
|
32
|
+
expect(prompts).to be_kind_of(LightSide::Pager)
|
33
|
+
expect(prompts.count).to eq 2
|
34
|
+
expect(prompt).to be_kind_of(LightSide::Prompt)
|
35
|
+
expect(prompt.url).to eq "https://api.example.com/api/prompts/2"
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
context ".page" do
|
40
|
+
let(:response_body) { File.new("spec/fixtures/prompts.json") }
|
41
|
+
|
42
|
+
before do
|
43
|
+
stub_request(:get, "#{base_url}/prompts/?page=2").with(:headers => headers).
|
44
|
+
to_return(:status => 200, :body => response_body, :headers => {})
|
45
|
+
end
|
46
|
+
|
47
|
+
context "when requesting without a page number" do
|
48
|
+
let(:prompts) { LightSide::Prompt.page }
|
49
|
+
it "raises an exception" do
|
50
|
+
expect { prompts }.to raise_error
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
context "when requesting with page number nil" do
|
55
|
+
let(:prompts) { LightSide::Prompt.page(nil) }
|
56
|
+
it "raises an exception" do
|
57
|
+
expect { prompts }.to raise_error
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
context "when requesting with page number 2" do
|
62
|
+
let(:prompts) { LightSide::Prompt.page(2) }
|
63
|
+
it "returns the second page of results" do
|
64
|
+
expect(prompts.collection.map(&:class)).to eq [LightSide::Prompt]*2
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
context ".find" do
|
70
|
+
context "with a valid ID" do
|
71
|
+
let(:response_body) { File.new("spec/fixtures/prompts/2.json") }
|
72
|
+
let(:prompt) { LightSide::Prompt.find(2) }
|
73
|
+
|
74
|
+
before do
|
75
|
+
stub_request(:get, "#{base_url}/prompts/2").
|
76
|
+
with(:headers => headers).
|
77
|
+
to_return(:status => 200, :body => response_body, :headers => {})
|
78
|
+
end
|
79
|
+
|
80
|
+
it "finds a prompt by its id" do
|
81
|
+
expect(prompt).to be_kind_of(LightSide::Prompt)
|
82
|
+
expect(prompt.url).to eq "https://api.example.com/api/prompts/2"
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
context "with an invalid ID" do
|
87
|
+
let(:prompt) { LightSide::Prompt.find(99) }
|
88
|
+
|
89
|
+
before do
|
90
|
+
stub_request(:get, "#{base_url}/prompts/99").with(:headers => headers).
|
91
|
+
to_return(:status => 404, :body => "", :headers => {})
|
92
|
+
end
|
93
|
+
|
94
|
+
it "raises an exception" do
|
95
|
+
expect { prompt }.to raise_error(LightSide::ResourceNotFound)
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
context ".create" do
|
101
|
+
context "with valid input" do
|
102
|
+
let(:response_body) { File.new("spec/fixtures/prompts/2.json") }
|
103
|
+
let(:data) { JSON.generate({
|
104
|
+
"title" => "new prompt title",
|
105
|
+
"text" => "This is the text of the prompt.",
|
106
|
+
"description" => "This prompt is an example.",
|
107
|
+
"lower" => nil,
|
108
|
+
"upper" => nil,
|
109
|
+
"default_models" => [],
|
110
|
+
"tags" => ["example", "period 2"]
|
111
|
+
}) }
|
112
|
+
|
113
|
+
before do
|
114
|
+
headers.merge!('Content-Length' => data.length)
|
115
|
+
stub_request(:post, "#{base_url}/prompts/").with(:headers => headers).
|
116
|
+
to_return(:status => 201, :body => response_body, :headers => {})
|
117
|
+
end
|
118
|
+
|
119
|
+
it "creates a prompt" do
|
120
|
+
prompt = LightSide::Prompt.create(data)
|
121
|
+
expect(prompt.url).to eq "https://api.example.com/api/prompts/2"
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
context "with invalid input" do
|
126
|
+
let(:error_hash) { {"text"=>["This field is required."], "title"=>["This field is required."]} }
|
127
|
+
let(:response_body) { JSON.generate(error_hash) }
|
128
|
+
let(:data) { JSON.generate({}) }
|
129
|
+
|
130
|
+
before do
|
131
|
+
headers.merge!('Content-Length' => data.length)
|
132
|
+
stub_request(:post, "#{base_url}/prompts/").with(:headers => headers).
|
133
|
+
to_return(:status => 400, :body => response_body, :headers => {})
|
134
|
+
end
|
135
|
+
|
136
|
+
it "returns an unsaved prompt and populates its error hash" do
|
137
|
+
prompt = LightSide::Prompt.create(data)
|
138
|
+
expect(prompt.errors).to eq error_hash
|
139
|
+
end
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
context ".update" do
|
144
|
+
context "with valid ID and input" do
|
145
|
+
let(:response_body) { File.new("spec/fixtures/prompts/2.json") }
|
146
|
+
let(:data) { JSON.generate({
|
147
|
+
"title" => "new prompt title",
|
148
|
+
"text" => "This is the text of the prompt.",
|
149
|
+
"description" => "This prompt is an example.",
|
150
|
+
"lower" => nil,
|
151
|
+
"upper" => nil,
|
152
|
+
"default_models" => [],
|
153
|
+
"tags" => ["example", "period 2"]
|
154
|
+
}) }
|
155
|
+
|
156
|
+
before do
|
157
|
+
headers.merge!('Content-Length' => data.length)
|
158
|
+
stub_request(:put, "#{base_url}/prompts/2").with(:headers => headers).
|
159
|
+
with(:body => data).
|
160
|
+
to_return(:status => 200, :body => response_body, :headers => {})
|
161
|
+
end
|
162
|
+
|
163
|
+
it "updates the prompt" do
|
164
|
+
prompt = LightSide::Prompt.update(2, data)
|
165
|
+
expect(prompt.url).to eq "https://api.example.com/api/prompts/2"
|
166
|
+
end
|
167
|
+
end
|
168
|
+
|
169
|
+
context "with valid ID and invalid input" do
|
170
|
+
let(:error_hash) { {"text"=>["This field is required."], "title"=>["This field is required."]} }
|
171
|
+
let(:response_body) { JSON.generate(error_hash) }
|
172
|
+
let(:data) { JSON.generate({}) }
|
173
|
+
|
174
|
+
before do
|
175
|
+
headers.merge!('Content-Length' => data.length)
|
176
|
+
stub_request(:put, "#{base_url}/prompts/2").with(:headers => headers).
|
177
|
+
with(:body => data).
|
178
|
+
to_return(:status => 400, :body => response_body, :headers => {})
|
179
|
+
end
|
180
|
+
|
181
|
+
it "return the prompt without updating and populates its error hash" do
|
182
|
+
prompt = LightSide::Prompt.update(2, data)
|
183
|
+
expect(prompt.errors).to eq error_hash
|
184
|
+
end
|
185
|
+
end
|
186
|
+
|
187
|
+
context "with invalid ID" do
|
188
|
+
let(:data) { JSON.generate({}) }
|
189
|
+
let(:prompt) { LightSide::Prompt.update(99, data) }
|
190
|
+
|
191
|
+
before do
|
192
|
+
headers.merge!('Content-Length' => data.length)
|
193
|
+
stub_request(:put, "#{base_url}/prompts/99").with(:headers => headers).
|
194
|
+
with(:body => data).
|
195
|
+
to_return(:status => 404, :body => "", :headers => {})
|
196
|
+
end
|
197
|
+
|
198
|
+
it "raises an exception" do
|
199
|
+
expect { prompt }.to raise_error(LightSide::ResourceNotFound)
|
200
|
+
end
|
201
|
+
end
|
202
|
+
end
|
203
|
+
|
204
|
+
context ".delete" do
|
205
|
+
context "with valid ID" do
|
206
|
+
before do
|
207
|
+
stub_request(:delete, "#{base_url}/prompts/2").with(:headers => headers).
|
208
|
+
to_return(:status => 204, :body => "", :headers => {})
|
209
|
+
end
|
210
|
+
|
211
|
+
it "returns true" do
|
212
|
+
expect(LightSide::Prompt.delete(2)).to eq true
|
213
|
+
end
|
214
|
+
end
|
215
|
+
|
216
|
+
context "with invalid ID" do
|
217
|
+
before do
|
218
|
+
stub_request(:delete, "#{base_url}/prompts/99").with(:headers => headers).
|
219
|
+
to_return(:status => 404, :body => "", :headers => {})
|
220
|
+
end
|
221
|
+
|
222
|
+
it "raises an exception" do
|
223
|
+
expect { LightSide::Prompt.delete(99) }.to raise_error(LightSide::ResourceNotFound)
|
224
|
+
end
|
225
|
+
end
|
226
|
+
end
|
227
|
+
|
228
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
# This file was generated by the `rspec --init` command. Conventionally, all
|
2
|
+
# specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
|
3
|
+
# Require this file using `require "spec_helper"` to ensure that it is only
|
4
|
+
# loaded once.
|
5
|
+
#
|
6
|
+
# See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
|
7
|
+
RSpec.configure do |config|
|
8
|
+
config.treat_symbols_as_metadata_keys_with_true_values = true
|
9
|
+
config.run_all_when_everything_filtered = true
|
10
|
+
config.filter_run :focus
|
11
|
+
|
12
|
+
# Run specs in random order to surface order dependencies. If you find an
|
13
|
+
# order dependency and want to debug it, you can fix the order by providing
|
14
|
+
# the seed, which is printed after each run.
|
15
|
+
# --seed 1234
|
16
|
+
config.order = 'random'
|
17
|
+
end
|
18
|
+
|
19
|
+
require 'webmock/rspec'
|
20
|
+
WebMock.disable_net_connect!
|
21
|
+
|
22
|
+
require 'lightside'
|
metadata
ADDED
@@ -0,0 +1,206 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: lightside
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Tom Head
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2013-12-02 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: rest-client
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ! '>='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '0'
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: rspec
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ! '>='
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '0'
|
38
|
+
type: :development
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '0'
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: webmock
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ! '>='
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '0'
|
54
|
+
type: :development
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ! '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
- !ruby/object:Gem::Dependency
|
63
|
+
name: pry
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
66
|
+
requirements:
|
67
|
+
- - ! '>='
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '0'
|
70
|
+
type: :development
|
71
|
+
prerelease: false
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ! '>='
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '0'
|
78
|
+
- !ruby/object:Gem::Dependency
|
79
|
+
name: pry-nav
|
80
|
+
requirement: !ruby/object:Gem::Requirement
|
81
|
+
none: false
|
82
|
+
requirements:
|
83
|
+
- - ! '>='
|
84
|
+
- !ruby/object:Gem::Version
|
85
|
+
version: '0'
|
86
|
+
type: :development
|
87
|
+
prerelease: false
|
88
|
+
version_requirements: !ruby/object:Gem::Requirement
|
89
|
+
none: false
|
90
|
+
requirements:
|
91
|
+
- - ! '>='
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: '0'
|
94
|
+
- !ruby/object:Gem::Dependency
|
95
|
+
name: guard
|
96
|
+
requirement: !ruby/object:Gem::Requirement
|
97
|
+
none: false
|
98
|
+
requirements:
|
99
|
+
- - ! '>='
|
100
|
+
- !ruby/object:Gem::Version
|
101
|
+
version: '0'
|
102
|
+
type: :development
|
103
|
+
prerelease: false
|
104
|
+
version_requirements: !ruby/object:Gem::Requirement
|
105
|
+
none: false
|
106
|
+
requirements:
|
107
|
+
- - ! '>='
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
version: '0'
|
110
|
+
- !ruby/object:Gem::Dependency
|
111
|
+
name: guard-rspec
|
112
|
+
requirement: !ruby/object:Gem::Requirement
|
113
|
+
none: false
|
114
|
+
requirements:
|
115
|
+
- - ! '>='
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0'
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
none: false
|
122
|
+
requirements:
|
123
|
+
- - ! '>='
|
124
|
+
- !ruby/object:Gem::Version
|
125
|
+
version: '0'
|
126
|
+
description: Ruby wrapper for LightSide Web API
|
127
|
+
email: tom.head@revolutionprep.com
|
128
|
+
executables: []
|
129
|
+
extensions: []
|
130
|
+
extra_rdoc_files: []
|
131
|
+
files:
|
132
|
+
- .gitignore
|
133
|
+
- .rspec
|
134
|
+
- Gemfile
|
135
|
+
- Guardfile
|
136
|
+
- README.md
|
137
|
+
- lib/lightside.rb
|
138
|
+
- lib/lightside/config.rb
|
139
|
+
- lib/lightside/exceptions.rb
|
140
|
+
- lib/lightside/models/answer.rb
|
141
|
+
- lib/lightside/models/answer_set.rb
|
142
|
+
- lib/lightside/models/assignment_icon.rb
|
143
|
+
- lib/lightside/models/assignment_tile_color.rb
|
144
|
+
- lib/lightside/models/author.rb
|
145
|
+
- lib/lightside/models/corpus.rb
|
146
|
+
- lib/lightside/models/human_score.rb
|
147
|
+
- lib/lightside/models/prediction_result.rb
|
148
|
+
- lib/lightside/models/prediction_task.rb
|
149
|
+
- lib/lightside/models/prompt.rb
|
150
|
+
- lib/lightside/models/resolved_score.rb
|
151
|
+
- lib/lightside/models/tag_answer_set.rb
|
152
|
+
- lib/lightside/models/tag_prompt.rb
|
153
|
+
- lib/lightside/models/trained_model.rb
|
154
|
+
- lib/lightside/models/trained_model_evaluation.rb
|
155
|
+
- lib/lightside/models/training_answer.rb
|
156
|
+
- lib/lightside/models/training_task.rb
|
157
|
+
- lib/lightside/pager.rb
|
158
|
+
- lib/lightside/resources.rb
|
159
|
+
- lib/lightside/version.rb
|
160
|
+
- lightside.gemspec
|
161
|
+
- spec/config_spec.rb
|
162
|
+
- spec/fixtures/prompts.json
|
163
|
+
- spec/fixtures/prompts/2.json
|
164
|
+
- spec/fixtures/prompts_1.json
|
165
|
+
- spec/fixtures/prompts_2.json
|
166
|
+
- spec/fixtures/prompts_3.json
|
167
|
+
- spec/fixtures/prompts_4.json
|
168
|
+
- spec/pager_spec.rb
|
169
|
+
- spec/resources_spec.rb
|
170
|
+
- spec/spec_helper.rb
|
171
|
+
homepage: ''
|
172
|
+
licenses:
|
173
|
+
- MIT
|
174
|
+
post_install_message:
|
175
|
+
rdoc_options: []
|
176
|
+
require_paths:
|
177
|
+
- lib
|
178
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
179
|
+
none: false
|
180
|
+
requirements:
|
181
|
+
- - ! '>='
|
182
|
+
- !ruby/object:Gem::Version
|
183
|
+
version: '0'
|
184
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
185
|
+
none: false
|
186
|
+
requirements:
|
187
|
+
- - ! '>='
|
188
|
+
- !ruby/object:Gem::Version
|
189
|
+
version: '0'
|
190
|
+
requirements: []
|
191
|
+
rubyforge_project:
|
192
|
+
rubygems_version: 1.8.25
|
193
|
+
signing_key:
|
194
|
+
specification_version: 3
|
195
|
+
summary: LightSide API
|
196
|
+
test_files:
|
197
|
+
- spec/config_spec.rb
|
198
|
+
- spec/fixtures/prompts.json
|
199
|
+
- spec/fixtures/prompts/2.json
|
200
|
+
- spec/fixtures/prompts_1.json
|
201
|
+
- spec/fixtures/prompts_2.json
|
202
|
+
- spec/fixtures/prompts_3.json
|
203
|
+
- spec/fixtures/prompts_4.json
|
204
|
+
- spec/pager_spec.rb
|
205
|
+
- spec/resources_spec.rb
|
206
|
+
- spec/spec_helper.rb
|