Skip to content

Commit 7e334f3

Browse files
committed
Add rspec tests
1 parent 01b1932 commit 7e334f3

File tree

7 files changed

+183
-2
lines changed

7 files changed

+183
-2
lines changed

.github/workflows/build.yml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,10 @@ jobs:
2121
with:
2222
bundler-cache: true
2323

24+
- name: Run automated tests & measure code coverage
25+
run: |
26+
bundle exec rspec
27+
2428
- name: Analyze source code
2529
run: |
2630
bundle exec rubocop

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
# https://git-scm.com/docs/gitignore
22
/.bundle
3+
/coverage
34
/vendor

.rubocop.yml

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
11
# https://docs.rubocop.org/rubocop/configuration.html
2+
require:
3+
- rubocop-rspec
4+
25
AllCops:
36
NewCops: enable
47

@@ -9,4 +12,7 @@ Metrics/MethodLength:
912
Max: 20
1013

1114
Metrics/ParameterLists:
12-
Max: 10
15+
Max: 10
16+
17+
RSpec/MultipleExpectations:
18+
Max: 3

Gemfile

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,13 @@ source 'https://rubygems.org'
66
gem 'rackup', '~> 2.2'
77
gem 'sinatra', '~> 4.0'
88

9+
# Logging
10+
gem 'logger', '~> 1.6'
11+
912
group :development do
1013
# Code formatting & linting
1114
gem 'rubocop', '~> 1.22', require: false
15+
gem 'rubocop-rspec', '~> 3.2', require: false
1216

1317
# Sinatra utilities (e.g. live reload)
1418
gem 'sinatra-contrib', '~> 4.0'
@@ -18,3 +22,10 @@ group :production do
1822
# Ruby web server (https://puma.io)
1923
gem 'puma', '~> 6.0'
2024
end
25+
26+
group :test do
27+
gem 'nokogiri', '~> 1.16'
28+
gem 'rack-test', '~> 2.1'
29+
gem 'rspec', '~> 3.13'
30+
gem 'simplecov', '~> 0.22.0', require: false
31+
end

Gemfile.lock

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,27 @@ GEM
33
specs:
44
ast (2.4.2)
55
base64 (0.2.0)
6+
diff-lcs (1.5.1)
7+
docile (1.4.1)
68
json (2.8.1)
79
language_server-protocol (3.17.0.3)
10+
logger (1.6.1)
11+
mini_portile2 (2.8.7)
812
multi_json (1.15.0)
913
mustermann (3.0.3)
1014
ruby2_keywords (~> 0.0.1)
1115
nio4r (2.7.4)
16+
nokogiri (1.16.7)
17+
mini_portile2 (~> 2.8.2)
18+
racc (~> 1.4)
19+
nokogiri (1.16.7-aarch64-linux)
20+
racc (~> 1.4)
21+
nokogiri (1.16.7-arm64-darwin)
22+
racc (~> 1.4)
23+
nokogiri (1.16.7-x86_64-darwin)
24+
racc (~> 1.4)
25+
nokogiri (1.16.7-x86_64-linux)
26+
racc (~> 1.4)
1227
parallel (1.26.3)
1328
parser (3.3.6.0)
1429
ast (~> 2.4.1)
@@ -22,10 +37,25 @@ GEM
2237
rack (>= 3.0.0, < 4)
2338
rack-session (2.0.0)
2439
rack (>= 3.0.0)
40+
rack-test (2.1.0)
41+
rack (>= 1.3)
2542
rackup (2.2.0)
2643
rack (>= 3)
2744
rainbow (3.1.1)
2845
regexp_parser (2.9.2)
46+
rspec (3.13.0)
47+
rspec-core (~> 3.13.0)
48+
rspec-expectations (~> 3.13.0)
49+
rspec-mocks (~> 3.13.0)
50+
rspec-core (3.13.2)
51+
rspec-support (~> 3.13.0)
52+
rspec-expectations (3.13.3)
53+
diff-lcs (>= 1.2.0, < 2.0)
54+
rspec-support (~> 3.13.0)
55+
rspec-mocks (3.13.2)
56+
diff-lcs (>= 1.2.0, < 2.0)
57+
rspec-support (~> 3.13.0)
58+
rspec-support (3.13.1)
2959
rubocop (1.68.0)
3060
json (~> 2.3)
3161
language_server-protocol (>= 3.17.0)
@@ -38,8 +68,16 @@ GEM
3868
unicode-display_width (>= 2.4.0, < 3.0)
3969
rubocop-ast (1.34.1)
4070
parser (>= 3.3.1.0)
71+
rubocop-rspec (3.2.0)
72+
rubocop (~> 1.61)
4173
ruby-progressbar (1.13.0)
4274
ruby2_keywords (0.0.5)
75+
simplecov (0.22.0)
76+
docile (~> 1.1)
77+
simplecov-html (~> 0.11)
78+
simplecov_json_formatter (~> 0.1)
79+
simplecov-html (0.13.1)
80+
simplecov_json_formatter (0.1.4)
4381
sinatra (4.0.0)
4482
mustermann (~> 3.0)
4583
rack (>= 3.0.0, < 4)
@@ -59,15 +97,22 @@ PLATFORMS
5997
aarch64-linux-musl
6098
arm64-darwin-20
6199
arm64-darwin-21
100+
ruby
62101
x86_64-darwin-21
63102
x86_64-linux
64103

65104
DEPENDENCIES
105+
logger (~> 1.6)
106+
nokogiri (~> 1.16)
66107
puma (~> 6.0)
108+
rack-test (~> 2.1)
67109
rackup (~> 2.2)
110+
rspec (~> 3.13)
68111
rubocop (~> 1.22)
112+
rubocop-rspec (~> 3.2)
113+
simplecov (~> 0.22.0)
69114
sinatra (~> 4.0)
70115
sinatra-contrib (~> 4.0)
71116

72117
BUNDLED WITH
73-
2.2.32
118+
2.5.21

spec/fibscale_spec.rb

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
# frozen_string_literal: true
2+
3+
require 'nokogiri'
4+
require 'rspec'
5+
require 'spec_helper'
6+
7+
ENV['APP_ENV'] = 'test'
8+
9+
require './fibscale'
10+
11+
RSpec.describe 'FibScale' do
12+
def app
13+
Sinatra::Application
14+
end
15+
16+
it 'shows the home page' do
17+
get '/'
18+
expect(last_response).to be_ok
19+
20+
page = Nokogiri::HTML.parse(last_response.body)
21+
expect(page.css('title').text).to eq('FibScale')
22+
expect(page.css('#fib-number').first['value']).to eq('0')
23+
end
24+
25+
it 'shows the home page without error even if the configured delay is invalid' do
26+
get '/', delay: 'foo'
27+
expect(last_response).to be_ok
28+
29+
page = Nokogiri::HTML.parse(last_response.body)
30+
expect(page.css('title').text).to eq('FibScale')
31+
expect(page.css('#fib-number').first['value']).to eq('0')
32+
end
33+
34+
it 'shows an error on the home page if the delay is badly configured' do
35+
get '/', delay: '-1'
36+
expect(last_response).to be_ok
37+
expect(last_response.body).to include('Delay must be greater than or equal to zero.')
38+
end
39+
40+
%w[recursive iterative].each do |algorithm|
41+
[{ n: 0, label: '0th', fib: 0 }, { n: 1, label: '1st', fib: 1 }, { n: 2, label: '2nd', fib: 1 },
42+
{ n: 3, label: '3rd', fib: 2 }, { n: 4, label: '4th', fib: 3 }, { n: 5, label: '5th', fib: 5 },
43+
{ n: 6, label: '6th', fib: 8 }, { n: 7, label: '7th', fib: 13 }, { n: 8, label: '8th', fib: 21 },
44+
{ n: 9, label: '9th', fib: 34 }, { n: 10, label: '10th', fib: 55 }].each do |params|
45+
it "computes the #{params[:label]} fibonacci number with the #{algorithm} algorithm" do
46+
post '/', fib: params[:n], algorithm: algorithm
47+
expect(last_response).to be_ok
48+
expect(last_response.body).to include("The #{params[:label]} fibonacci number is:")
49+
50+
page = Nokogiri::HTML.parse(last_response.body)
51+
expect(page.css('.fib-result').text).to eq(params[:fib].to_s)
52+
end
53+
end
54+
end
55+
56+
it 'computes the 100th fibonacci number with the iterative algorithm' do
57+
post '/', fib: 100, algorithm: 'iterative'
58+
expect(last_response).to be_ok
59+
expect(last_response.body).to include('The 100th fibonacci number is:')
60+
61+
page = Nokogiri::HTML.parse(last_response.body)
62+
expect(page.css('.fib-result').text).to eq('354,224,848,179,261,915,075')
63+
end
64+
65+
it 'cannot compute a non-numeric fibonacci number' do
66+
post '/', fib: 'foo'
67+
expect(last_response).to be_ok
68+
expect(last_response.body).to include('Fibonacci number must be an integer.')
69+
end
70+
71+
it 'cannot compute a negative fibonacci number' do
72+
post '/', fib: -1
73+
expect(last_response).to be_ok
74+
expect(last_response.body).to include('Fibonacci number must be greater than or equal to zero.')
75+
end
76+
77+
it 'cannot compute a fibonacci number with an unknown algorithm' do
78+
post '/', fib: 1, algorithm: 'foo'
79+
expect(last_response).to be_ok
80+
expect(last_response.body).to include('Fibonacci algorithm must be one of: recursive, iterative.')
81+
end
82+
83+
it 'cannot compute a fibonacci number higher than 40 with the recursive algorithm by default' do
84+
post '/', fib: 41
85+
expect(last_response).to be_ok
86+
expect(last_response.body).to include(
87+
'Cannot compute fibonacci numbers beyond 40 with the recursive algorithm (it would be too slow).'
88+
)
89+
end
90+
91+
it 'cannot compute a fibonacci number higher than 10000 with the iterative algorithm by default' do
92+
post '/', fib: 10_001, algorithm: 'iterative'
93+
expect(last_response).to be_ok
94+
expect(last_response.body).to include('Cannot compute fibonacci numbers beyond 10000.')
95+
end
96+
97+
it 'cannot compute a fibonacci number with a negative delay' do
98+
post '/', fib: 1, delay: -2
99+
expect(last_response).to be_ok
100+
expect(last_response.body).to include('Delay must be greater than or equal to zero.')
101+
end
102+
end

spec/spec_helper.rb

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# frozen_string_literal: true
2+
3+
require 'rspec'
4+
require 'rack/test'
5+
require 'simplecov'
6+
7+
SimpleCov.start
8+
9+
RSpec.configure do |conf|
10+
conf.formatter = :documentation
11+
conf.include Rack::Test::Methods
12+
end

0 commit comments

Comments
 (0)