Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

Already on GitHub? Sign in to your account

Fix dead links #94

Merged
merged 9 commits into from Jan 14, 2013
View
@@ -4,6 +4,8 @@ ruby '1.9.3'
gem 'bourne'
gem 'colored'
+gem 'httparty'
gem 'json'
gem 'mocha', require: false
@adarsh

adarsh Jan 10, 2013

Contributor

Mocha will throw deprecation warnings unless you put it last in the gem list. Maybe with a comment like

gem 'mocha', require: false   #this gem needs to be last in the list

To prevent future undesired alphabetization (by me :) )

@georgebrock

georgebrock Jan 11, 2013

Owner

The order of the Gemfile didn't get rid of the deprecation notice for me. Nor did removing Mocha and manually requiring Bourne (see https://github.com/thoughtbot/bourne/issues/14)

gem 'rspec'
+gem 'webmock'
View
@@ -1,15 +1,21 @@
GEM
remote: http://rubygems.org/
specs:
- awesome_print (1.1.0)
+ addressable (2.3.2)
bourne (1.2.0)
mocha (= 0.12.3)
colored (1.2)
+ crack (0.3.2)
diff-lcs (1.1.3)
+ httparty (0.9.0)
+ multi_json (~> 1.0)
+ multi_xml
json (1.7.5)
metaclass (0.0.1)
mocha (0.12.3)
metaclass (~> 0.0.1)
+ multi_json (1.5.0)
+ multi_xml (0.5.1)
rspec (2.12.0)
rspec-core (~> 2.12.0)
rspec-expectations (~> 2.12.0)
@@ -18,14 +24,18 @@ GEM
rspec-expectations (2.12.0)
diff-lcs (~> 1.1.3)
rspec-mocks (2.12.0)
+ webmock (1.9.0)
+ addressable (>= 2.2.7)
+ crack (>= 0.1.7)
PLATFORMS
ruby
DEPENDENCIES
- awesome_print
bourne
colored
+ httparty
json
mocha
rspec
+ webmock
View
@@ -0,0 +1,31 @@
+require 'rake'
+require 'bundler/setup'
+require 'rspec/core/rake_task'
+
+RSpec::Core::RakeTask.new(:spec)
+
+task :environment do
+ script_directory = File.dirname(__FILE__)
+ helper_files = script_directory + '/lib/helpers/*.rb'
+ Dir[helper_files].each { |file| require File.expand_path(file) }
+end
+
+desc 'Run RSpec code examples and validations'
+task :test => [:spec, :validate]
+
+desc 'Run validations'
+task :validate => %w(validate:json validate:uris)
+
+namespace :validate do
+ desc 'Run JSON validations'
+ task :json => :environment do
+ TrailRunner.new.run('JSON validation') { |file| JSONValidator.new(file).run }
+ end
+
+ desc 'Run URI validations'
+ task :uris => :environment do
+ TrailRunner.new.run('URI validation') { |file| URIValidator.new(file).run }
+ end
+end
+
+task :default => :test
@@ -13,8 +13,10 @@ def run
def check_json_validation
if valid_json?
print_progress_marker
+ return true
else
print_error_message
+ return false
end
end
@@ -2,20 +2,16 @@
require 'rubygems'
class TrailRunner
- def run
- print_starting_message
- run_validations_on_json_files
+ def run(purpose, &block)
+ print_starting_message(purpose)
+ json_files.each(&block)
print_closing_puts
end
private
- def print_starting_message
- puts "Starting JSON validation\n"
- end
-
- def run_validations_on_json_files
- json_files.each { |file| JSONValidator.new(file).run }
+ def print_starting_message(purpose)
+ puts "Starting #{purpose}\n"
end
def json_files
@@ -0,0 +1,44 @@
+class URIExtractor
+ def initialize(file_name)
+ @file_name = file_name
+ @json = parse_json
+ end
+
+ def each(&block)
+ uris.each(&block)
+ end
+
+ private
+
+ def extract_uris(source)
+ if source.is_a?(Hash)
+ extract_uris_from_hash(source)
+ elsif source.is_a?(Array)
+ extract_uris_from_array(source)
+ else
+ []
+ end
+ end
+
+ def extract_uris_from_hash(hash)
+ hash.inject([]) do |uris, (key, value)|
+ if key == 'uri'
+ uris + [value]
+ else
+ uris + extract_uris(value)
+ end
+ end
+ end
+
+ def extract_uris_from_array(array)
+ array.map { |o| extract_uris(o) }.flatten
+ end
+
+ def parse_json
+ JSON.parse(File.read(@file_name))
+ end
+
+ def uris
+ @uris ||= extract_uris(@json)
+ end
+end
@@ -0,0 +1,49 @@
+require 'httparty'
+
+class URIValidator
+ def initialize(file_name)
+ @file_name = file_name
+ end
+
+ def run
+ uris.each do |uri|
+ if valid_uri?(uri)
+ print_progress_marker
+ else
+ print_error_message(uri)
+ end
+ end
+ end
+
+ private
+
+ def uris
+ URIExtractor.new(@file_name)
+ end
+
+ def valid_uri?(uri)
+ head_request_ok?(uri) || get_request_ok?(uri)
+ end
+
+ def head_request_ok?(uri)
+ response = HTTParty.head(uri)
+ return response.ok?
+ rescue SocketError
+ return false
+ end
+
+ def get_request_ok?(uri)
+ response = HTTParty.get(uri)
+ return response.ok?
+ rescue SocketError
+ return false
+ end
+
+ def print_progress_marker
+ print '.'
+ end
+
+ def print_error_message(uri)
+ puts "\nERROR in #{File.basename(@file_name)}: #{uri} cannot be found"
+ end
+end
View
@@ -1,8 +0,0 @@
-#!/usr/bin/env ruby
-
-script_directory = File.dirname(__FILE__)
-helper_files = script_directory + '/helpers/*.rb'
-
-Dir[helper_files].each { |file| require File.expand_path(file) }
-
-TrailRunner.new.run
@@ -1,24 +1,26 @@
require 'spec_helper'
describe JSONValidator, '#run' do
- it 'returns a dot if the JSON is valid' do
+ it 'returns true and outputs a dot if the JSON is valid' do
$stdout = io = StringIO.new
dir = File.dirname(__FILE__)
file_name = File.open(dir + '/fixtures/valid.json')
- JSONValidator.new(file_name).run
+ result = JSONValidator.new(file_name).run
+ result.should be_true
io.string.should eq '.'
end
- it 'returns an error if the JSON is not valid' do
+ it 'returns false and outputs an error if the JSON is not valid' do
$stdout = io = StringIO.new
dir = File.dirname(__FILE__)
file_name = File.open(dir + '/fixtures/invalid.json')
- JSONValidator.new(file_name).run
+ result = JSONValidator.new(file_name).run
+ result.should be_false
io.string.should =~ /ERROR/
end
end
View
@@ -1,3 +1,5 @@
+require 'webmock/rspec'
+
script_directory = File.dirname(__FILE__)
helper_files = script_directory + '/../lib/helpers/*.rb'
View
@@ -4,33 +4,29 @@
require 'bourne'
describe TrailRunner, '#run' do
- it 'returns a starting message' do
+ it 'outputs a starting message' do
$stdout = io = StringIO.new
- TrailRunner.new.run
+ TrailRunner.new.run('JSON validation') {}
- io.string.split("\n")[0].should =~ /Starting/
+ io.string.split("\n")[0].should =~ /Starting JSON validation/
end
- it 'calls JSONValidator.new(file).run on each file' do
- validator_stub = stub('json validator stub', :run)
- JSONValidator.stubs(:new).returns(validator_stub)
-
- dir = File.dirname(__FILE__)
- file_name = File.open(dir + '/fixtures/valid.json')
- files = [file_name]
+ it 'yields each file name' do
runner = TrailRunner.new
+ files = %w(rails.json vim.json)
runner.stubs(:json_files).returns(files)
+ yielded_files = []
- runner.run
+ runner.run('Yield test') { |f| yielded_files << f }
- JSONValidator.should have_received(:new)
+ yielded_files.should eq files
end
it 'prints a closing puts' do
$stdout = io = StringIO.new
- TrailRunner.new.run
+ TrailRunner.new.run('Closing test') {}
output = io.string[-1, 1]
output.should == "\n"
View
@@ -0,0 +1,15 @@
+require 'spec_helper'
+
+describe URIExtractor, '#each' do
+ it 'yields each URI' do
+ file_name = File.expand_path('../fixtures/valid.json', __FILE__)
+ found_uris = []
+
+ URIExtractor.new(file_name).each { |uri| found_uris << uri }
+
+ expect(found_uris).to eq %w(
+ http://amzn.to/the-linux-programming-interface
+ http://en.wikipedia.org/wiki/Redirection_%28computing%29
+ )
+ end
+end
View
@@ -0,0 +1,62 @@
+require 'spec_helper'
+
+describe URIValidator, '#run' do
+ it 'outputs a dot for each valid URI' do
+ stub_request(:head, 'http://example.org')
+ stub_request(:head, 'http://example.com')
+ file_name = 'good_json_file.json'
+ URIExtractor.stubs(:new).with(file_name).returns %w(
+ http://example.org
+ http://example.com
+ )
+ $stdout = io = StringIO.new
+
+ URIValidator.new(file_name).run
+
+ io.string.should eq '..'
+ end
+
+ it 'outputs an error for each invalid URI' do
+ stub_request(:head, 'http://bad.example.org').to_raise(SocketError)
+ stub_request(:get, 'http://bad.example.org').to_raise(SocketError)
+ stub_request(:head, 'http://thoughtbot.com/404').to_return(status: 404)
+ stub_request(:get, 'http://thoughtbot.com/404').to_return(status: 404)
+ file_name = 'path/to/bad_json_file.json'
+ URIExtractor.stubs(:new).with(file_name).returns %w(
+ http://bad.example.org
+ http://thoughtbot.com/404
+ )
+ $stdout = io = StringIO.new
+
+ URIValidator.new(file_name).run
+
+ io.string.should =~ %r{ERROR in bad_json_file\.json: http://bad\.example\.org}
+ io.string.should =~ %r{ERROR in bad_json_file\.json: http://thoughtbot\.com/404}
+ end
+
+ it 'retries with a GET request on a method not allowed error' do
+ stub_request(:head, 'http://example.com').to_return(status: 405)
+ stub_request(:get, 'http://example.com')
+ file_name = 'rails.json'
+ URIExtractor.stubs(:new).with(file_name).returns %w(http://example.com)
+ $stdout = io = StringIO.new
+
+ URIValidator.new(file_name).run
+
+ WebMock.should have_requested(:head, 'http://example.com')
+ WebMock.should have_requested(:get, 'http://example.com')
+ end
+
+ it 'retries with a GET request on an exception' do
+ stub_request(:head, 'http://example.com').to_raise(SocketError)
+ stub_request(:get, 'http://example.com')
+ file_name = 'rails.json'
+ URIExtractor.stubs(:new).with(file_name).returns %w(http://example.com)
+ $stdout = io = StringIO.new
+
+ URIValidator.new(file_name).run
+
+ WebMock.should have_requested(:head, 'http://example.com')
+ WebMock.should have_requested(:get, 'http://example.com')
+ end
+end
Oops, something went wrong.