Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
5fe3b34
Moved nested .framework dir to replace the high level .framework dire…
doanceaep Apr 28, 2016
2f7d480
Merge pull request #5 from doancea/release-fix
joshmg Jul 27, 2016
7f7e498
New mocker styles to support swift 3; also nimble extensions
keitzer Feb 23, 2017
03d6718
Merge pull request #6 from keitzer/master
joshmg Feb 23, 2017
f3c1dd8
MOBEE-1075: Add shared data
doancea-wiser Jan 28, 2022
0a8e539
MOBEE-1075: Renaming
doancea-wiser Jan 28, 2022
b5d89db
MOBEE-1075: Streamlining library for mocking only
doancea-wiser Jan 28, 2022
0a744f5
Merge branch 'master' of github.com:PillarTechnology/swiftlibs into M…
doancea-wiser Jan 28, 2022
0e744f4
MOBEE-1075: re-add matchers to project
doancea-wiser Jan 28, 2022
7e3bdd1
MOBEE-1075: Streamline project to contain mocks only, added nimble as…
doancea-wiser Jan 28, 2022
d322ba0
MOBEE-1075: MockedMethod naming support added to replace raw strings
doancea-wiser Jan 28, 2022
ce7a0ec
MOBEE-1075: Recommended project settings
doancea-wiser Jan 28, 2022
a56ac4c
MOBEE-1075: Begin converting deprecated matcherfunc nimble matchers
doancea-wiser Jan 28, 2022
3c28c7d
MOBEE-1075: Renamed
doancea-wiser Jan 28, 2022
d4f7827
MOBEE-1075: Converted all custom matchers
doancea-wiser Jan 28, 2022
dda7307
MOBEE-1075: Comments
doancea-wiser Jan 28, 2022
7fc47b7
Project cleanup and package structure
doancea-wiser Jan 28, 2022
8343165
MOBEE-1075: Package updates
doancea-wiser Jan 31, 2022
2624059
Merge pull request #1 from WiserSolutions/MOBEE-1075
doancea-wiser Jan 31, 2022
8343fc2
MOBEE-1075: not sure but looks helpful
doancea-wiser Jan 31, 2022
07a02e2
MOBEE-1075: rename target to match package specification
doancea-wiser Feb 2, 2022
d90cfcc
MOBEE-1975: remove test target, troubleshooting
doancea-wiser Feb 2, 2022
dfa9787
MOBEE-1075: Syntax
doancea-wiser Feb 2, 2022
921d92b
MOBEE-1075: Packgage troubleshooting
doancea-wiser Feb 2, 2022
544f804
MOBEE-1075: Packgage troubleshooting
doancea-wiser Feb 2, 2022
273b8c3
MOBEE-1075: Package declaration location
doancea-wiser Feb 2, 2022
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
21 changes: 0 additions & 21 deletions LICENSE

This file was deleted.

31 changes: 31 additions & 0 deletions Package.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// swift-tools-version:5.5
// The swift-tools-version declares the minimum version of Swift required to build this package.

import PackageDescription

let package = Package(
name: "WiseMock",
platforms: [
.macOS(.v10_10), .iOS(.v12)
],
products: [
// Products define the executables and libraries a package produces, and make them visible to other packages.
.library(
name: "WiseMock",
targets: ["WiseMock"]),
],
dependencies: [
.package(url: "https://github.com/Quick/Nimble.git", from: "9.2.1"),
],
targets: [
// Targets are the basic building blocks of a package. A target can define a module or a test suite.
// Targets can depend on other targets in this package, and on products in packages this package depends on.
.target(
name: "WiseMock",
dependencies: [
.product(name: "Nimble", package: "Nimble",
condition: .when(platforms: [.macOS, .iOS])),
]
)
]
)
34 changes: 0 additions & 34 deletions README
Original file line number Diff line number Diff line change
@@ -1,34 +0,0 @@
This framework provides:
- iOS Mocker
- WebRequest
- HTTP MultiPart
- HTTP Methods (ex. GET/POST/PUT/etc)
- HTTP-Redirection
- Mock WebRequest
- Util Functions
- DataFromHexString
- SplitString

IMPORTANT:
This project contains two frameworks, one for development and another for production.
The production version is portable to the Apple App Store, but is incompatible with iOS-Simulators.
The development version is compatible with both iOS-Devices and the iOS-Simulators, but is NOT compatible with the Apple App Store.


Build:
Development (Non App Store):
1. Select the "SwiftLibsFramework" project from the target-menu.
2. Select any non-generic simulator from the build-target. (i.e. "iPhone 5s")
3. Copy the built framework from bin/development into your project's directory.
4. Add the framework as an embedded-binary into your application.
Production (App Store):
1. Select the "SwiftLibsFrameworkProduction" project from the target-menu.
2. Select any the generic simulator from the build-target. (i.e. "Generic iOS Device")
3. Copy the built framework from bin/production into your project's directory.
4. Add the framework as an embedded-binary into your application.


Pre-Built Binaries:
Located:
./release/<version>/

7 changes: 7 additions & 0 deletions Sources/WiseMock/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
.DS_Store
/.build
/Packages
/*.xcodeproj
xcuserdata/
DerivedData/
.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
<string>1.0.5</string>
<string>$(MARKETING_VERSION)</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
Expand Down
55 changes: 55 additions & 0 deletions Sources/WiseMock/Mockable.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import Foundation

public protocol Mockable {
associatedtype MockedMethod: RawRepresentable where MockedMethod.RawValue == String

var mocker: Mocker { get set }

func record(invocation: MockedMethod, with parameters: Any?...)
func invocationCount(for name: MockedMethod) -> Int
func parameters(for name: MockedMethod, at index: Int) -> [Any]
func parameter<T>(for name: MockedMethod, at index: Int, andInvocation invocation: Int) -> T?
func setReturnValue(for name: MockedMethod, with value: Any?, index: Int)
func returnValue<T>(for name: MockedMethod) -> T?
func reset()
}

public extension Mockable {

func record(invocation name: MockedMethod, with parameters: Any?...) {
mocker.recordInvocation(name.rawValue, paramList: parameters as [Any?])
}

func invocationCount(for name: MockedMethod) -> Int {
return mocker.getInvocationCountFor(name.rawValue)
}

func parameters(for name: MockedMethod, at index: Int = 0) -> [Any] {
return mocker.getParametersFor(name.rawValue, n: index) ?? []
}

func parameter<T>(for name: MockedMethod, at index: Int, andInvocation invocation: Int = 0) -> T? {
return parameters(for: name, at: invocation).value(at: index) as? T
}

func setReturnValue(for name: MockedMethod, with value: Any?, index: Int = -1) {
mocker.setReturnValueFor(name.rawValue, returnValue: value, n: index)
}

func returnValue<T>(for name: MockedMethod) -> T? {
return mocker.getReturnValueFor(name.rawValue) as? T
}

func reset() {
mocker.reset()
}
}

private extension Array {
func value(at index: Int) -> Element? {
guard index >= 0 && index < endIndex else {
return nil
}
return self[index]
}
}
82 changes: 82 additions & 0 deletions Sources/WiseMock/Mocker.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
import UIKit
protocol iMocker {
associatedtype MethodName_t = String
associatedtype ParamList_t = Array<Any>
associatedtype ReturnType_t = Any
func setReturnValueFor(_ methodName : MethodName_t, returnValue : ReturnType_t?, n : Int)
func getReturnValueFor(_ methodName : MethodName_t) -> ReturnType_t?
func getParametersFor(_ methodName : MethodName_t, n : Int) -> ParamList_t?
func getInvocationCountFor(_ methodName : MethodName_t) -> Int
func recordInvocation(_ methodName : MethodName_t, paramList : ParamList_t?)
func reset()
}

private extension Array {
func get(at i: Index) -> Element? {
var count = 0
for item in self {
if count == i {
return item
}
count += 1
}
return nil
}
}
open class Mocker : NSObject, iMocker {
public typealias MethodName_t = String
public typealias ParamList_t = Array<Any>
public typealias ReturnType_t = Any

var invocationParameterArray = Dictionary<MethodName_t, Array<ParamList_t?>>()
var definedReturnValues = Dictionary<MethodName_t, Array<ReturnType_t?>>()
var definedReturnValueRequestCount = Dictionary<MethodName_t, Int>()
// If unspecified (or negative), n will append the returnValue to the queue of returnValues
// If specified, n will override the already-specified returnValue
open func setReturnValueFor(_ methodName : MethodName_t, returnValue : ReturnType_t?, n : Int = -1) {
if (definedReturnValues[methodName] == nil) {
definedReturnValues[methodName] = Array<ReturnType_t?>()
definedReturnValueRequestCount[methodName] = 0
}
if (n < 0) {
definedReturnValues[methodName]!.append(returnValue)
}
else {
definedReturnValues[methodName]![n] = returnValue
}
}
open func getReturnValueFor(_ methodName : MethodName_t) -> ReturnType_t? {
guard let requestCount = definedReturnValueRequestCount[methodName],
let returnValues = definedReturnValues[methodName] else {
return nil
}
definedReturnValueRequestCount[methodName] = requestCount + 1
assert(returnValues.count > 0, "Could not return \(requestCount)th value for \(methodName); no return values were set.")
if requestCount < returnValues.count {
return returnValues[requestCount]
}
else {
return returnValues[returnValues.count - 1]
}
}
open func getParametersFor(_ methodName : MethodName_t, n : Int = 0) -> ParamList_t? {
guard let methodName = invocationParameterArray[methodName] else { return nil }
let parametersForAllInvocations : Array<ParamList_t?> = methodName
return parametersForAllInvocations.get(at: n) ?? nil
}
open func getInvocationCountFor(_ methodName : MethodName_t) -> Int {
let parametersForAllInvocations : Array<ParamList_t?>? = invocationParameterArray[methodName]
return ( (parametersForAllInvocations == nil) ? 0 : parametersForAllInvocations!.count )
}
open func recordInvocation(_ methodName : MethodName_t, paramList : ParamList_t? = []) {
if (invocationParameterArray[methodName] == nil) {
invocationParameterArray[methodName] = Array<ParamList_t?>()
}
invocationParameterArray[methodName]!.append(paramList)
}
open func reset() {
invocationParameterArray.removeAll(keepingCapacity: false)
definedReturnValues.removeAll(keepingCapacity: false)
definedReturnValueRequestCount.removeAll(keepingCapacity: false)
}
}
83 changes: 83 additions & 0 deletions Sources/WiseMock/NimbleMatchers.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
import Foundation
import Nimble

///Invocation Count
public func invoke<T: Mockable>(_ name: T.MockedMethod, times: Int = 1) -> Predicate<T> {

return Predicate<T>.define { actualExpression in
var expectationMessage: ExpectationMessage!
var status: PredicateStatus!

if let mockable = try? actualExpression.evaluate() {
let failureExpectationMessage = "invoke \(name) \(times) times"
let actualMessage = "\(mockable.invocationCount(for: name)) invocations"
status = PredicateStatus(bool: mockable.invocationCount(for: name) == times)
expectationMessage = .expectedCustomValueTo(failureExpectationMessage, actual: actualMessage)
} else {
status = .fail
expectationMessage = .fail("something else happened")
}
return PredicateResult(status: status, message: expectationMessage)
}

}

///Equality
public func invoke<T: Mockable, E: Equatable>(_ name: T.MockedMethod, atInvocation invocationIndex: Int = 0, withParameter parameter: E?, at parameterIndex: Int = 0) -> Predicate<T> {
return Predicate<T>.define { actualExpression in
var expectationMessage: ExpectationMessage!
var status: PredicateStatus!

if let mockable = try? actualExpression.evaluate() {
let actualParameter: E? = mockable.parameter(for: name, at: parameterIndex, andInvocation: invocationIndex)
let actualMessage = String(describing: actualParameter)

expectationMessage = .expectedActualValueTo(actualMessage)
status = PredicateStatus(bool: actualParameter == parameter)
} else {
status = .fail
expectationMessage = .fail("something else happened")
}
return PredicateResult(status: status, message: expectationMessage)
}

}

///Identity
public func invoke<T: Mockable, E: AnyObject>(_ name: T.MockedMethod, atInvocation invocationIndex: Int = 0, withIdenticalParameter parameter: E?, at parameterIndex: Int = 0) -> Predicate<T> {
return Predicate<T>.define { actualExpression in
var expectationMessage: ExpectationMessage!
var status: PredicateStatus!

if let mockable = try? actualExpression.evaluate() {
let actualParameter: E? = mockable.parameter(for: name, at: parameterIndex, andInvocation: invocationIndex)
let actualMessage = String(describing: actualParameter)

expectationMessage = .expectedActualValueTo(actualMessage)
status = PredicateStatus(bool: actualParameter === parameter)
} else {
status = .fail
expectationMessage = .fail("something else happened")
}
return PredicateResult(status: status, message: expectationMessage)
}
}

/// Closure Matcher
public func invoke<T: Mockable, U>(_ name: T.MockedMethod, atInvocation invocationIndex: Int = 0, atParameterIndex parameterIndex: Int = 0, withMatcher matcher: @escaping ((U?) -> Bool)) -> Predicate<T> {
return Predicate<T>.define { actualExpression in
var expectationMessage: ExpectationMessage!
var status: PredicateStatus!

if let mockable = try? actualExpression.evaluate() {
let actualParameter: U? = mockable.parameter(for: name, at: parameterIndex, andInvocation: invocationIndex)

expectationMessage = .fail("parameter as \(String(describing: actualParameter)) does not match")
status = PredicateStatus(bool: matcher(actualParameter))
} else {
status = .fail
expectationMessage = .fail("something else happened")
}
return PredicateResult(status: status, message: expectationMessage)
}
}
3 changes: 3 additions & 0 deletions Sources/WiseMock/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# WiseMock

A description of this package.
File renamed without changes.
Loading