Skip to content

Commit 9be5d74

Browse files
Yusuf DanijuAustin Kabiru
Yusuf Daniju
authored and
Austin Kabiru
committed
List status codes by type (#24)
* method for listing codes by type * specify type * include type description * optimize slow code * refactor methods with high branch size * add regex to throw error if type entered is wrong * fix bug in grouping * separate code type constant into file * refactor tests for system exits * remove redundant code * add more test coverage * add rspec matchers to test for actual status code * bump version
1 parent e4b78bb commit 9be5d74

9 files changed

+148
-9
lines changed

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,4 @@
99
/tmp/
1010
/config/env.yaml
1111
/*.gem
12+
test.log

lib/hscode.rb

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
require 'hscode/version'
22
require 'hscode/input_parser'
33
require 'hscode/http_status_codes'
4+
require 'hscode/status_code_types'
45
require 'optparse'
56
require 'ostruct'
67

@@ -18,7 +19,7 @@ def self.print_code(options)
1819

1920
unless status_code
2021
puts "#{options.status_code} is not a valid code. See 'hscode --help'."
21-
exit
22+
exit 1
2223
end
2324

2425
PrettyPrint.print(

lib/hscode/input_parser.rb

+31-2
Original file line numberDiff line numberDiff line change
@@ -52,8 +52,11 @@ def run_verbosely(opts)
5252
end
5353

5454
def list_status_codes(opts)
55-
opts.on('-l', '--list', 'List all HTTP status codes') do
56-
print_all_codes
55+
opts.on('-l', '--list [TYPE]',
56+
'List all HTTP status codes of type') do |type|
57+
print_all_codes unless type
58+
options.status_type = type
59+
print_all_codes_by_type(type)
5760
end
5861
end
5962

@@ -63,6 +66,7 @@ def display_help_message(opts)
6366
hscode -c 200
6467
hscode -c 200 -v
6568
hscode -l
69+
hscode -l 2xx
6670
'
6771
exit
6872
end
@@ -75,6 +79,31 @@ def display_version_number(opts)
7579
end
7680
end
7781

82+
def print_all_codes_by_type(type)
83+
unless type =~ /\A[1-5]x{2}\z/
84+
abort "#{type} is not a valid code type. See 'hscode --help'."
85+
end
86+
87+
colour_code = type.to_s[0]
88+
PrettyPrint.print("#{type} #{STATUS_CODE_TYPES[type]}\n", colour_code)
89+
90+
process_code_type(type, colour_code)
91+
end
92+
93+
def process_code_type(type, colour)
94+
code_type_group(type).map do |code, info_hash|
95+
PrettyPrint.print("#{code} - #{info_hash[:title]}", colour)
96+
end
97+
98+
exit
99+
end
100+
101+
def code_type_group(type)
102+
HTTP_STATUS_CODES.select do |code, _|
103+
type.start_with? code.to_s[0]
104+
end
105+
end
106+
78107
def print_all_codes
79108
HTTP_STATUS_CODES.map do |code, info_hash|
80109
colour_code = code.to_s[0]

lib/hscode/status_code_types.rb

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
module Hscode
2+
STATUS_CODE_TYPES = {
3+
'1xx' => 'Informational',
4+
'2xx' => 'Sucess',
5+
'3xx' => 'Redirection',
6+
'4xx' => 'Client Error',
7+
'5xx' => 'Server Error'
8+
}.freeze
9+
end

lib/hscode/version.rb

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
module Hscode
2-
VERSION = '0.1.1'.freeze
2+
VERSION = '0.1.2'.freeze
33
end

spec/exit_code_matchers.rb

+37
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
RSpec::Matchers.define :terminate do |_code|
2+
actual = nil
3+
4+
def supports_block_expectations?
5+
true
6+
end
7+
8+
match do |block|
9+
begin
10+
block.call
11+
rescue SystemExit => e
12+
actual = e.status
13+
end
14+
actual && (actual == status_code)
15+
end
16+
17+
chain :with_code do |status_code|
18+
@status_code = status_code
19+
end
20+
21+
failure_message do |_block|
22+
"expected block to call exit(#{status_code}) but exit" +
23+
(actual.nil? ? ' not called' : "(#{actual}) was called")
24+
end
25+
26+
failure_message_when_negated do |_block|
27+
"expected block not to call exit(#{status_code})"
28+
end
29+
30+
description do
31+
"expect block to call exit(#{status_code})"
32+
end
33+
34+
def status_code
35+
@status_code ||= 0
36+
end
37+
end

spec/hscode/input_parser_spec.rb

+52-2
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,61 @@
1818
end
1919
end
2020

21+
context 'when option is `-l 5xx`' do
22+
it 'returns all http codes belonging to type' do
23+
expect do
24+
options = new_input_parser.parse(['-l', '5xx'])
25+
expect(options).to be_an_instance_of(OpenStruct)
26+
expect(options.verbose).to be nil
27+
expect(options.status_type).to eq('5xx')
28+
end.to terminate.with_code(0)
29+
end
30+
end
31+
32+
context 'when option is `-l 5xc`' do
33+
it 'should exit with status 1' do
34+
expect do
35+
options = new_input_parser.parse(['-l', '5xc'])
36+
expect(options).to be_an_instance_of(OpenStruct)
37+
expect(options.verbose).to be nil
38+
expect(options.status_type).to eq('5xx')
39+
end.to terminate.with_code(1)
40+
end
41+
end
42+
43+
context 'list all http codes' do
44+
it 'returns all http codes' do
45+
expect do
46+
options = new_input_parser.parse(['-l'])
47+
expect(options).to be_an_instance_of(OpenStruct)
48+
expect(options.status_type).to be nil
49+
end.to terminate.with_code(0)
50+
end
51+
end
52+
53+
context 'when option is --help' do
54+
it 'displays help message' do
55+
expect do
56+
options = new_input_parser.parse(['--help'])
57+
expect(options).to be_an_instance_of(OpenStruct)
58+
end.to terminate.with_code(0)
59+
end
60+
end
61+
62+
context 'when option is --version' do
63+
it 'displays version' do
64+
expect do
65+
options = new_input_parser.parse(['--version'])
66+
expect(options).to be_an_instance_of(OpenStruct)
67+
end.to terminate.with_code(0)
68+
end
69+
end
70+
2171
context 'Invalid requests' do
2272
let(:options) { new_input_parser.parse(['-f']) }
2373

24-
it 'raises an error' do
25-
expect { options }.to raise_error
74+
it 'exit with status 1' do
75+
expect { options }.to terminate.with_code(1)
2676
end
2777
end
2878
end

spec/hscode_spec.rb

+3-1
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,9 @@
3434
let(:error_msg) { "800 is not a valid code. See 'hscode --help'." }
3535

3636
it 'prints an error message' do
37-
expect(invalid_code).to be_eql error_msg
37+
expect do
38+
expect(invalid_code).to be_eql error_msg
39+
end.to terminate.with_code(1)
3840
end
3941
end
4042
end

spec/spec_helper.rb

+12-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
require 'simplecov'
22
require 'coveralls'
33
require 'pry'
4+
require 'exit_code_matchers'
45

56
Coveralls.wear!
67

@@ -20,7 +21,16 @@
2021
require 'rspec'
2122

2223
RSpec.configure do |config|
23-
# custom RSpec configurations
24+
config.before(:all) do
25+
@original_stdout = $stdout
26+
$stdout = File.new(File.join(File.dirname(__FILE__), 'test.log'), 'w')
27+
Pry.output = @original_stdout
28+
end
29+
30+
config.after(:all) do
31+
$stdout = @original_stdout
32+
@original_stdout = nil
33+
end
2434
end
2535

26-
ENV["RUBY_ENV"] = "test"
36+
ENV['RUBY_ENV'] = 'test'

0 commit comments

Comments
 (0)