Skip to content

Commit

Permalink
Raise incompatible algorithm errors
Browse files Browse the repository at this point in the history
  • Loading branch information
jaysonvirissimo committed Dec 24, 2023
1 parent 1f23d39 commit 9474d32
Show file tree
Hide file tree
Showing 5 changed files with 55 additions and 17 deletions.
2 changes: 2 additions & 0 deletions lib/active_recall.rb
Original file line number Diff line number Diff line change
Expand Up @@ -30,4 +30,6 @@ def self.configuration
def self.reset
@configuration = Configuration.new
end

class IncompatibleAlgorithmError < StandardError; end
end
4 changes: 4 additions & 0 deletions lib/active_recall/algorithms/sm2.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ def self.score(box:, easiness_factor:, times_right:, times_wrong:, grade:, curre
).score
end

def self.type
:gradable
end

def initialize(box:, easiness_factor:, times_right:, times_wrong:, grade:, current_time: Time.current)
@box = box
@easiness_factor = easiness_factor || 2.5
Expand Down
24 changes: 17 additions & 7 deletions lib/active_recall/models/item.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,21 +18,33 @@ def self.known(current_time: Time.current)
end

def score!(grade)
update!(
algorithm_class.score(**scoring_attributes.merge(grade: grade))
).score
if algorithm_class.type == :gradable
update!(
algorithm_class.score(**scoring_attributes.merge(grade: grade))
).score
else
raise IncompatibleAlgorithmError, "#{algorithm_class.name} is a not an gradable algorithm, so is not compatible with the #score! method"
end
end

def source
source_type.constantize.find(source_id)
end

def right!
update!(algorithm_class.right(**scoring_attributes))
if algorithm_class.type == :binary
update!(algorithm_class.right(**scoring_attributes))
else
raise IncompatibleAlgorithmError, "#{algorithm_class.name} is not a binary algorithm, so is not compatible with the #right! method"
end
end

def wrong!
update!(algorithm_class.wrong(**scoring_attributes))
if algorithm_class.type == :binary
update!(algorithm_class.wrong(**scoring_attributes))
else
raise IncompatibleAlgorithmError, "#{algorithm_class.name} is not a binary algorithm, so is not compatible with the #wrong! method"
end
end

private
Expand All @@ -46,7 +58,5 @@ def scoring_attributes
.symbolize_keys
.slice(*algorithm_class.required_attributes)
end

class IncompatibleAlgorithmError < StandardError; end
end
end
35 changes: 25 additions & 10 deletions spec/active_recall/item_methods_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,25 +11,40 @@
end

describe "#right_answer_for!" do
it "calls right! on the corresponding item" do
expect_any_instance_of(ActiveRecall::Item).to receive(:right!).and_call_original
user.right_answer_for!(item)
it "errors when tried without a binary algorithm" do
ActiveRecall.configure do |config|
@previous_algorithm_class = config.algorithm_class
config.algorithm_class = ActiveRecall::SM2
end

expect { user.right_answer_for!(item) }.to raise_error(ActiveRecall::IncompatibleAlgorithmError)

ActiveRecall.configure do |config|
config.algorithm_class = @previous_algorithm_class
end
end
end

describe "#wrong_answer_for!" do
it "calls wrong! on the corresponding item" do
expect_any_instance_of(ActiveRecall::Item).to receive(:wrong!).and_call_original
user.wrong_answer_for!(item)
it "errors when tried without a binary algorithm" do
ActiveRecall.configure do |config|
@previous_algorithm_class = config.algorithm_class
config.algorithm_class = ActiveRecall::SM2
end

expect { user.wrong_answer_for!(item) }.to raise_error(ActiveRecall::IncompatibleAlgorithmError)

ActiveRecall.configure do |config|
config.algorithm_class = @previous_algorithm_class
end
end
end

xdescribe "#score!" do
describe "#score!" do
let(:grade) { 4 }

it "calls score! on the corresponding item with the correct grade" do
expect_any_instance_of(ActiveRecall::Item).to receive(:score!).with(grade).and_call_original
user.score!(grade, item)
it "errors when tried without a binary algorithm" do
expect { user.score!(grade, item) }.to raise_error(ActiveRecall::IncompatibleAlgorithmError)
end
end
end
7 changes: 7 additions & 0 deletions spec/active_recall_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,17 @@
context "when overriding the default" do
before do
ActiveRecall.configure do |config|
@previous_algorithm_class = config.algorithm_class
config.algorithm_class = ActiveRecall::FibonacciSequence
end
end

after do
ActiveRecall.configure do |config|
config.algorithm_class = @previous_algorithm_class
end
end

it "uses the explicitly specified algorithm" do
allow(ActiveRecall::FibonacciSequence).to receive(:right).and_return({})
allow(ActiveRecall::LeitnerSystem).to receive(:right)
Expand Down

0 comments on commit 9474d32

Please sign in to comment.