-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Testing the backwards logic was too hard, so I reversed it. i.e. `include_test_difficulty_level?` is easier to reason about than. `exclude_test_difficulty_level?` I also realized, through testing, that the previous attempt at memoization wasn't going to work since `a ||= false` will run every time. So we have to do an explicit Nil check, and only run the logic if the class variable is `#nil?`. Next, I started seeing random testing errors, which is never good or fun to track down. But I had a suspicion straight away that it was due to how we're memoizing state into the App class during the App test examples. So, i added a `before` block to pre-set that class variable back to `nil` before each test example run. However, that wasn't all! There was another place where class state was being affected. Which was in the DifficultyLevel::SETTINGS_MAP constant. Since we conditionally exclude the "Test" Difficulty Level, based on the result of our method under test: App.include_test_difficulty_level?. The easiest way to fix this is to lazy-initialize the "Settings Map" in Difficulty Level. i.e. don't load it as class load time, but rather, only after it is first accessed. This allows the "running" class to determine whether or not to include the "Test" difficulty level vs the "loaded" class. Annndddd... this is part of hwy lazy loading is one of the tenants of OOD. i.e. putting off loading a thing until the last second. - We didn't run into this before because before, our memoization of App.include_test_difficulty_level? wasn't working properly. After fixing it, we started seeing Class-level state issues in DifficultyLevel.
- Loading branch information
Showing
4 changed files
with
137 additions
and
14 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,113 @@ | ||
# frozen_string_literal: true | ||
|
||
require "test_helper" | ||
|
||
class AppTest < ActiveSupport::TestCase | ||
describe "App" do | ||
let(:unit_class) { App } | ||
|
||
subject { unit_class } | ||
|
||
describe ".include_test_difficulty_level?" do | ||
before do | ||
App.instance_variable_set(:@include_test_difficulty_level, nil) | ||
end | ||
|
||
after do | ||
App.instance_variable_set(:@include_test_difficulty_level, nil) | ||
end | ||
|
||
context "GIVEN App.debug? = true" do | ||
before do | ||
MuchStub.(unit_class, :debug?) { true } | ||
end | ||
|
||
context "WHETHER OR NOT any 'Test' Games exist" do | ||
before do | ||
MuchStub.tap(Game, :for_difficulty_level_test) { |arel| | ||
MuchStub.(arel, :any?) { [true, false].sample } | ||
} | ||
end | ||
|
||
it "returns true" do | ||
_(subject.include_test_difficulty_level?).must_equal(true) | ||
end | ||
end | ||
end | ||
|
||
context "GIVEN App.debug? = false" do | ||
before do | ||
MuchStub.(unit_class, :debug?) { false } | ||
end | ||
|
||
context "GIVEN 'Test' Games do exist" do | ||
before do | ||
MuchStub.tap(Game, :for_difficulty_level_test) { |arel| | ||
MuchStub.(arel, :any?) { true } | ||
} | ||
end | ||
|
||
it "returns true" do | ||
_(subject.include_test_difficulty_level?).must_equal(true) | ||
end | ||
end | ||
|
||
context "GIVEN no 'Test' Games exist" do | ||
before do | ||
MuchStub.tap(Game, :for_difficulty_level_test) { |arel| | ||
MuchStub.(arel, :any?) { false } | ||
} | ||
end | ||
|
||
it "returns false" do | ||
_(subject.include_test_difficulty_level?).must_equal(false) | ||
end | ||
end | ||
|
||
context "GIVEN multiple calls" do | ||
before do | ||
@any_called_count = 0 | ||
MuchStub.tap(Game, :for_difficulty_level_test) { |arel| | ||
MuchStub.(arel, :any?) { | ||
@any_called_count += 1 | ||
false | ||
} | ||
} | ||
end | ||
|
||
it "uses a memoized result" do | ||
subject.include_test_difficulty_level? | ||
subject.include_test_difficulty_level? | ||
_(@any_called_count).must_equal(1) | ||
end | ||
end | ||
end | ||
end | ||
|
||
describe ".debug?" do | ||
context "GIVEN Rails.configuration.debug = true" do | ||
before do | ||
MuchStub.tap(Rails, :configuration) { |config| | ||
MuchStub.(config, :debug) { true } | ||
} | ||
end | ||
|
||
it "returns true" do | ||
_(subject.debug?).must_equal(true) | ||
end | ||
end | ||
|
||
context "GIVEN Rails.configuration.debug = false" do | ||
before do | ||
MuchStub.tap(Rails, :configuration) { |config| | ||
MuchStub.(config, :debug) { false } | ||
} | ||
end | ||
|
||
it "returns false" do | ||
_(subject.debug?).must_equal(false) | ||
end | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters