Skip to content
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
20 changes: 16 additions & 4 deletions UnitTests.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,12 @@
B18A153528C3DD6600D23165 /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = B18A153328C3DD6600D23165 /* Main.storyboard */; };
B18A153728C3DD6900D23165 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = B18A153628C3DD6900D23165 /* Assets.xcassets */; };
B18A153A28C3DD6900D23165 /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = B18A153828C3DD6900D23165 /* LaunchScreen.storyboard */; };
B18A154528C3DD6900D23165 /* UnitTestsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B18A154428C3DD6900D23165 /* UnitTestsTests.swift */; };
B18A154F28C3DD6900D23165 /* UnitTestsUITests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B18A154E28C3DD6900D23165 /* UnitTestsUITests.swift */; };
B18A155128C3DD6900D23165 /* UnitTestsUITestsLaunchTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B18A155028C3DD6900D23165 /* UnitTestsUITestsLaunchTests.swift */; };
B1AA319128C4B653006FB275 /* Player.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1AA319028C4B653006FB275 /* Player.swift */; };
B1AA319328C4BB2A006FB275 /* PlayerUnitTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1AA319228C4BB2A006FB275 /* PlayerUnitTests.swift */; };
B1AA319528C4CB3B006FB275 /* AsyncTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1AA319428C4CB3B006FB275 /* AsyncTests.swift */; };
B1AA319728C4D0AF006FB275 /* URlSessionMocks.swift in Sources */ = {isa = PBXBuildFile; fileRef = B1AA319628C4D0AF006FB275 /* URlSessionMocks.swift */; };
/* End PBXBuildFile section */

/* Begin PBXContainerItemProxy section */
Expand Down Expand Up @@ -45,10 +48,13 @@
B18A153928C3DD6900D23165 /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
B18A153B28C3DD6900D23165 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
B18A154028C3DD6900D23165 /* UnitTestsTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = UnitTestsTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
B18A154428C3DD6900D23165 /* UnitTestsTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UnitTestsTests.swift; sourceTree = "<group>"; };
B18A154A28C3DD6900D23165 /* UnitTestsUITests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = UnitTestsUITests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
B18A154E28C3DD6900D23165 /* UnitTestsUITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UnitTestsUITests.swift; sourceTree = "<group>"; };
B18A155028C3DD6900D23165 /* UnitTestsUITestsLaunchTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UnitTestsUITestsLaunchTests.swift; sourceTree = "<group>"; };
B1AA319028C4B653006FB275 /* Player.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Player.swift; sourceTree = "<group>"; };
B1AA319228C4BB2A006FB275 /* PlayerUnitTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlayerUnitTests.swift; sourceTree = "<group>"; };
B1AA319428C4CB3B006FB275 /* AsyncTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AsyncTests.swift; sourceTree = "<group>"; };
B1AA319628C4D0AF006FB275 /* URlSessionMocks.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = URlSessionMocks.swift; sourceTree = "<group>"; };
/* End PBXFileReference section */

/* Begin PBXFrameworksBuildPhase section */
Expand Down Expand Up @@ -106,14 +112,17 @@
B18A153628C3DD6900D23165 /* Assets.xcassets */,
B18A153828C3DD6900D23165 /* LaunchScreen.storyboard */,
B18A153B28C3DD6900D23165 /* Info.plist */,
B1AA319028C4B653006FB275 /* Player.swift */,
B1AA319628C4D0AF006FB275 /* URlSessionMocks.swift */,
);
path = UnitTests;
sourceTree = "<group>";
};
B18A154328C3DD6900D23165 /* UnitTestsTests */ = {
isa = PBXGroup;
children = (
B18A154428C3DD6900D23165 /* UnitTestsTests.swift */,
B1AA319228C4BB2A006FB275 /* PlayerUnitTests.swift */,
B1AA319428C4CB3B006FB275 /* AsyncTests.swift */,
);
path = UnitTestsTests;
sourceTree = "<group>";
Expand Down Expand Up @@ -260,6 +269,8 @@
files = (
B18A153228C3DD6600D23165 /* ViewController.swift in Sources */,
B18A152E28C3DD6600D23165 /* AppDelegate.swift in Sources */,
B1AA319128C4B653006FB275 /* Player.swift in Sources */,
B1AA319728C4D0AF006FB275 /* URlSessionMocks.swift in Sources */,
B18A153028C3DD6600D23165 /* SceneDelegate.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
Expand All @@ -268,7 +279,8 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
B18A154528C3DD6900D23165 /* UnitTestsTests.swift in Sources */,
B1AA319528C4CB3B006FB275 /* AsyncTests.swift in Sources */,
B1AA319328C4BB2A006FB275 /* PlayerUnitTests.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down
5 changes: 5 additions & 0 deletions UnitTests/Assets.xcassets/AppIcon.appiconset/Contents.json
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,11 @@
"scale" : "2x",
"size" : "40x40"
},
{
"idiom" : "ipad",
"scale" : "1x",
"size" : "76x76"
},
{
"idiom" : "ipad",
"scale" : "2x",
Expand Down
54 changes: 54 additions & 0 deletions UnitTests/Player.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
//
// Player.swift
// UnitTests
//
// Created by Nishchal Visavadiya on 04/09/22.
//

import Foundation

/**
* A model class to represent a player in the game
*/
class Player {

private(set) var health = 100
/**
* Represent the hit power of the plyer,
* i.e. how muhc damage this player can do in one hit
*/
private(set) var hitPower = 10
/**
* Whether the player is dead or not
*/
var isDead: Bool {
get {
return health <= 0
}
}

/**
* Increments the `hitPower` of self
*
* - Parameter inc: The increment value
*
* - Returns: New hit power
*/
func increaseHitPowerBy(inc: Int) -> Int {
hitPower += inc
return hitPower
}

/**
* Hits the playr passed in parameter with Player.hitPower
*
* - Parameter player: The player to hit
*
* - Returns: Whether the hit was successful or not
*/
func hit(player: Player) -> Bool {
if player.isDead { return false }
player.health -= hitPower
return true
}
}
72 changes: 72 additions & 0 deletions UnitTests/URlSessionMocks.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
//
// URlSessionMocks.swift
// UnitTests
//
// Created by Nishchal Visavadiya on 04/09/22.
//

import Foundation

typealias CompletionHandler = (Data?, URLResponse?, Error?) -> Void

protocol URLSessionProtocol {

associatedtype DataTaskType

func dataTask(
with url: URL,
completionHandler: @escaping CompletionHandler
) -> DataTaskType
}

extension URLSession: URLSessionProtocol {}

protocol URLSessionDataTaskProtocol {
func resume()
}

extension URLSessionDataTask: URLSessionDataTaskProtocol {}

class URLSessionDataTaskMock: URLSessionDataTaskProtocol {

private let completion: CompletionHandler
private let data: Data?
private let error: Error?
private let response: URLResponse?

init(
data: Data?,
error: Error?,
response: URLResponse?,
completion: @escaping CompletionHandler
) {
self.data = data
self.error = error
self.response = response
self.completion = completion
}

func resume() {
completion(data, response, error)
}
}

class URLSessionMock: URLSessionProtocol {

// data and error can be set to provide data or an error
var data: Data?
var error: Error?
var response: URLResponse?

func dataTask(
with url: URL,
completionHandler: @escaping CompletionHandler
) -> URLSessionDataTaskMock {
return URLSessionDataTaskMock(
data: data,
error: error,
response: response,
completion: completionHandler
)
}
}
47 changes: 47 additions & 0 deletions UnitTestsTests/AsyncTests.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
//
// AsyncTests.swift
// UnitTestsTests
//
// Created by Nishchal Visavadiya on 04/09/22.
//

import XCTest
@testable import UnitTests

class AsyncTests: XCTestCase {

var sut: URLSessionMock!

override func setUpWithError() throws {
try super.setUpWithError()
sut = URLSessionMock()
}

func testApiCallCompletes() throws {
// given
let urlString = "http://www.randomnumberapi.com/test"
let url = URL(string: urlString)!
let promise = expectation(description: "Completion handler invoked")
var statusCode: Int?
var responseError: Error?

// when
sut.response = HTTPURLResponse(url: url, statusCode: 200, httpVersion: nil, headerFields: nil)
let dataTask = sut.dataTask(with: url) { _, response, error in
statusCode = (response as? HTTPURLResponse)?.statusCode
responseError = error
promise.fulfill()
}
dataTask.resume()
wait(for: [promise], timeout: 5)

// then
XCTAssertNil(responseError)
XCTAssertEqual(statusCode, 200)
}

override func tearDownWithError() throws {
sut = nil
try super.tearDownWithError()
}
}
62 changes: 62 additions & 0 deletions UnitTestsTests/PlayerUnitTests.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
//
// PlayerUnitTests.swift
// UnitTestsTests
//
// Created by Nishchal Visavadiya on 04/09/22.
//

import Foundation
import XCTest
@testable import UnitTests

class PlayerUnitTests: XCTestCase {

private var sut: Player!

override func setUpWithError() throws {
try super.setUpWithError()
sut = Player()
}

func testHitPowerShouldIncrementBasedOnValueProvided() {
// Given
let oldHitPower = sut.hitPower

// When
let newHitPower = sut.increaseHitPowerBy(inc: 10)

// Then
XCTAssert(newHitPower == oldHitPower + 10, "Old hit power is incresed by value provided")
}

func testPlayerCanHitAnotherOneIfNotDead() {
// Given
let anotherPlayer = Player()
XCTAssert(!anotherPlayer.isDead)

// When
let hitSuccessfull = sut.hit(player: anotherPlayer)

// Then
XCTAssert(hitSuccessfull == true, "Couuld no dealt damage")
}

func testPlayerShouldBeDeadAfterHealtIsDepleted() {
// Given
let anotherPlayer = Player()
XCTAssert(!anotherPlayer.isDead)

// When
_ = sut.increaseHitPowerBy(inc: 100)
let hitSuccessfull = sut.hit(player: anotherPlayer)

// Then
XCTAssert(hitSuccessfull == true, "Could no dealt damage")
XCTAssert(anotherPlayer.isDead == true, "Player is not dead even after health less or equal to 0")
}

override func tearDownWithError() throws {
sut = nil
try super.tearDownWithError()
}
}
36 changes: 0 additions & 36 deletions UnitTestsTests/UnitTestsTests.swift

This file was deleted.