-
Notifications
You must be signed in to change notification settings - Fork 5
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Refactor OutdatedGem
; install FactoryBot for improved test coverage
#5
Conversation
@@ -3,14 +3,17 @@ | |||
source "https://rubygems.org" | |||
gemspec | |||
|
|||
gem "factory_bot", "~> 6.3.0" |
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.
🗒️ I had to pin at 6.3 because newer versions of FactoryBot do not support Ruby 2.7, which is still part of our CI.
gem "minitest", "~> 5.11" | ||
gem "minitest-snapshots", "~> 1.1" | ||
gem "mocha", "~> 2.4" | ||
gem "observer" |
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.
🗒️ FactoryBot 6.3 has an undeclared dependency on observer
, which won't be part of Ruby 3.4. I had to make it an explicit dependency so that CI would pass on Ruby head.
@@ -28,7 +28,7 @@ def render_gem(name) | |||
|
|||
def render | |||
lines = [render_header] | |||
rows.each_key { |name| lines << render_gem(name) } | |||
rows.keys.sort.each { |name| lines << render_gem(name) } |
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.
🗒️ I moved sorting behavior into CLI::Table
, out of the core Report
class. This makes the report implementation simpler, and sorting is naturally more of a UI (CLI in our case) concern.
attr_reader :current_lockfile_entry, :updated_lockfile_entry, :gemfile_groups | ||
attr_writer :vulnerable | ||
attr_accessor :name, |
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.
🗒️ This refactor removes dependencies on lock file entries (which are deep data structures that in turn depend on internal Bundler classes) in favor of a flat set of simple PORO attributes.
class BundleUpdateInteractive::CLI | ||
class RowTest < Minitest::Test | ||
def test_formatted_gem_name_for_vulnerable_gem_is_red_on_white | ||
outdated_gem = build(:outdated_gem, name: "rails", vulnerable: true) |
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.
🗒️ These tests were super easy to write, because I can now use FactoryBot's build
to construct the exact scenarios I needed.
The core model class of this project is
OutdatedGem
. Currently, an instance of this class represents a complex object graph that is tightly coupled with Bundler classes likeBundler::LazySpecification
. Because of this complexity and broad scope, writing test coverage for different scenarios involvingOutdatedGem
is prohibitively difficult without a significant amount of mocking or fixture setup.This PR addresses this problem by refactoring
OutdatedGem
to be a shallow, struct-like data class that no longer has external Bundler dependencies.With that refactor in place, I was able to install FactoryBot and use it to easily write some new unit tests for
CLI::Row
.