Add tests to InfoCommandSpec

This commit is contained in:
Ben Chatelain 2019-01-07 18:33:03 -07:00
parent 96b3fb04b9
commit 77c37c77be
3 changed files with 123 additions and 4 deletions

View file

@ -13,12 +13,62 @@ import Nimble
class InfoCommandSpec: QuickSpec {
override func spec() {
let result = SearchResult(
bundleId: "",
currentVersionReleaseDate: "2019-01-07T18:53:13Z",
fileSizeBytes: "1024",
formattedPrice: "",
minimumOsVersion: "10.14",
price: 2.0,
sellerName: "Awesome Dev",
sellerUrl: "",
trackId: 1111,
trackCensoredName: "",
trackName: "Awesome App",
trackViewUrl: "https://awesome.app",
version: "1.0"
)
let storeSearch = StoreSearchMock()
let cmd = InfoCommand(storeSearch: storeSearch)
let expectedOutput = """
Awesome App 1.0 [2.0]
By: Awesome Dev
Released: Jan 7, 2019
Minimum OS: 10.14
Size: 1 KB
From: https://awesome.app
"""
describe("Info command") {
beforeEach {
storeSearch.reset()
}
it("fails to open app with invalid ID") {
let result = cmd.run(InfoCommand.Options(appId: "-999"))
expect(result).to(beFailure { error in
expect(error) == .searchFailed
})
}
it("can't find app with unknown ID") {
let result = cmd.run(InfoCommand.Options(appId: "999"))
expect(result).to(beFailure { error in
expect(error) == .noSearchResultsFound
})
}
it("displays app details") {
let cmd = InfoCommand()
let result = cmd.run(InfoCommand.Options(appId: ""))
print(result)
// expect(result).to(beSuccess())
storeSearch.apps[result.trackId] = result
let output = OutputListener()
output.openConsolePipe()
let result = cmd.run(InfoCommand.Options(appId: result.trackId.description))
expect(result).to(beSuccess())
waitUntil { done in
print(output.contents)
expect(output.contents) == expectedOutput
done()
}
}
}
}

View file

@ -0,0 +1,65 @@
//
// OutputListener.swift
// MasKitTests
//
// Created by Ben Chatelain on 1/7/19.
// Copyright © 2019 mas-cli. All rights reserved.
//
import Foundation
/// https://medium.com/@thesaadismail/eavesdropping-on-swifts-print-statements-57f0215efb42
class OutputListener {
// open a new Pipe to consume the messages on STDOUT and STDERR
let inputPipe = Pipe()
// open another Pipe to output messages back to STDOUT
let outputPipe = Pipe()
var contents = ""
func openConsolePipe() {
let pipeReadHandle = inputPipe.fileHandleForReading
//from documentation
//dup2() makes newfd (new file descriptor) be the copy of oldfd (old file descriptor), closing newfd first if necessary.
//here we are copying the STDOUT file descriptor into our output pipe's file descriptor
//this is so we can write the strings back to STDOUT, so it can show up on the xcode console
dup2(STDOUT_FILENO, outputPipe.fileHandleForWriting.fileDescriptor)
//In this case, the newFileDescriptor is the pipe's file descriptor and the old file descriptor is STDOUT_FILENO and STDERR_FILENO
dup2(inputPipe.fileHandleForWriting.fileDescriptor, STDOUT_FILENO)
dup2(inputPipe.fileHandleForWriting.fileDescriptor, STDERR_FILENO)
//listen in to the readHandle notification
NotificationCenter.default.addObserver(self, selector: #selector(self.handlePipeNotification), name: FileHandle.readCompletionNotification, object: pipeReadHandle)
//state that you want to be notified of any data coming across the pipe
pipeReadHandle.readInBackgroundAndNotify()
}
@objc func handlePipeNotification(notification: Notification) {
//note you have to continuously call this when you get a message
//see this from documentation:
//Note that this method does not cause a continuous stream of notifications to be sent. If you wish to keep getting notified, youll also need to call readInBackgroundAndNotify() in your observer method.
inputPipe.fileHandleForReading.readInBackgroundAndNotify()
if let userInfo = notification.userInfo,
let data = userInfo[NSFileHandleNotificationDataItem] as? Data,
let str = String(data: data, encoding: String.Encoding.ascii) {
contents += str
//write the data back into the output pipe. the output pipe's write file descriptor points to STDOUT. this allows the logs to show up on the xcode console
outputPipe.fileHandleForWriting.write(data)
// `str` here is the log/contents of the print statement
//if you would like to route your print statements to the UI: make
//sure to subscribe to this notification in your VC and update the UITextView.
//Or if you wanted to send your print statements to the server, then
//you could do this in your notification handler in the app delegate.
}
}
}

View file

@ -38,6 +38,7 @@
B576FE1D21E28EF70016B39D /* URLSessionDataTaskMock.swift in Sources */ = {isa = PBXBuildFile; fileRef = B576FE1C21E28EF70016B39D /* URLSessionDataTaskMock.swift */; };
B576FE2821E423E60016B39D /* Dictionary+StringOrEmpty.swift in Sources */ = {isa = PBXBuildFile; fileRef = B576FE2721E423E60016B39D /* Dictionary+StringOrEmpty.swift */; };
B576FE2A21E4240B0016B39D /* AppInfoFormatter.swift in Sources */ = {isa = PBXBuildFile; fileRef = B576FE2921E4240B0016B39D /* AppInfoFormatter.swift */; };
B576FE2C21E42A230016B39D /* OutputListener.swift in Sources */ = {isa = PBXBuildFile; fileRef = B576FE2B21E42A230016B39D /* OutputListener.swift */; };
B5793E29219BDD4800135B39 /* JSON in Resources */ = {isa = PBXBuildFile; fileRef = B5793E28219BDD4800135B39 /* JSON */; };
B588CE0221DC89490047D305 /* ExternalCommand.swift in Sources */ = {isa = PBXBuildFile; fileRef = B588CE0121DC89490047D305 /* ExternalCommand.swift */; };
B588CE0421DC8AFB0047D305 /* TrashCommand.swift in Sources */ = {isa = PBXBuildFile; fileRef = B588CE0321DC8AFB0047D305 /* TrashCommand.swift */; };
@ -219,6 +220,7 @@
B576FE1C21E28EF70016B39D /* URLSessionDataTaskMock.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = URLSessionDataTaskMock.swift; sourceTree = "<group>"; };
B576FE2721E423E60016B39D /* Dictionary+StringOrEmpty.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Dictionary+StringOrEmpty.swift"; sourceTree = "<group>"; };
B576FE2921E4240B0016B39D /* AppInfoFormatter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppInfoFormatter.swift; sourceTree = "<group>"; };
B576FE2B21E42A230016B39D /* OutputListener.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = OutputListener.swift; sourceTree = "<group>"; };
B5793E28219BDD4800135B39 /* JSON */ = {isa = PBXFileReference; lastKnownFileType = folder; path = JSON; sourceTree = "<group>"; };
B588CE0121DC89490047D305 /* ExternalCommand.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExternalCommand.swift; sourceTree = "<group>"; };
B588CE0321DC8AFB0047D305 /* TrashCommand.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TrashCommand.swift; sourceTree = "<group>"; };
@ -638,6 +640,7 @@
B576FE0A21E116470016B39D /* Network */,
B576FE1821E28E460016B39D /* Nimble */,
B576FE2621E29DD90016B39D /* SupportingFiles */,
B576FE2B21E42A230016B39D /* OutputListener.swift */,
);
path = MasKitTests;
sourceTree = "<group>";
@ -932,6 +935,7 @@
B576FDF321E03B780016B39D /* MasStoreSearchSpec.swift in Sources */,
B576FE0C21E116590016B39D /* NetworkManagerTests.swift in Sources */,
B576FE1B21E28E8A0016B39D /* NetworkSessionMock.swift in Sources */,
B576FE2C21E42A230016B39D /* OutputListener.swift in Sources */,
B576FE1221E1D82D0016B39D /* NetworkSessionMockFromFile.swift in Sources */,
B5DBF81321DEEC7C00F3B151 /* OpenCommandSpec.swift in Sources */,
B5DBF81721E02E3400F3B151 /* OpenSystemCommandMock.swift in Sources */,