Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Automate discovery of broken URIs.

  • Loading branch information...
commit 0a5880527f62dd363cc1b469f7723061053e049a 1 parent b03f863
@georgebrock georgebrock authored
View
2  Gemfile
@@ -4,6 +4,8 @@ ruby '1.9.3'
gem 'bourne'
gem 'colored'
+gem 'httparty'
gem 'json'
gem 'mocha', require: false
gem 'rspec'
+gem 'webmock'
View
14 Gemfile.lock
@@ -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
2  lib/helpers/json_validator.rb
@@ -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
View
4 lib/helpers/trail_runner.rb
@@ -15,7 +15,9 @@ def print_starting_message
end
def run_validations_on_json_files
- json_files.each { |file| JSONValidator.new(file).run }
+ json_files.each do |file|
+ JSONValidator.new(file).run && URIValidator.new(file).run
+ end
end
def json_files
View
45 lib/helpers/uri_extractor.rb
@@ -0,0 +1,45 @@
+class URIExtractor
+ def initialize(file_name)
+ @file_name = file_name
+ contents = File.read(@file_name)
+ @json = JSON.parse(contents)
+ end
+
+ def each(&block)
+ uris.each(&block)
+ end
+
+ private
+
+ def uris
+ @uris ||= extract_uris(@json)
+ end
+
+ 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)
+ uris = []
+
+ hash.each do |key, value|
+ if key == 'uri'
+ uris << value
+ else
+ uris += extract_uris(value)
+ end
+ end
+
+ uris
+ end
+
+ def extract_uris_from_array(array)
+ array.map { |o| extract_uris(o) }.flatten
+ end
+end
View
38 lib/helpers/uri_validator.rb
@@ -0,0 +1,38 @@
+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)
+ response = HTTParty.head(uri)
+ return response.code == 200
+ rescue SocketError
+ return false
+ end
+
+ def print_progress_marker
+ print '.'
+ end
+
+ def print_error_message(uri)
+ puts "\nERROR: #{uri} cannot be found"
+ end
+end
View
10 spec/json_validator_spec.rb
@@ -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
2  spec/spec_helper.rb
@@ -1,3 +1,5 @@
+require 'webmock/rspec'
+
script_directory = File.dirname(__FILE__)
helper_files = script_directory + '/../lib/helpers/*.rb'
View
13 spec/trail_runner_spec.rb
@@ -6,6 +6,8 @@
describe TrailRunner, '#run' do
it 'returns a starting message' do
$stdout = io = StringIO.new
+ uri_validator_stub = stub('uri validator stub', :run)
+ URIValidator.stubs(:new).returns(uri_validator_stub)
TrailRunner.new.run
@@ -13,11 +15,13 @@
end
it 'calls JSONValidator.new(file).run on each file' do
- validator_stub = stub('json validator stub', :run)
+ validator_stub = stub('json validator stub', run: true)
JSONValidator.stubs(:new).returns(validator_stub)
- dir = File.dirname(__FILE__)
- file_name = File.open(dir + '/fixtures/valid.json')
+ uri_validator_stub = stub('uri validator stub', :run)
+ URIValidator.stubs(:new).returns(uri_validator_stub)
+
+ file_name = File.expand_path('../fixtures/valid.json', __FILE__)
files = [file_name]
runner = TrailRunner.new
runner.stubs(:json_files).returns(files)
@@ -25,10 +29,13 @@
runner.run
JSONValidator.should have_received(:new)
+ URIValidator.should have_received(:new)
end
it 'prints a closing puts' do
$stdout = io = StringIO.new
+ uri_validator_stub = stub('uri validator stub', :run)
+ URIValidator.stubs(:new).returns(uri_validator_stub)
TrailRunner.new.run
View
15 spec/uri_extractor_spec.rb
@@ -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
34 spec/uri_validator_spec.rb
@@ -0,0 +1,34 @@
+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(:head, 'http://thoughtbot.com/404').to_return(status: 404)
+ file_name = '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: http://bad\.example\.org}
+ io.string.should =~ %r{ERROR: http://thoughtbot\.com/404}
+ end
+end
Please sign in to comment.
Something went wrong with that request. Please try again.