Skip to content
New issue

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

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature: Add testing exercises for RSpec lessons #54

Open
wants to merge 2 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions .rubocop.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
AllCops:
NewCops: enable
Exclude:
- 'ruby_basics/**/*'
Style/Documentation:
Enabled: false
5 changes: 4 additions & 1 deletion Gemfile
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
# frozen_string_literal: true

source 'https://rubygems.org'

gem 'rspec', '~>3.9'
gem 'rspec', '~> 3.10'
gem 'rubocop', '~> 1.21'
45 changes: 33 additions & 12 deletions Gemfile.lock
Original file line number Diff line number Diff line change
@@ -1,26 +1,47 @@
GEM
remote: https://rubygems.org/
specs:
ast (2.4.2)
diff-lcs (1.4.4)
rspec (3.9.0)
rspec-core (~> 3.9.0)
rspec-expectations (~> 3.9.0)
rspec-mocks (~> 3.9.0)
rspec-core (3.9.2)
rspec-support (~> 3.9.3)
rspec-expectations (3.9.2)
parallel (1.21.0)
parser (3.0.2.0)
ast (~> 2.4.1)
rainbow (3.0.0)
regexp_parser (2.1.1)
rexml (3.2.5)
rspec (3.10.0)
rspec-core (~> 3.10.0)
rspec-expectations (~> 3.10.0)
rspec-mocks (~> 3.10.0)
rspec-core (3.10.1)
rspec-support (~> 3.10.0)
rspec-expectations (3.10.1)
diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.9.0)
rspec-mocks (3.9.1)
rspec-support (~> 3.10.0)
rspec-mocks (3.10.2)
diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.9.0)
rspec-support (3.9.3)
rspec-support (~> 3.10.0)
rspec-support (3.10.2)
rubocop (1.21.0)
parallel (~> 1.10)
parser (>= 3.0.0.0)
rainbow (>= 2.2.2, < 4.0)
regexp_parser (>= 1.8, < 3.0)
rexml
rubocop-ast (>= 1.9.1, < 2.0)
ruby-progressbar (~> 1.7)
unicode-display_width (>= 1.4.0, < 3.0)
rubocop-ast (1.11.0)
parser (>= 3.0.1.1)
ruby-progressbar (1.11.0)
unicode-display_width (2.1.0)

PLATFORMS
ruby

DEPENDENCIES
rspec (~> 3.9)
rspec (~> 3.10)
rubocop (~> 1.21)

BUNDLED WITH
2.1.4
2 changes: 1 addition & 1 deletion ruby_basics/README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Ruby Basics Exercises
These exercises are designed to compliment the [Ruby Basic lessons](https://www.theodinproject.com/courses/ruby-programming#basic-ruby) on [The Odin Project](https://www.theodinproject.com/). Each folder contains exercises and specs(tests) for the lessons in the Ruby Basics section.
These exercises are designed to complement the [Ruby Basic lessons](https://www.theodinproject.com/courses/ruby-programming#basic-ruby) on [The Odin Project](https://www.theodinproject.com/). Each folder contains exercises and specs(tests) for the lessons in the Ruby Basics section.

### Usage

Expand Down
1 change: 1 addition & 0 deletions ruby_testing/1_rspec_basics/.rspec
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
--require spec_helper --format documentation --color
16 changes: 16 additions & 0 deletions ruby_testing/1_rspec_basics/spec/1_eq_matcher_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# frozen_string_literal: true

def generate_hashtag(str)
tag = str.split.map(&:capitalize).join
return nil unless tag.length.between?(1, 139)

"##{tag}"
end

RSpec.describe 'Eq Matcher Exercise' do
# Write a test that generate_hashtag('The Odin Project') eq '#TheOdinProject'

# Write a test that generate_hashtag('Ruby on Rails') eq '#RubyOnRails'

# Write a test that generate_hashtag('Join our Discord Community') eq '#JoinOurDiscordCommunity'
end
19 changes: 19 additions & 0 deletions ruby_testing/1_rspec_basics/spec/2_include_matcher_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# frozen_string_literal: true

def create_range(min, max)
(min..max).to_a
end

RSpec.describe 'Include Matcher Exercises' do
# Write a test that create_range(0, 5) includes 0, 1, 2, 3, 4, 5

# Write a test that create_range(0, 5) includes 3

# Write a test that create_range(0, 5) does not include 11

# Write a test that create_range(5, 10) includes 5, 6, 7, 8, 9, 10

# Write a test that create_range(5, 10) includes 5, 7, 9

# Write a test that create_range(5, 10) does not include 0 or 1
end
35 changes: 35 additions & 0 deletions ruby_testing/1_rspec_basics/spec/3_be_true_false_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
# frozen_string_literal: true

RSpec.describe 'Be True False Matcher Exercises' do
describe 'be truthy and falsy matcher' do
# Using the be matcher, write a test that any string, for example 'hello' is truthy

# Using the be matcher, write a test that any number, for example -100 is truthy

# Using the be matcher, write a test that any array, for example [] is truthy

# Using the be matcher, write a test that true is truthy

# Using the be matcher, write a test that false is falsy

# Using the be matcher, write a test that nil is falsy
end

# As you can see, almost all values are truthy, with the exception of false and nil.
# Therefore do not use 'be_truthy' or 'be_falsy' for methods that should only be evaluated into a Boolean.
# https://eddyluten.com/rspec-be_truthy-exists-or-be-true

def palindrome?(word)
word.reverse == word
end

describe 'be true and false matcher' do
# Using the be matcher, write a test that palindrome?('cat') is false

# Using the be matcher, write a test that palindrome?('level') is true

# Using the be matcher, write a test that palindrome?('racecar') is true

# Using the be matcher, write a test that palindrome?('odin') is false
end
end
18 changes: 18 additions & 0 deletions ruby_testing/1_rspec_basics/spec/4_be_nil_matcher_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# frozen_string_literal: true

def generate_hashtag(str)
tag = str.split.map(&:capitalize).join
return nil unless tag.length.between?(1, 139)

"##{tag}"
end

RSpec.describe 'Be Nil Matcher Exercises' do
# Using the be matcher, write a test that generate_hashtag('') is nil

# Using the be matcher, write a test that generate_hashtag('a' * 140) is nil

# Using the be matcher, write a test that generate_hashtag(' ' * 140) is nil

# Using the be matcher, write a test that generate_hashtag('The Odin Project') is not nil
end
15 changes: 15 additions & 0 deletions ruby_testing/1_rspec_basics/spec/5_contain_exactly_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# frozen_string_literal: true

def create_range(min, max)
(min..max).to_a
end

RSpec.describe 'Contain Exactly Matcher Exercises' do
# Write a test that create_range(0, 3) contains exactly 0, 1, 2, 3

# Write a test that create_range(0, 3) contains exactly 3, 2, 1, 0

# Write a test that create_range(0, 3) contains exactly 1, 3, 0, 2

# Write a test that create_range(0, 3) contains exactly 2, 0, 3, 1
end
19 changes: 19 additions & 0 deletions ruby_testing/1_rspec_basics/spec/spec_helper.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# frozen_string_literal: true

RSpec.configure do |config|
config.expect_with :rspec do |expectations|
expectations.include_chain_clauses_in_custom_matcher_descriptions = true
end

config.mock_with :rspec do |mocks|
mocks.verify_partial_doubles = true
end

config.shared_context_metadata_behavior = :apply_to_host_groups
end

module FormatterOverrides
def dump_pending(_); end
end

RSpec::Core::Formatters::DocumentationFormatter.prepend FormatterOverrides
1 change: 1 addition & 0 deletions ruby_testing/2_rspec_techniques/.rspec
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
--require spec_helper --format documentation --color
62 changes: 62 additions & 0 deletions ruby_testing/2_rspec_techniques/spec/1_equality_matchers_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
# frozen_string_literal: true

RSpec.describe 'Equality Matcher Exercises' do
describe 'eq and eql (equality matchers)' do
let(:my_score) { 10.0 } # Float
let(:your_score) { 10 } # Integer

context 'when using eq matcher' do
# NOTE: the eq matcher looks at the VALUE of the objects.

# Using the eq matcher, test that my_score is eq to your_score
end

context 'when using eql matcher' do
# NOTE: the eql matcher looks at the VALUE and the TYPE of the objects.

# Temporarily remove the 'x' from the following test, run this test, and read the error message.
# It fails because my_score and your_score do not have eql VALUE and TYPE.
xit 'has eql value and type' do
expect(my_score).to eql(your_score)
end

# Using the eql matcher, test that my_score is not eql to your_score
end
end

describe 'eql, equal, and be (equality matchers)' do
let(:my_car) { { year: 2013, make: 'Toyota', model: 'Camry' } }
let(:your_car) { { year: 2013, make: 'Toyota', model: 'Camry' } }
let(:my_kids_borrowed_car) { my_car }

context 'when using eql matcher' do
# Using the eql matcher, test that my_car is eql to your_car

# Using the eql matcher, test that my_kids_borrowed_car is eql to your_car
end

# Wait a second... my kids can borrow your car!?!

context 'when using equal matcher' do
# NOTE: the equal matcher looks at the OBJECT IDENTITY.

# Temporarily remove the 'x' from the following test, run this test, and read the error message.
# It fails because my_kids_borrowed_car and your_car do not have the same OBJECT IDENTITY.
xit 'has object identity' do
expect(my_kids_borrowed_car).to equal(your_car)
end

# Using the equal matcher, test that my_kids_borrowed_car is not equal to your_car
end

# Whew! I bet you're relieved that my kids can not borrow your car anymore!

context 'when using be matcher' do
# NOTE: the be matcher is similar to the equal matcher (looks at the OBJECT IDENTITY).

# Using the be matcher, test that my_kids_borrowed_car is my_car

# Using the be matcher, test that my_kids_borrowed_car is not your_car
end
end
end
79 changes: 79 additions & 0 deletions ruby_testing/2_rspec_techniques/spec/2_lesson_practice_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
# frozen_string_literal: true

# In a typical workflow, the class being tested will be located in a separate file from the tests.
# However, for this simple example, we are going to keep everything together.

class SchoolClub
attr_reader :count, :members

def initialize(name, members = [])
@name = name
@members = members
@count = members.length
end

def add_members(*names)
names.each do |name|
@members << name
@count += 1
end
end

def remove_members(*names)
names.each do |name|
next unless @members.include?(name)

@members.delete(name)
@count -= 1
end
end
end

RSpec.describe SchoolClub do
# Create a named subject with just a club name, for example SchoolClub.new('Robotics Club')

describe 'add_members' do
context 'when adding one new member' do
# Using a before block, add one member to the club. For example, robotics_club.add_members('Adam')

# Test the value of count, for example that robotics_club.count is 1

# Test the value of members, for example that robotics_club.members includes Adam
end

context 'when adding three new members' do
# Using a before block, add three members to the club.
# For example, robotics_club.add_members('Alice', 'Bob', 'Carrie')

# Test the value of count, for example that robotics_club.count is 3

# Test the value of members, for example that robotics_club.members includes Alice, Bob, and Carrie
end
end

describe 'remove_members' do
# Create a named subject with a club name and a founders variable that we will define in each context.
# For example SchoolClub.new('Chess Club', founders)

context 'when removing one member from two member club' do
# Create a let variable named founders that is an array with two names, for example, ['Adam', 'Beth']

# Using a before block, remove one member from the club. For example, chess_club.remove_members('Beth')

# Test the value of count, for example that chess_club.count is 1

# Test the value of members, for example that chess_club.members does not include Beth
end

context 'when removing two members from four member club' do
# Create another let variable named founders that is an array with four names.
# For example, ['Alice', 'Bob', 'Carrie', 'Dave']

# Using a before block, remove two members from the club. For example, chess_club.remove_members('Carrie', 'Dave')

# Test the value of count, for example that chess_club.count is 2

# Test the value of members, for example that chess_club.members does not include Carrie or Dave
end
end
end
19 changes: 19 additions & 0 deletions ruby_testing/2_rspec_techniques/spec/spec_helper.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# frozen_string_literal: true

RSpec.configure do |config|
config.expect_with :rspec do |expectations|
expectations.include_chain_clauses_in_custom_matcher_descriptions = true
end

config.mock_with :rspec do |mocks|
mocks.verify_partial_doubles = true
end

config.shared_context_metadata_behavior = :apply_to_host_groups
end

module FormatterOverrides
def dump_pending(_); end
end

RSpec::Core::Formatters::DocumentationFormatter.prepend FormatterOverrides
Loading