Skip to content

Commit

Permalink
test: add fully integrated test that installs and runs gembytes via b…
Browse files Browse the repository at this point in the history
…undler

Add cucumber tests (run via rspec with the turnip gem) that creates a sample project,
installs the bundler-gem_bytes plugin, and then runs a gembytes script.

The purpose is to make sure that the integration with bundler is completely working
end-to-end.
  • Loading branch information
jcouball committed Oct 30, 2024
1 parent ab907b4 commit 2147776
Show file tree
Hide file tree
Showing 5 changed files with 190 additions and 3 deletions.
3 changes: 3 additions & 0 deletions bundler-gem_bytes.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -51,11 +51,14 @@ Gem::Specification.new do |spec|

spec.add_development_dependency 'bundler-audit', '~> 0.9'
spec.add_development_dependency 'main_branch_shared_rubocop_config'
spec.add_development_dependency 'process_executer', '~> 1.2'
spec.add_development_dependency 'rake', '~> 13.2'
spec.add_development_dependency 'rspec', '~> 3.13'
spec.add_development_dependency 'rubocop', '~> 1.66'
spec.add_development_dependency 'simplecov', '~> 0.22'
spec.add_development_dependency 'simplecov-lcov', '~> 0.8'
spec.add_development_dependency 'simplecov-rspec', '~> 0.4'
spec.add_development_dependency 'turnip', '~> 4.4'

if RUBY_PLATFORM != 'java'
spec.add_development_dependency 'redcarpet', '~> 3.5'
Expand Down
2 changes: 0 additions & 2 deletions lib/bundler/gem_bytes/actions.rb
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,11 @@ module Actions
# @api public
#
def add_dependency(dependency_type, gem_name, version_constraint, force: false, gemspec: Dir['*.gemspec'].first)
puts 'Staring'
source = File.read(gemspec)
updated_source = Bundler::GemBytes::Gemspec::UpsertDependency.new(
dependency_type, gem_name, version_constraint, force: force
).call(source)
File.write(gemspec, updated_source)
puts 'Ending'
end
end
end
Expand Down
95 changes: 95 additions & 0 deletions spec/features/actions_steps.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
# frozen_string_literal: true

# In your Turnip step definitions file
require 'fileutils'
require 'process_executer'
require 'stringio'
require 'tmpdir'

# Around hook to ensure the temp directory is cleaned up
RSpec.configure do |config|
config.around(:each, type: :feature) do |example|
@project_dir = Dir.pwd
Dir.mktmpdir do |temp_dir|
@temp_dir = temp_dir
Dir.chdir(temp_dir) do
example.run
end
end
end
end

# rubocop:disable Style/TrivialAccessors
def project_dir = @project_dir
def temp_dir = @temp_dir
def gem_project_dir = @gem_project_dir
def gem_bytes_script_name = @gem_bytes_script_name
def gem_bytes_script_path = @gem_bytes_script_path
def gemspec_path = @gemspec_path
def env = { 'BUNDLE_IGNORE_CONFIG' => 'TRUE' }
def command_out = @command_out
def command_err = @command_err
def command_status = @command_status
# rubocop:enable Style/TrivialAccessors

def run_command(command, raise_on_fail: true, failure_message: "#{command[0]} failed")
out_buffer = StringIO.new
out_pipe = ProcessExecuter::MonitoredPipe.new(out_buffer)
err_buffer = StringIO.new
err_pipe = ProcessExecuter::MonitoredPipe.new(err_buffer)

ProcessExecuter.spawn(env, *command, timeout: 5, out: out_pipe, err: err_pipe).tap do |status|
@command_out = out_buffer.string
@command_err = err_buffer.string
@command_status = status

raise "#{failure_message}: #{command_err}" if raise_on_fail && !command_status.success?
end
end

step 'a gem project named :gem_name with the bundler-gem_bytes plugin installed' do |gem_name|
@gem_project_dir = File.join(temp_dir, gem_name)

command = [
'bundle', 'gem', gem_name, '--no-test', '--no-ci', '--no-mit', '--no-coc', '--no-linter', '--no-changelog'
]
run_command(command, failure_message: 'Failed to create gem project')

Dir.chdir(gem_project_dir) do
command = ['bundle', 'plugin', 'install', '--path', project_dir, 'bundler-gem_bytes']
run_command(command, failure_message: 'Failed to install plugin')
end
end

step 'the project has a gemspec containing:' do |content|
@gemspec_path = File.join(@gem_project_dir, "#{File.basename(gem_project_dir)}.gemspec")
File.write gemspec_path, content
end

step 'a gem-bytes script :gem_bytes_script_name containing:' do |gem_bytes_script_name, content|
@gem_bytes_script_name = gem_bytes_script_name
@gem_bytes_script_path = File.join(@gem_project_dir, gem_bytes_script_name)
File.write gem_bytes_script_path, content
end

step 'I run :command' do |command|
Dir.chdir(gem_project_dir) do
run_command(command.split, fail_on_error: false)
end
end

step 'the command should have succeeded' do
expect(command_status.success?).to eq(true)
end

step 'the command should have failed' do
expect(command_status.success?).to eq(false)
end

step 'the gemspec should contain:' do |content|
expect(File.read(gemspec_path)).to eq(content)
end

step 'the command stderr should contain :content' do |content|
expect(command_err).to include(content)
end
70 changes: 70 additions & 0 deletions spec/features/add_dependency.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
Feature: Add or update a dependency to the project's gemspec

Scenario: Add a dependency

Given a gem project named "foo" with the bundler-gem_bytes plugin installed
And the project has a gemspec containing:
"""
Gem::Specification.new do |spec|
spec.name = 'foo'
spec.version = '1.0'
end
"""
And a gem-bytes script "gem_bytes_script" containing:
"""
add_dependency :runtime, 'foo', '>= 1.0'
"""
When I run "bundle gem-bytes gem_bytes_script"
Then the command should have succeeded
And the gemspec should contain:
"""
Gem::Specification.new do |spec|
spec.name = 'foo'
spec.version = '1.0'
spec.add_dependency 'foo', '>= 1.0'
end
"""

Scenario: Update a dependency

Given a gem project named "foo" with the bundler-gem_bytes plugin installed
And the project has a gemspec containing:
"""
Gem::Specification.new do |spec|
spec.name = 'foo'
spec.version = '1.0'
spec.add_dependency 'foo', '>= 0.9'
end
"""
And a gem-bytes script "gem_bytes_script" containing:
"""
add_dependency :runtime, 'foo', '>= 1.0'
"""
When I run "bundle gem-bytes gem_bytes_script"
Then the command should have succeeded
And the gemspec should contain:
"""
Gem::Specification.new do |spec|
spec.name = 'foo'
spec.version = '1.0'
spec.add_dependency 'foo', '>= 1.0'
end
"""

Scenario: Update a dependency with conflicting dependency type
Given a gem project named "foo" with the bundler-gem_bytes plugin installed
And the project has a gemspec containing:
"""
Gem::Specification.new do |spec|
spec.name = 'foo'
spec.version = '1.0'
spec.add_runtime_dependency 'foo', '>= 0.9'
end
"""
And a gem-bytes script "gem_bytes_script" containing:
"""
add_dependency :runtime, 'foo', '>= 1.0'
"""
When I run "bundle gem-bytes gem_bytes_script"
Then the command should have failed
And the command stderr should contain "the dependency type is different"
23 changes: 22 additions & 1 deletion spec/spec_helper.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
# frozen_string_literal: true

# Turnip setup
#
require 'turnip/rspec'
Dir[File.join(__dir__, '**/*_steps.rb')].each { |f| require f }

# RSpec setup
#
RSpec.configure do |config|
# Enable flags like --only-failures and --next-failure
config.example_status_persistence_file_path = '.rspec_status'
Expand All @@ -12,7 +19,21 @@
end
end

# SimpleCov configuration
#
require 'simplecov'
require 'simplecov-lcov'
require 'simplecov-rspec'
SimpleCov::RSpec.start

def ci_build? = ENV.fetch('GITHUB_ACTIONS', 'false') == 'true'

if ci_build?
SimpleCov.formatters = [
SimpleCov::Formatter::HTMLFormatter,
SimpleCov::Formatter::LcovFormatter
]
end

SimpleCov::RSpec.start(list_uncovered_lines: ci_build?)

require 'bundler/gem_bytes'

0 comments on commit 2147776

Please sign in to comment.