//
// RatPolyStackTest.swift
// RatNumTests
//
import XCTest
@testable import RatNum
/**
* This class contains a set of test cases that can be used to test the
* implementation of the RatPolyStack class.
*
* Some Test Methods are relatively longer in order to simulate proper stack functionality
*/
class RatPolyStackTest: XCTestCase {
// create a new poly that is a constant (doesn't depend on x)
private func constantPoly(_ constant : Int) -> RatPoly {
return RatPoly(c: constant, e: 0)
}
// create stack of single-digit constant polys
private func stack(_ desc : String) -> RatPolyStack {
let s = RatPolyStack()
for c in desc.reversed() {
let v: String = String(c)
let x: RatPoly = constantPoly(Int(v, radix:10)!)
s.push(x)
}
return s
}
// Compares 's' to a string describing its values.
// desc MUST be a sequence of decimal number chars.
// Example call: assertStackIs(myStack, "123")
//
// NOTE: THIS CAN FAIL WITH A WORKING STACK IF RatPoly.description IS BROKEN!
private func assertStackIs(_ s: RatPolyStack, _ desc: String, file: StaticString = #file, line: UInt = #line) -> Void {
XCTAssertEqual(desc.count, s.count)
let zipped = zip(s, desc).enumerated()
for (i,(p,num)) in zipped {
XCTAssertEqual(p,constantPoly(Int(String(num))!), "Elem \"(i) was \"(p), Expected \"(num), (Expected Stack:\"(desc)", file: file, line: line)
}
}
///////////////////////////////////////////////////////////////////////////////////////
//// Constructor
///////////////////////////////////////////////////////////////////////////////////////
public func testCtor() -> Void {
let stk1 = RatPolyStack()
XCTAssertEqual(0, stk1.count)
}
///////////////////////////////////////////////////////////////////////////////////////
//// Push
///////////////////////////////////////////////////////////////////////////////////////
public func testPush() -> Void {
let stk1 = RatPolyStack()
stk1.push(constantPoly(0))
assertStackIs(stk1, "0")
stk1.push(constantPoly(0))
assertStackIs(stk1, "00")
stk1.push(constantPoly(1))
assertStackIs(stk1, "100")
for s in ["3", "24", "134"] {
assertStackIs(stack(s), s)
}
}
public func testPushCheckForSharingTwixtStacks() -> Void {
let stk1 = RatPolyStack()
let stk2 = stack("123")
assertStackIs(stk1, "")
assertStackIs(stk2, "123")
stk1.push(constantPoly(0))
assertStackIs(stk1, "0")
assertStackIs(stk2, "123")
stk1.push(constantPoly(0))
assertStackIs(stk1, "00")
assertStackIs(stk2, "123")
stk1.push(constantPoly(1))
assertStackIs(stk1, "100")
assertStackIs(stk2, "123")
stk2.push(constantPoly(8))
assertStackIs(stk1, "100")
assertStackIs(stk2, "8123")
}
///////////////////////////////////////////////////////////////////////////////////////
//// Pop
///////////////////////////////////////////////////////////////////////////////////////
public func testPop() -> Void {
let stk1 = stack("123")
var poly = stk1.pop()
XCTAssertTrue(poly == constantPoly(1))
assertStackIs(stk1, "23")
poly = stk1.pop()
XCTAssertTrue(poly == constantPoly(2))
assertStackIs(stk1, "3")
poly = stk1.pop()
assertStackIs(stk1, "")
}
///////////////////////////////////////////////////////////////////////////////////////
//// Duplicate
///////////////////////////////////////////////////////////////////////////////////////
public func testDupWithOneVal() -> Void {
var stk1 = stack("3")
stk1.dup()
assertStackIs(stk1, "33")
stk1 = stack("123")
stk1.dup()
assertStackIs(stk1, "1123")
}
public func testDupWithTwoVal() -> Void {
let stk1 = stack("23")
stk1.dup()
assertStackIs(stk1, "223")
XCTAssertEqual(3, stk1.count)
XCTAssertTrue(stk1[indexFromTop: 0] == constantPoly(2))
XCTAssertTrue(stk1[indexFromTop: 1] == constantPoly(2))
XCTAssertTrue(stk1[indexFromTop: 2] == constantPoly(3))
}
public func testDupWithMultVal() -> Void {
let stk1 = stack("123")
stk1.dup()
assertStackIs(stk1, "1123")
}
///////////////////////////////////////////////////////////////////////////////////////
//// Swap
///////////////////////////////////////////////////////////////////////////////////////
public func testSwapWithTwoElems() -> Void {
let stk1 = stack("23")
stk1.swap()
assertStackIs(stk1, "32")
}
public func testSwapWithMultElems() -> Void {
let stk1 = stack("123")
stk1.swap()
assertStackIs(stk1, "213")
}
public func testSwapWitSameElems() -> Void {
let stk1 = stack("112")
stk1.swap()
assertStackIs(stk1, "112")
}
///////////////////////////////////////////////////////////////////////////////////////
//// Clear
///////////////////////////////////////////////////////////////////////////////////////
public func testClear() -> Void {
let stk1 = stack("123")
stk1.clear()
assertStackIs(stk1, "")
let stk2 = stack("112")
stk2.clear()
assertStackIs(stk2, "")
}
///////////////////////////////////////////////////////////////////////////////////////
//// Add
///////////////////////////////////////////////////////////////////////////////////////
public func testAddTwoElems() -> Void {
let stk1 = stack("11")
stk1.add()
assertStackIs(stk1, "2")
}
public func testAddMultiElems() -> Void {
var stk1 = stack("123")
stk1.add()
assertStackIs(stk1, "33")
stk1.add()
assertStackIs(stk1, "6")
stk1 = stack("112")
stk1.add()
assertStackIs(stk1, "22")
stk1.add()
assertStackIs(stk1, "4")
stk1.push(constantPoly(5))
assertStackIs(stk1, "54")
stk1.add()
assertStackIs(stk1, "9")
}
///////////////////////////////////////////////////////////////////////////////////////
//// Subtract
///////////////////////////////////////////////////////////////////////////////////////
public func testSubTwoElems() -> Void {
let stk1 = stack("12")
stk1.sub()
assertStackIs(stk1, "1")
}
public func testSubMultiElems() -> Void {
var stk1 = stack("123")
stk1.sub()
assertStackIs(stk1, "13")
stk1.sub()
assertStackIs(stk1, "2")
stk1 = stack("5723")
stk1.sub()
assertStackIs(stk1, "223")
stk1.sub()
assertStackIs(stk1, "03")
stk1.sub()
assertStackIs(stk1, "3")
}
///////////////////////////////////////////////////////////////////////////////////////
//// Multiplication
///////////////////////////////////////////////////////////////////////////////////////
public func testMulTwoElems() -> Void {
let stk1 = stack("23")
stk1.mul()
assertStackIs(stk1, "6")
}
public func testMulMultiElems() -> Void {
var stk1 = stack("123")
stk1.mul()
assertStackIs(stk1, "23")
stk1.mul()
assertStackIs(stk1, "6")
stk1 = stack("112")
stk1.mul()
assertStackIs(stk1, "12")
stk1.mul()
assertStackIs(stk1, "2")
stk1.push(constantPoly(4))
assertStackIs(stk1, "42")
stk1.mul()
assertStackIs(stk1, "8")
}
///////////////////////////////////////////////////////////////////////////////////////
//// Division
///////////////////////////////////////////////////////////////////////////////////////
public func testDivTwoElems() -> Void {
let stk1 = stack("28")
stk1.div()
assertStackIs(stk1, "4")
}
public func testDivMultiElems() -> Void {
let stk1 = stack("123")
stk1.div()
assertStackIs(stk1, "23")
}
///////////////////////////////////////////////////////////////////////////////////////
//// Differentiate
///////////////////////////////////////////////////////////////////////////////////////
public func testDifferentiate() -> Void {
let stk1 = stack("123")
stk1.differentiate()
stk1.differentiate()
stk1.differentiate()
stk1.differentiate()
XCTAssertEqual(3, stk1.count)
assertStackIs(stk1, "023")
let rp1 = RatPoly(c: 3, e: 5)
let rp2 = RatPoly(c: 7, e: 0)
let rp3 = RatPoly(c: 4, e: 1)
stk1.push(rp1)
stk1.push(rp2)
stk1.push(rp3)
stk1.differentiate()
XCTAssertEqual("4", stk1.pop().description)
stk1.differentiate()
XCTAssertEqual("0", stk1.pop().description)
stk1.differentiate()
XCTAssertEqual("15*x^4", stk1.pop().description)
}
///////////////////////////////////////////////////////////////////////////////////////
//// Integrate
///////////////////////////////////////////////////////////////////////////////////////
public func testIntegrate() -> Void {
let stk1 = stack("123")
stk1.integrate()
stk1.integrate()
stk1.integrate()
stk1.integrate()
XCTAssertEqual(3, stk1.count)
XCTAssertEqual("1/24*x^4", stk1.pop().description)
let rp1 = RatPoly(c: 15, e: 4)
let rp2 = RatPoly(c: 7, e: 0)
let rp3 = RatPoly(c: 4, e: 0)
stk1.push(rp1)
stk1.push(rp2)
stk1.push(rp3)
stk1.integrate()
XCTAssertEqual("4*x", stk1.pop().description)
stk1.integrate()
XCTAssertEqual("7*x", stk1.pop().description)
stk1.integrate()
XCTAssertEqual("3*x^5", stk1.pop().description)
}
}