diff --git a/.rspec b/.rspec new file mode 100644 index 0000000..43ae203 --- /dev/null +++ b/.rspec @@ -0,0 +1,3 @@ +--color +--require spec_helper +--format documentation diff --git a/gem_updater.gemspec b/gem_updater.gemspec index 7799ac2..b404cee 100644 --- a/gem_updater.gemspec +++ b/gem_updater.gemspec @@ -14,5 +14,7 @@ Gem::Specification.new do |s| s.add_runtime_dependency 'json', '~> 1.8' s.add_runtime_dependency 'nokogiri', '~> 1.6' + s.add_development_dependency 'rspec' + s.executables << 'gem_update' end diff --git a/lib/gem_updater/source_page_parser.rb b/lib/gem_updater/source_page_parser.rb index 4233108..209b435 100644 --- a/lib/gem_updater/source_page_parser.rb +++ b/lib/gem_updater/source_page_parser.rb @@ -20,7 +20,7 @@ def initialize( url: nil, version: nil ) def changelog @changelog ||= begin puts "Looking for a changelog in #{@uri}" - doc = Nokogiri::HTML(open( @uri ) ) + doc = Nokogiri::HTML( open( @uri ) ) find_changelog( doc ) @@ -119,7 +119,7 @@ def find_changelog_link # @param url [String] url of changelog # @return [String, nil] anchor's href def find_anchor( url ) - changelog_page = Nokogiri::HTML(open( url ) ) + changelog_page = Nokogiri::HTML( open( url ) ) anchor = changelog_page.css( %(a.anchor) ).find{ |element| element.attr( 'href' ).match( @version.gsub('.', '') ) } if anchor diff --git a/spec/gem_updater/gem_file_spec.rb b/spec/gem_updater/gem_file_spec.rb new file mode 100644 index 0000000..dba6461 --- /dev/null +++ b/spec/gem_updater/gem_file_spec.rb @@ -0,0 +1,69 @@ +require 'spec_helper' + +describe GemUpdater::GemFile do + subject( :gemfile ) { GemUpdater::GemFile.new } + let( :bundler_cli ){ OpenStruct.new( update: true, compute_changes: true ) } + + def old_gem_set + Bundler::SpecSet.new( [ + Gem::Specification.new( 'gem_up_to_date', '0.1' ), + Gem::Specification.new( 'gem_to_update', '1.5' ) + ] ) + end + + def new_gem_set + Bundler::SpecSet.new( [ + Gem::Specification.new( 'gem_up_to_date', '0.1' ), + Gem::Specification.new( 'gem_to_update', '2.3' ) + ] ) + end + + before do + allow( Bundler.definition ).to receive( :specs ).and_return( old_gem_set ) + allow( Bundler::CLI ).to receive( :new ).and_return( bundler_cli ) + allow( bundler_cli ).to receive( :update ) + end + + describe '#initialize' do + before { subject } + it 'gets current spec set' do + expect( Bundler.definition ).to have_received( :specs ) + end + end + + describe '#update!' do + before :each do + allow( subject ).to receive( :compute_changes ) + subject.update! + end + + it 'launched bundle update' do + expect( bundler_cli ).to have_received( :update ) + end + + it 'computes changes' do + expect( subject ).to have_received( :compute_changes ) + end + + it 'gets new spec set' do + expect( Bundler.definition ).to have_received( :specs ).twice + end + end + + describe '#compute_changes' do + before :each do + subject + allow( Bundler.definition ).to receive( :specs ).and_return( new_gem_set ) + subject.update! + subject.compute_changes + end + + it 'skips gems that were not updated' do + expect( subject.changes ).to_not have_key( :gem_up_to_date ) + end + + it 'includes updated gems with old and new version number' do + expect( subject.changes[ 'gem_to_update' ] ).to eq( versions: { old: '1.5', new: '2.3' } ) + end + end +end diff --git a/spec/gem_updater/ruby_gems_fetcher_spec.rb b/spec/gem_updater/ruby_gems_fetcher_spec.rb new file mode 100644 index 0000000..c603deb --- /dev/null +++ b/spec/gem_updater/ruby_gems_fetcher_spec.rb @@ -0,0 +1,51 @@ +require 'spec_helper' + +describe GemUpdater::RubyGemsFetcher do + subject { GemUpdater::RubyGemsFetcher.new( 'gem_name' ) } + + describe '#source_uri' do + context "when 'source_code_uri' is present" do + before do + allow( subject ).to receive_message_chain( :open, :read ) { { source_code_uri: 'source_code_uri' }.to_json } + subject.source_uri + end + + it "returns 'source_code_uri' value" do + expect( subject.source_uri ).to eq 'source_code_uri' + end + end + + context "when 'homepage_uri' is present" do + before do + allow( subject ).to receive_message_chain( :open, :read ) { { homepage_uri: 'homepage_uri' }.to_json } + subject.source_uri + end + + it "returns 'homepage_uri' value" do + expect( subject.source_uri ).to eq 'homepage_uri' + end + end + + context "when both 'source_code_uri' and 'homepage_uri' are present" do + before do + allow( subject ).to receive_message_chain( :open, :read ) { { source_code_uri: 'source_code_uri', homepage_uri: 'homepage_uri' }.to_json } + subject.source_uri + end + + it "returns 'source_code_uri' value" do + expect( subject.source_uri ).to eq 'source_code_uri' + end + end + + context 'none is present' do + before do + allow( subject ).to receive_message_chain( :open, :read ) { {}.to_json } + subject.source_uri + end + + it 'is falsey' do + expect( subject.source_uri ).to be_falsey + end + end + end +end diff --git a/spec/gem_updater/source_page_parser_spec.rb b/spec/gem_updater/source_page_parser_spec.rb new file mode 100644 index 0000000..b44513d --- /dev/null +++ b/spec/gem_updater/source_page_parser_spec.rb @@ -0,0 +1,41 @@ +require 'spec_helper' +require 'pry' + +describe GemUpdater::SourcePageParser do + subject { GemUpdater::SourcePageParser.new( url: 'https://github.com/fake_user/fake_gem', version: '0.2' ) } + + describe '#changelog' do + context 'when gem is hosted on github' do + context 'when there is no changelog' do + before do + allow( subject ).to receive( :open ) { github_gem_without_changelog } + end + + it 'is nil' do + expect( subject.changelog ).to be_nil + end + end + + context 'when changelog is in raw text' do + before do + allow( subject ).to receive( :open ) { github_gem_with_raw_changelog } + end + + it 'returns url of changelog' do + expect( subject.changelog ).to eq 'https://github.com/fake_user/fake_gem/blob/master/changelog.txt' + end + end + + context 'when changelog may contain anchor' do + before do + allow( subject ).to receive( :open ).with( URI( "https://github.com/fake_user/fake_gem" ) ) { github_gem_with_changelog_with_anchor } + allow_any_instance_of( GemUpdater::SourcePageParser::GitHubParser ).to receive( :open ).with( "https://github.com/fake_user/fake_gem/blob/master/changelog.md" ) { github_changelog } + end + + it 'returns url of changelog with anchor to version' do + expect( subject.changelog ).to eq 'https://github.com/fake_user/fake_gem/blob/master/changelog.md#02' + end + end + end + end +end diff --git a/spec/gem_updater_spec.rb b/spec/gem_updater_spec.rb new file mode 100644 index 0000000..5a597ee --- /dev/null +++ b/spec/gem_updater_spec.rb @@ -0,0 +1,54 @@ +require 'spec_helper' + +describe GemUpdater::Updater do + let( :gemfile ){ OpenStruct.new( update!: true, changes: [] ) } + + before :each do + allow( GemUpdater::GemFile ).to receive( :new ).and_return( gemfile ) + end + + describe '#update' do + before :each do + allow( gemfile ).to receive( :update! ) + allow( gemfile ).to receive( :changes ).and_return( { fake_gem: { versions: { old: '0.1', new: '0.2' } } } ) + allow( GemUpdater::RubyGemsFetcher ).to receive_message_chain( :new, :source_uri ) + allow( GemUpdater::SourcePageParser ).to receive( :new ).and_return( @source_page = OpenStruct.new( changelog: 'fake_gem_changelog_url' ) ) + subject.update! + end + + it 'updates gemfile' do + expect( gemfile ).to have_received( :update! ) + end + + it 'gets changelogs' do + expect( gemfile.changes[ :fake_gem ][ :changelog ] ).to eq 'fake_gem_changelog_url' + end + end + + describe '#format_diff' do + before :each do + allow( gemfile ).to receive( :changes ).and_return( { + fake_gem_1: { changelog: 'fake_gem_1_url', versions: { old: '1.0', new: '1.1' } }, + fake_gem_2: { changelog: 'fake_gem_2_url', versions: { old: '0.4', new: '0.4.2' } } + } ) + allow( STDOUT ).to receive( :puts ) + subject.format_diff + end + + it 'outputs changes' do + expect( STDOUT ).to have_received( :puts ).with( < +
+

+ + Version 0.2 +

+ +

Details

+ + +

+ + Version 0.1 +

+ +

Details

+
+ diff --git a/spec/support/fake_web/changelog_with_anchor.html b/spec/support/fake_web/changelog_with_anchor.html new file mode 100644 index 0000000..7def07e --- /dev/null +++ b/spec/support/fake_web/changelog_with_anchor.html @@ -0,0 +1,22 @@ + + + + + + + + + +
+ + + + changelog.md + + + Foo + + + +
diff --git a/spec/support/fake_web/no_changelog.html b/spec/support/fake_web/no_changelog.html new file mode 100644 index 0000000..28617dc --- /dev/null +++ b/spec/support/fake_web/no_changelog.html @@ -0,0 +1,21 @@ + + + + + + + + + +
+ + + + foo + + + Foo + + + +
diff --git a/spec/support/fake_web/raw_changelog.html b/spec/support/fake_web/raw_changelog.html new file mode 100644 index 0000000..17fd431 --- /dev/null +++ b/spec/support/fake_web/raw_changelog.html @@ -0,0 +1,22 @@ + + + + + + + + + +
+ + + + changelog + + + Foo + + + +
diff --git a/spec/support/helpers.rb b/spec/support/helpers.rb new file mode 100644 index 0000000..f48e9fa --- /dev/null +++ b/spec/support/helpers.rb @@ -0,0 +1,24 @@ +module Spec + module Helpers + + def fake_web_dir + '../fake_web' + end + + def github_gem_without_changelog + open( File.expand_path( "#{fake_web_dir}/no_changelog.html", __FILE__) ) + end + + def github_gem_with_raw_changelog + open( File.expand_path( "#{fake_web_dir}/raw_changelog.html", __FILE__) ) + end + + def github_gem_with_changelog_with_anchor + open( File.expand_path( "#{fake_web_dir}/changelog_with_anchor.html", __FILE__) ) + end + + def github_changelog + open( File.expand_path( "#{fake_web_dir}/changelog.html", __FILE__) ) + end + end +end