Passing about half of the MathListTest tests. Need to work on copy-related tests.
Currently the copy() is not working.
This commit is contained in:
@@ -120,7 +120,7 @@ public class MTMathAtomFactory {
|
||||
return _accentValueToName!
|
||||
}
|
||||
|
||||
public static var supportedLatexSymbols: [String: MTMathAtom] = [
|
||||
static var supportedLatexSymbols: [String: MTMathAtom] = [
|
||||
"square" : MTMathAtomFactory.placeholder(),
|
||||
|
||||
// Greek characters
|
||||
@@ -448,35 +448,16 @@ public class MTMathAtomFactory {
|
||||
|
||||
public static func fontNameForStyle(_ fontStyle:MTFontStyle) -> String {
|
||||
switch fontStyle {
|
||||
case .defaultStyle:
|
||||
return "mathnormal";
|
||||
|
||||
case .roman:
|
||||
return "mathrm";
|
||||
|
||||
case .bold:
|
||||
return "mathbf";
|
||||
|
||||
case .fraktur:
|
||||
return "mathfrak";
|
||||
|
||||
case .caligraphic:
|
||||
return "mathcal";
|
||||
|
||||
case .italic:
|
||||
return "mathit";
|
||||
|
||||
case .sansSerif:
|
||||
return "mathsf";
|
||||
|
||||
case .blackboard:
|
||||
return "mathbb";
|
||||
|
||||
case .typewriter:
|
||||
return "mathtt";
|
||||
|
||||
case .boldItalic:
|
||||
return "bm";
|
||||
case .defaultStyle: return "mathnormal"
|
||||
case .roman: return "mathrm"
|
||||
case .bold: return "mathbf"
|
||||
case .fraktur: return "mathfrak"
|
||||
case .caligraphic: return "mathcal"
|
||||
case .italic: return "mathit"
|
||||
case .sansSerif: return "mathsf"
|
||||
case .blackboard: return "mathbb"
|
||||
case .typewriter: return "mathtt"
|
||||
case .boldItalic: return "bm"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -599,6 +580,7 @@ public class MTMathAtomFactory {
|
||||
}
|
||||
|
||||
if let atom = supportedLatexSymbols[name] {
|
||||
// FIXME: A kludge - objects should be copied here
|
||||
if name == "int" { return MTMathAtomFactory.operatorWithName( "\u{222B}", limits: false) }
|
||||
if name == "sum" { return MTMathAtomFactory.operatorWithName( "\u{2211}", limits: true) }
|
||||
return atom
|
||||
@@ -707,6 +689,15 @@ public class MTMathAtomFactory {
|
||||
@note The reason this function returns a `MTMathAtom` and not a `MTMathTable` is because some
|
||||
matrix environments are have builtin delimiters added to the table and hence are returned as inner atoms.
|
||||
*/
|
||||
static let matrixEnvs = [
|
||||
"matrix": [],
|
||||
"pmatrix": ["(", ")"],
|
||||
"bmatrix": ["[", "]"],
|
||||
"Bmatrix": ["{", "}"],
|
||||
"vmatrix": ["vert", "vert"],
|
||||
"Vmatrix": ["Vert", "Vert"]
|
||||
]
|
||||
|
||||
public static func table(withEnvironment env: String?, rows: [[MTMathList]], error:inout NSError?) -> MTMathAtom? {
|
||||
let table = MTMathTable(environment: env)
|
||||
|
||||
@@ -717,15 +708,6 @@ public class MTMathAtomFactory {
|
||||
}
|
||||
}
|
||||
|
||||
let matrixEnvs = [
|
||||
"matrix": [],
|
||||
"pmatrix": ["(", ")"],
|
||||
"bmatrix": ["[", "]"],
|
||||
"Bmatrix": ["{", "}"],
|
||||
"vmatrix": ["vert", "vert"],
|
||||
"Vmatrix": ["Vert", "Vert"]
|
||||
]
|
||||
|
||||
if env == nil {
|
||||
table.interColumnSpacing = 0
|
||||
table.interRowAdditionalSpacing = 1
|
||||
|
||||
@@ -341,7 +341,6 @@ public class MTLargeOperator: MTMathAtom {
|
||||
init(value: String, limits: Bool) {
|
||||
super.init(type: .largeOperator, value: value)
|
||||
self.limits = limits
|
||||
//print("Operator \(value) limits:\(limits)")
|
||||
}
|
||||
|
||||
public override func copy(with zone: NSZone? = nil) -> Any {
|
||||
@@ -740,7 +739,7 @@ public class MTMathList: NSObject, NSCopying {
|
||||
if prevNode != nil && prevNode!.type == .binaryOperator {
|
||||
prevNode!.type = .unaryOperator
|
||||
finalizedList.removeLastAtom()
|
||||
finalizedList.add(prevNode!)
|
||||
finalizedList.add(prevNode)
|
||||
}
|
||||
|
||||
return finalizedList
|
||||
@@ -758,7 +757,19 @@ public class MTMathList: NSObject, NSCopying {
|
||||
self.atoms = []
|
||||
}
|
||||
|
||||
func add(_ atom: MTMathAtom) {
|
||||
func NSParamException(_ param:Any?) {
|
||||
if param == nil {
|
||||
NSException(name: NSExceptionName(rawValue: "Error"), reason: "Parameter cannot be nil").raise()
|
||||
}
|
||||
}
|
||||
|
||||
func NSIndexException(_ array:[Any], index: Int) {
|
||||
guard !array.indices.contains(index) else { return }
|
||||
NSException(name: NSExceptionName(rawValue: "Error"), reason: "Index \(index) out of bounds").raise()
|
||||
}
|
||||
|
||||
func add(_ atom: MTMathAtom?) {
|
||||
guard let atom = atom else { return }
|
||||
if self.isAtomAllowed(atom) {
|
||||
self.atoms.append(atom)
|
||||
} else {
|
||||
@@ -766,15 +777,21 @@ public class MTMathList: NSObject, NSCopying {
|
||||
}
|
||||
}
|
||||
|
||||
func insert(_ atom: MTMathAtom, at index: Int) {
|
||||
func insert(_ atom: MTMathAtom?, at index: Int) {
|
||||
// NSParamException(atom)
|
||||
guard let atom = atom else { return }
|
||||
guard self.atoms.indices.contains(index) || index == self.atoms.endIndex else { return }
|
||||
// guard self.atoms.endIndex >= index else { NSIndexException(); return }
|
||||
if self.isAtomAllowed(atom) {
|
||||
// NSIndexException(self.atoms, index: index)
|
||||
self.atoms.insert(atom, at: index)
|
||||
} else {
|
||||
NSException(name: NSExceptionName(rawValue: "Error"), reason: "Cannot add atom of type \(atom.type.rawValue) into mathlist").raise()
|
||||
}
|
||||
}
|
||||
|
||||
func append(_ list: MTMathList) {
|
||||
func append(_ list: MTMathList?) {
|
||||
guard let list = list else { return }
|
||||
self.atoms += list.atoms
|
||||
}
|
||||
|
||||
@@ -785,14 +802,17 @@ public class MTMathList: NSObject, NSCopying {
|
||||
}
|
||||
|
||||
func removeAtom(at index: Int) {
|
||||
NSIndexException(self.atoms, index:index)
|
||||
self.atoms.remove(at: index)
|
||||
}
|
||||
|
||||
func removeAtoms(in range: ClosedRange<Int>) {
|
||||
NSIndexException(self.atoms, index: range.lowerBound)
|
||||
NSIndexException(self.atoms, index: range.upperBound)
|
||||
self.atoms.removeSubrange(range)
|
||||
}
|
||||
|
||||
func isAtomAllowed(_ atom: MTMathAtom) -> Bool {
|
||||
return atom.type != .boundary
|
||||
func isAtomAllowed(_ atom: MTMathAtom?) -> Bool {
|
||||
return atom?.type != .boundary
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ import Foundation
|
||||
/** `MTMathListBuilder` is a class for parsing LaTeX into an `MTMathList` that
|
||||
can be rendered and processed mathematically.
|
||||
*/
|
||||
class MTEnvProperties {
|
||||
struct MTEnvProperties {
|
||||
var envName: String?
|
||||
var ended: Bool
|
||||
var numRows: Int
|
||||
@@ -376,7 +376,7 @@ public class MTMathListBuilder {
|
||||
// this puts us in a recursive routine, and sets oneCharOnly to false and no stop character
|
||||
let subList = self.buildInternal(false, stopChar: "}")
|
||||
prevAtom = subList!.atoms.last
|
||||
list.append(subList!)
|
||||
list.append(subList)
|
||||
if oneCharOnly {
|
||||
return list
|
||||
}
|
||||
@@ -425,7 +425,7 @@ public class MTMathListBuilder {
|
||||
// (note setError will not set the error if there is already one, so we flag internal error
|
||||
// in the odd case that an _error is not set.
|
||||
self.setError(.internalError, message:"Internal error")
|
||||
return nil;
|
||||
return nil
|
||||
}
|
||||
} else if char == "&" {
|
||||
assert(!oneCharOnly, "This should have been handled before")
|
||||
@@ -446,7 +446,7 @@ public class MTMathListBuilder {
|
||||
|
||||
assert(atom != nil, "Atom shouldn't be nil")
|
||||
atom?.fontStyle = currentFontStyle
|
||||
list.add(atom!)
|
||||
list.add(atom)
|
||||
prevAtom = atom
|
||||
|
||||
if oneCharOnly {
|
||||
|
||||
@@ -8,7 +8,7 @@ import XCTest
|
||||
// Created by Mike Griebling on 2023-01-02.
|
||||
//
|
||||
|
||||
final class SwiftMathRenderTests: XCTestCase {
|
||||
final class MTMathListBuilderTests: XCTestCase {
|
||||
|
||||
func checkAtomTypes(_ list:MTMathList?, types:[MTMathAtomType], desc:String) {
|
||||
if let list = list {
|
||||
@@ -23,13 +23,13 @@ final class SwiftMathRenderTests: XCTestCase {
|
||||
}
|
||||
}
|
||||
|
||||
override func setUpWithError() throws {
|
||||
// Put setup code here. This method is called before the invocation of each test method in the class.
|
||||
}
|
||||
|
||||
override func tearDownWithError() throws {
|
||||
// Put teardown code here. This method is called after the invocation of each test method in the class.
|
||||
}
|
||||
// override func setUpWithError() throws {
|
||||
// // Put setup code here. This method is called before the invocation of each test method in the class.
|
||||
// }
|
||||
//
|
||||
// override func tearDownWithError() throws {
|
||||
// // Put teardown code here. This method is called after the invocation of each test method in the class.
|
||||
// }
|
||||
|
||||
struct TestRecord {
|
||||
let build : String
|
||||
@@ -1150,15 +1150,11 @@ final class SwiftMathRenderTests: XCTestCase {
|
||||
for testCase in data {
|
||||
let str = testCase.0
|
||||
var error : NSError? = nil
|
||||
if str == "\\begin{displaylines} x & y \\end{displaylines}" {
|
||||
let x = 0
|
||||
}
|
||||
let list = MTMathListBuilder.build(fromString: str, error:&error)
|
||||
let desc = "Error for string:\(str)"
|
||||
XCTAssertNil(list, desc)
|
||||
XCTAssertNotNil(error, desc)
|
||||
XCTAssertEqual(error!.domain, MTParseError, desc)
|
||||
let code = error!.code
|
||||
let num = testCase.1
|
||||
XCTAssertEqual(error!.code, num.rawValue, desc)
|
||||
}
|
||||
@@ -1170,13 +1166,13 @@ final class SwiftMathRenderTests: XCTestCase {
|
||||
var list = MTMathListBuilder.build(fromString: str, error:&error)
|
||||
XCTAssertNil(list)
|
||||
XCTAssertNotNil(error)
|
||||
|
||||
|
||||
MTMathAtomFactory.add(latexSymbol: "lcm", value: MTMathAtomFactory.operatorWithName("lcm", limits:false))
|
||||
error = nil
|
||||
list = MTMathListBuilder.build(fromString: str, error:&error)
|
||||
let atomTypes = [MTMathAtomType.largeOperator, .open, .variable, .punctuation, .variable, .close]
|
||||
self.checkAtomTypes(list, types:atomTypes, desc:"Error for lcm")
|
||||
|
||||
|
||||
// convert it back to latex
|
||||
let latex = MTMathListBuilder.mathListToString(list)
|
||||
XCTAssertEqual(latex, "\\lcm (a,b)");
|
||||
617
Tests/SwiftMathRenderTests/MTMathListTests.swift
Normal file
617
Tests/SwiftMathRenderTests/MTMathListTests.swift
Normal file
@@ -0,0 +1,617 @@
|
||||
import XCTest
|
||||
@testable import SwiftMathRender
|
||||
|
||||
//
|
||||
// MathRenderSwiftTests.swift
|
||||
// MathRenderSwiftTests
|
||||
//
|
||||
// Created by Mike Griebling on 2023-01-02.
|
||||
//
|
||||
|
||||
final class MTMathListTests: XCTestCase {
|
||||
|
||||
func testSubScript() throws {
|
||||
let str = "-52x^{13+y}_{15-} + (-12.3 *)\\frac{-12}{15.2}"
|
||||
let list = MTMathListBuilder.build(fromString: str)!
|
||||
let finalized = list.finalized
|
||||
try self.checkListContents(finalized)
|
||||
// refinalizing a finalized list should not cause any more changes
|
||||
try self.checkListContents(finalized.finalized)
|
||||
}
|
||||
|
||||
func checkListContents(_ finalized:MTMathList) throws {
|
||||
// check
|
||||
XCTAssertEqual((finalized.atoms.count), 10, "Num atoms");
|
||||
var atom = finalized.atoms[0];
|
||||
XCTAssertEqual(atom.type, .unaryOperator, "Atom 0");
|
||||
XCTAssertEqual(atom.nucleus, "−", "Atom 0 value");
|
||||
XCTAssertTrue(NSEqualRanges(atom.indexRange, NSMakeRange(0, 1)), "Range");
|
||||
atom = finalized.atoms[1];
|
||||
XCTAssertEqual(atom.type, .number, "Atom 1");
|
||||
XCTAssertEqual(atom.nucleus, "52", "Atom 1 value");
|
||||
XCTAssertTrue(NSEqualRanges(atom.indexRange, NSMakeRange(1, 2)), "Range");
|
||||
atom = finalized.atoms[2];
|
||||
XCTAssertEqual(atom.type, .variable, "Atom 2");
|
||||
XCTAssertEqual(atom.nucleus, "x", "Atom 2 value");
|
||||
XCTAssertTrue(NSEqualRanges(atom.indexRange, NSMakeRange(3, 1)), "Range");
|
||||
|
||||
let superScr = atom.superScript!
|
||||
XCTAssertEqual((superScr.atoms.count), 3, "Super script");
|
||||
atom = superScr.atoms[0];
|
||||
XCTAssertEqual(atom.type, .number, "Super Atom 0");
|
||||
XCTAssertEqual(atom.nucleus, "13", "Super Atom 0 value");
|
||||
XCTAssertTrue(NSEqualRanges(atom.indexRange, NSMakeRange(0, 2)), "Range");
|
||||
atom = superScr.atoms[1];
|
||||
XCTAssertEqual(atom.type, .binaryOperator, "Super Atom 1");
|
||||
XCTAssertEqual(atom.nucleus, "+", "Super Atom 1 value");
|
||||
XCTAssertTrue(NSEqualRanges(atom.indexRange, NSMakeRange(2, 1)), "Range");
|
||||
atom = superScr.atoms[2];
|
||||
XCTAssertEqual(atom.type, .variable, "Super Atom 2");
|
||||
XCTAssertEqual(atom.nucleus, "y", "Super Atom 2 value");
|
||||
XCTAssertTrue(NSEqualRanges(atom.indexRange, NSMakeRange(3, 1)), "Range");
|
||||
|
||||
atom = finalized.atoms[2];
|
||||
let subScr = atom.subScript!
|
||||
XCTAssertEqual((subScr.atoms.count), 2, "Sub script");
|
||||
atom = subScr.atoms[0];
|
||||
XCTAssertEqual(atom.type, .number, "Sub Atom 0");
|
||||
XCTAssertEqual(atom.nucleus, "15", "Sub Atom 0 value");
|
||||
XCTAssertTrue(NSEqualRanges(atom.indexRange, NSMakeRange(0, 2)), "Range");
|
||||
atom = subScr.atoms[1];
|
||||
XCTAssertEqual(atom.type, .unaryOperator, "Sub Atom 1");
|
||||
XCTAssertEqual(atom.nucleus, "−", "Sub Atom 1 value");
|
||||
XCTAssertTrue(NSEqualRanges(atom.indexRange, NSMakeRange(2, 1)), "Range");
|
||||
|
||||
atom = finalized.atoms[3];
|
||||
XCTAssertEqual(atom.type, .binaryOperator, "Atom 3");
|
||||
XCTAssertEqual(atom.nucleus, "+", "Atom 3 value");
|
||||
XCTAssertTrue(NSEqualRanges(atom.indexRange, NSMakeRange(4, 1)), "Range");
|
||||
atom = finalized.atoms[4];
|
||||
XCTAssertEqual(atom.type, .open, "Atom 4");
|
||||
XCTAssertEqual(atom.nucleus, "(", "Atom 4 value");
|
||||
XCTAssertTrue(NSEqualRanges(atom.indexRange, NSMakeRange(5, 1)), "Range");
|
||||
atom = finalized.atoms[5];
|
||||
XCTAssertEqual(atom.type, .unaryOperator, "Atom 5");
|
||||
XCTAssertEqual(atom.nucleus, "−", "Atom 5 value");
|
||||
XCTAssertTrue(NSEqualRanges(atom.indexRange, NSMakeRange(6, 1)), "Range");
|
||||
atom = finalized.atoms[6];
|
||||
XCTAssertEqual(atom.type, .number, "Atom 6");
|
||||
XCTAssertEqual(atom.nucleus, "12.3", "Atom 6 value");
|
||||
XCTAssertTrue(NSEqualRanges(atom.indexRange, NSMakeRange(7, 4)), "Range");
|
||||
atom = finalized.atoms[7];
|
||||
XCTAssertEqual(atom.type, .unaryOperator, "Atom 7");
|
||||
XCTAssertEqual(atom.nucleus, "*", "Atom 7 value");
|
||||
XCTAssertTrue(NSEqualRanges(atom.indexRange, NSMakeRange(11, 1)), "Range");
|
||||
atom = finalized.atoms[8];
|
||||
XCTAssertEqual(atom.type, .close, "Atom 8");
|
||||
XCTAssertEqual(atom.nucleus, ")", "Atom 8 value");
|
||||
XCTAssertTrue(NSEqualRanges(atom.indexRange, NSMakeRange(12, 1)), "Range");
|
||||
|
||||
let frac = finalized.atoms[9] as! MTFraction
|
||||
XCTAssertEqual(frac.type, .fraction, "Atom 9");
|
||||
XCTAssertEqual(frac.nucleus, "", "Atom 9 value");
|
||||
XCTAssertTrue(NSEqualRanges(frac.indexRange, NSMakeRange(13, 1)), "Range");
|
||||
|
||||
let numer = frac.numerator!
|
||||
XCTAssertNotNil(numer, "Numerator");
|
||||
XCTAssertEqual((numer.atoms.count), 2, "Numer script");
|
||||
atom = numer.atoms[0];
|
||||
XCTAssertEqual(atom.type, .unaryOperator, "Numer Atom 0");
|
||||
XCTAssertEqual(atom.nucleus, "−", "Numer Atom 0 value");
|
||||
XCTAssertTrue(NSEqualRanges(atom.indexRange, NSMakeRange(0, 1)), "Range");
|
||||
atom = numer.atoms[1];
|
||||
XCTAssertEqual(atom.type, .number, "Numer Atom 1");
|
||||
XCTAssertEqual(atom.nucleus, "12", "Numer Atom 1 value");
|
||||
XCTAssertTrue(NSEqualRanges(atom.indexRange, NSMakeRange(1, 2)), "Range");
|
||||
|
||||
|
||||
let denom = frac.denominator!
|
||||
XCTAssertNotNil(denom, "Denominator");
|
||||
XCTAssertEqual((denom.atoms.count), 1, "Denom script");
|
||||
atom = denom.atoms[0];
|
||||
XCTAssertEqual(atom.type, .number, "Denom Atom 0");
|
||||
XCTAssertEqual(atom.nucleus, "15.2", "Denom Atom 0 value");
|
||||
XCTAssertTrue(NSEqualRanges(atom.indexRange, NSMakeRange(0, 4)), "Range");
|
||||
|
||||
}
|
||||
|
||||
func testAdd() throws {
|
||||
let list = MTMathList()
|
||||
XCTAssertEqual(list.atoms.count, 0);
|
||||
let atom = MTMathAtomFactory.placeholder()
|
||||
list.add(atom)
|
||||
XCTAssertEqual(list.atoms.count, 1);
|
||||
XCTAssertEqual(list.atoms[0], atom);
|
||||
let atom2 = MTMathAtomFactory.placeholder()
|
||||
list.add(atom2);
|
||||
XCTAssertEqual(list.atoms.count, 2);
|
||||
XCTAssertEqual(list.atoms[0], atom);
|
||||
XCTAssertEqual(list.atoms[1], atom2);
|
||||
}
|
||||
|
||||
private var options : XCTExpectedFailure.Options {
|
||||
let op = XCTExpectedFailure.Options()
|
||||
op.isStrict = true
|
||||
return op
|
||||
}
|
||||
|
||||
func testAddErrors() throws {
|
||||
let list = MTMathList()
|
||||
var atom : MTMathAtom? = nil
|
||||
list.add(atom)
|
||||
atom = MTMathAtom.atom(withType: .boundary, value: "")
|
||||
XCTExpectFailure("Test adding an illegal atom", options:options) {
|
||||
XCTAssertThrowsError(list.add(atom))
|
||||
}
|
||||
}
|
||||
|
||||
func testInsert() throws {
|
||||
let list = MTMathList()
|
||||
XCTAssertEqual(list.atoms.count, 0);
|
||||
let atom = MTMathAtomFactory.placeholder()
|
||||
list.insert(atom, at: 0)
|
||||
XCTAssertEqual(list.atoms.count, 1);
|
||||
XCTAssertEqual(list.atoms[0], atom);
|
||||
let atom2 = MTMathAtomFactory.placeholder()
|
||||
list.insert(atom2, at: 0)
|
||||
XCTAssertEqual(list.atoms.count, 2);
|
||||
XCTAssertEqual(list.atoms[0], atom2);
|
||||
XCTAssertEqual(list.atoms[1], atom);
|
||||
let atom3 = MTMathAtomFactory.placeholder()
|
||||
list.insert(atom3, at: 2)
|
||||
XCTAssertEqual(list.atoms.count, 3);
|
||||
XCTAssertEqual(list.atoms[0], atom2);
|
||||
XCTAssertEqual(list.atoms[1], atom);
|
||||
XCTAssertEqual(list.atoms[2], atom3);
|
||||
}
|
||||
|
||||
func testInsertErrors() throws {
|
||||
let list = MTMathList()
|
||||
var atom : MTMathAtom? = nil
|
||||
list.insert(atom, at: 0)
|
||||
atom = MTMathAtom.atom(withType: .boundary, value:"")
|
||||
XCTExpectFailure("Test adding an illegal atom", options:options) {
|
||||
XCTAssertThrowsError(list.insert(atom, at:0))
|
||||
}
|
||||
atom = MTMathAtomFactory.placeholder()
|
||||
list.insert(atom, at:1)
|
||||
}
|
||||
|
||||
func testAppend() throws {
|
||||
let list1 = MTMathList()
|
||||
let atom = MTMathAtomFactory.placeholder()
|
||||
let atom2 = MTMathAtomFactory.placeholder()
|
||||
let atom3 = MTMathAtomFactory.placeholder()
|
||||
list1.add(atom)
|
||||
list1.add(atom2)
|
||||
list1.add(atom3)
|
||||
|
||||
let list2 = MTMathList()
|
||||
let atom5 = MTMathAtomFactory.times()
|
||||
let atom6 = MTMathAtomFactory.divide()
|
||||
list2.add(atom5)
|
||||
list2.add(atom6)
|
||||
|
||||
XCTAssertEqual(list1.atoms.count, 3);
|
||||
XCTAssertEqual(list2.atoms.count, 2);
|
||||
|
||||
list1.append(list2)
|
||||
XCTAssertEqual(list1.atoms.count, 5);
|
||||
XCTAssertEqual(list1.atoms[3], atom5);
|
||||
XCTAssertEqual(list1.atoms[4], atom6);
|
||||
}
|
||||
|
||||
func testRemoveLast() throws {
|
||||
let list = MTMathList()
|
||||
let atom = MTMathAtomFactory.placeholder()
|
||||
list.add(atom)
|
||||
XCTAssertEqual(list.atoms.count, 1);
|
||||
list.removeLastAtom()
|
||||
XCTAssertEqual(list.atoms.count, 0);
|
||||
// Removing from empty list.
|
||||
list.removeLastAtom()
|
||||
XCTAssertEqual(list.atoms.count, 0);
|
||||
let atom2 = MTMathAtomFactory.placeholder()
|
||||
list.add(atom)
|
||||
list.add(atom2);
|
||||
XCTAssertEqual(list.atoms.count, 2);
|
||||
list.removeLastAtom()
|
||||
XCTAssertEqual(list.atoms.count, 1);
|
||||
XCTAssertEqual(list.atoms[0], atom);
|
||||
}
|
||||
|
||||
func testRemoveAtomAtIndex() throws {
|
||||
let list = MTMathList()
|
||||
let atom = MTMathAtomFactory.placeholder()
|
||||
let atom2 = MTMathAtomFactory.placeholder()
|
||||
list.add(atom)
|
||||
list.add(atom2);
|
||||
XCTAssertEqual(list.atoms.count, 2);
|
||||
list.removeAtom(at:0)
|
||||
XCTAssertEqual(list.atoms.count, 1);
|
||||
XCTAssertEqual(list.atoms[0], atom2);
|
||||
|
||||
// Index out of range
|
||||
XCTExpectFailure("Test removing an out-of-index cell", options: options) {
|
||||
XCTAssertThrowsError(list.removeAtom(at:2))
|
||||
}
|
||||
}
|
||||
|
||||
func testRemoveAtomsInRange() throws {
|
||||
let list = MTMathList()
|
||||
let atom = MTMathAtomFactory.placeholder()
|
||||
let atom2 = MTMathAtomFactory.placeholder()
|
||||
let atom3 = MTMathAtomFactory.placeholder()
|
||||
list.add(atom)
|
||||
list.add(atom2);
|
||||
list.add(atom3)
|
||||
XCTAssertEqual(list.atoms.count, 3)
|
||||
list.removeAtoms(in: 1...2)
|
||||
XCTAssertEqual(list.atoms.count, 1);
|
||||
XCTAssertEqual(list.atoms[0], atom);
|
||||
|
||||
// Index out of range
|
||||
XCTExpectFailure("Test removing an out-of-bounds range", options: options) {
|
||||
XCTAssertThrowsError(list.removeAtoms(in: 1...3))
|
||||
}
|
||||
}
|
||||
|
||||
// func MTAssertEqual(test, expression1, expression2, ...) \
|
||||
// _XCTPrimitiveAssertEqual(test, expression1, @#expression1, expression2, @#expression2, __VA_ARGS__)
|
||||
//
|
||||
// func MTAssertNotEqual(test, expression1, expression2, ...) \
|
||||
// _XCTPrimitiveAssertNotEqual(test, expression1, @#expression1, expression2, @#expression2, __VA_ARGS__)
|
||||
|
||||
// func checkAtomCopy(_ copy:MTMathAtom, original:MTMathAtom, forTest test:XCTestCase?) throws {
|
||||
// MTAssertEqual(test, copy.type, original.type);
|
||||
// MTAssertEqual(test, copy.nucleus, original.nucleus);
|
||||
// // Deep copy
|
||||
// MTAssertNotEqual(test, copy, original);
|
||||
// }
|
||||
//
|
||||
// func checkListCopy(_ copy:MTMathList, original:MTMathList, forTest test:XCTestCase?) throws {
|
||||
// MTAssertEqual(test, copy.atoms.count, original.atoms.count)
|
||||
// for (i, copyAtom) in copy.atoms.enumerated() {
|
||||
// let origAtom = original.atoms[i];
|
||||
// try self.checkAtomCopy(copyAtom, original:origAtom, forTest:test)
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// func testCopy() throws {
|
||||
// let list = MTMathList()
|
||||
// let atom = MTMathAtomFactory.placeholder()
|
||||
// let atom2 = MTMathAtomFactory.times()
|
||||
// let atom3 = MTMathAtomFactory.divide()
|
||||
// list.add(atom)
|
||||
// list.add(atom2);
|
||||
// list.add(atom3)
|
||||
//
|
||||
// let list2 = list.copy()
|
||||
// checkListCopy(list2, original:list, forTest:self)
|
||||
// }
|
||||
//
|
||||
// func testAtomInit() throws {
|
||||
// var atom = MTMathAtom.atom(withType: .open, value:"(")
|
||||
// XCTAssertEqual(atom.nucleus, "(");
|
||||
// XCTAssertEqual(atom.type, .open);
|
||||
//
|
||||
// atom = MTMathAtom.atom(withType: .radical, value:"(")
|
||||
// XCTAssertEqual(atom.nucleus, "");
|
||||
// XCTAssertEqual(atom.type, .radical);
|
||||
// }
|
||||
//
|
||||
// func testAtomScripts() throws {
|
||||
// var atom = MTMathAtom.atom(withType: .open, value:"(")
|
||||
// XCTAssertTrue(atom.isScriptAllowed())
|
||||
// atom.subScript = MTMathList()
|
||||
// XCTAssertNotNil(atom.subScript);
|
||||
// atom.superScript = MTMathList()
|
||||
// XCTAssertNotNil(atom.superScript);
|
||||
//
|
||||
// atom = MTMathAtom.atom(withType: .boundary, value:"(")
|
||||
// XCTAssertFalse(atom.isScriptAllowed());
|
||||
// // Can set to nil
|
||||
// atom.subScript = nil;
|
||||
// XCTAssertNil(atom.subScript);
|
||||
// atom.superScript = nil;
|
||||
// XCTAssertNil(atom.superScript);
|
||||
// // Can't set to value
|
||||
// let list = MTMathList()
|
||||
// XCTAssertThrowsError(atom.subScript = list);
|
||||
// XCTAssertThrowsError(atom.superScript = list);
|
||||
// }
|
||||
//
|
||||
// func testAtomCopy() throws {
|
||||
// let list = MTMathList()
|
||||
// let atom1 = MTMathAtomFactory.placeholder()
|
||||
// let atom2 = MTMathAtomFactory.times()
|
||||
// let atom3 = MTMathAtomFactory.divide()
|
||||
// list.add(atom1)
|
||||
// list.add(atom2);
|
||||
// list.add(atom3)
|
||||
//
|
||||
// let list2 = MTMathList()
|
||||
// list2.add(atom3)
|
||||
// list2.add(atom2)
|
||||
//
|
||||
// let atom = MTMathAtom.atom(withType: .open, value:"(")
|
||||
// atom.subScript = list;
|
||||
// atom.superScript = list2;
|
||||
// let copy = atom.copy()
|
||||
//
|
||||
// checkAtomCopy(copy, original:atom, forTest:self)
|
||||
// checkListCopy(copy.superScript, original:atom.superScript, forTest:self)
|
||||
// checkListCopy(copy.subScript, original:atom.subScript, forTest:self)
|
||||
// }
|
||||
//
|
||||
// func testCopyFraction() throws {
|
||||
// let list = MTMathList()
|
||||
// let atom = MTMathAtomFactory.placeholder()
|
||||
// let atom2 = MTMathAtomFactory.times()
|
||||
// let atom3 = MTMathAtomFactory.divide()
|
||||
// list.add(atom)
|
||||
// list.add(atom2);
|
||||
// list.add(atom3)
|
||||
//
|
||||
// let list2 = MTMathList()
|
||||
// list2.add(atom3)
|
||||
// list2.add(atom2)
|
||||
//
|
||||
// let frac = MTFraction(hasRule: false)
|
||||
// XCTAssertEqual(frac.type, .fraction);
|
||||
// frac.numerator = list;
|
||||
// frac.denominator = list2;
|
||||
// frac.leftDelimiter = "a";
|
||||
// frac.rightDelimiter = "b";
|
||||
//
|
||||
// let copy = frac.copy() as! MTFraction
|
||||
// try checkAtomCopy(copy, original:frac, forTest:self)
|
||||
// checkListCopy(copy.numerator, original:frac.numerator, forTest:self)
|
||||
// checkListCopy(copy.denominator, original:frac.denominator, forTest:self)
|
||||
// XCTAssertFalse(copy.hasRule)
|
||||
// XCTAssertEqual(copy.leftDelimiter, "a");
|
||||
// XCTAssertEqual(copy.rightDelimiter, "b");
|
||||
// }
|
||||
//
|
||||
// func testCopyRadical() throws {
|
||||
// let list = MTMathList()
|
||||
// let atom = MTMathAtomFactory.placeholder()
|
||||
// let atom2 = MTMathAtomFactory.times()
|
||||
// let atom3 = MTMathAtomFactory.divide()
|
||||
// list.add(atom)
|
||||
// list.add(atom2);
|
||||
// list.add(atom3)
|
||||
//
|
||||
// let list2 = MTMathList()
|
||||
// list2.add(atom3)
|
||||
// list2.add(atom2)
|
||||
//
|
||||
// let rad = [[MTRadical alloc] init)
|
||||
// XCTAssertEqual(rad.type, kMTMathAtomRadical);
|
||||
// rad.radicand = list;
|
||||
// rad.degree = list2;
|
||||
//
|
||||
// let copy = [rad copy)
|
||||
// checkAtomCopy(copy original:rad forTest:self)
|
||||
// checkListCopy(copy.radicand original:rad.radicand forTest:self)
|
||||
// checkListCopy(copy.degree original:rad.degree forTest:self)
|
||||
// }
|
||||
//
|
||||
// func testCopyLargeOperator() throws {
|
||||
// let lg = [[MTLargeOperator alloc] initWithValue:"lim" limits:true)
|
||||
// XCTAssertEqual(lg.type, kMTMathAtomLargeOperator);
|
||||
// XCTAssertTrue(lg.limits);
|
||||
//
|
||||
// let copy = [lg copy)
|
||||
// checkAtomCopy(copy original:lg forTest:self)
|
||||
// XCTAssertEqual(copy.limits, lg.limits);
|
||||
// }
|
||||
// func testCopyInner() throws {
|
||||
// let list = MTMathList()
|
||||
// let atom = MTMathAtomFactory.placeholder()
|
||||
// let atom2 = MTMathAtomFactory.times()
|
||||
// let atom3 = MTMathAtomFactory.divide()
|
||||
// list.add(atom)
|
||||
// list.add(atom2);
|
||||
// list.add(atom3)
|
||||
//
|
||||
// let inner = MTInner()
|
||||
// inner.innerList = list;
|
||||
// inner.leftBoundary = MTMathAtom.atom(withType: .boundary, value: "(")
|
||||
// inner.rightBoundary = MTMathAtom.atom(withType: .boundary, value:")")
|
||||
// XCTAssertEqual(inner.type, .inner);
|
||||
//
|
||||
// let copy = [inner copy)
|
||||
// checkAtomCopy(copy original:inner forTest:self)
|
||||
// checkListCopy(copy.innerList original:inner.innerList forTest:self)
|
||||
// checkAtomCopy(copy.leftBoundary original:inner.leftBoundary forTest:self)
|
||||
// checkAtomCopy(copy.rightBoundary original:inner.rightBoundary forTest:self)
|
||||
// }
|
||||
//
|
||||
// func testSetInnerBoundary() throws {
|
||||
// let inner = MTInner()
|
||||
//
|
||||
// // Can set non-nil
|
||||
// inner.leftBoundary = MTMathAtom.atom(withType: .boundary, value:"(")
|
||||
// inner.rightBoundary = MTMathAtom.atom(withType: .boundary, value:")")
|
||||
// XCTAssertNotNil(inner.leftBoundary);
|
||||
// XCTAssertNotNil(inner.rightBoundary);
|
||||
// // Can set nil
|
||||
// inner.leftBoundary = nil;
|
||||
// inner.rightBoundary = nil;
|
||||
// XCTAssertNil(inner.leftBoundary);
|
||||
// XCTAssertNil(inner.rightBoundary);
|
||||
// // Can't set non boundary
|
||||
// let atom = MTMathAtomFactory.placeholder()
|
||||
// XCTAssertThrowsError(inner.leftBoundary = atom);
|
||||
// XCTAssertThrowsError(inner.rightBoundary = atom);
|
||||
// }
|
||||
//
|
||||
// func testCopyOverline() throws {
|
||||
// let list = MTMathList()
|
||||
// let atom = MTMathAtomFactory.placeholder()
|
||||
// let atom2 = MTMathAtomFactory.times()
|
||||
// let atom3 = MTMathAtomFactory.divide()
|
||||
// list.add(atom)
|
||||
// list.add(atom2);
|
||||
// list.add(atom3)
|
||||
//
|
||||
// let over = MTOverLine()
|
||||
// XCTAssertEqual(over.type, .overline);
|
||||
// over.innerList = list;
|
||||
//
|
||||
// let copy = [over copy)
|
||||
// checkAtomCopy(copy original:over forTest:self)
|
||||
// checkListCopy(copy.innerList original:over.innerList forTest:self)
|
||||
// }
|
||||
//
|
||||
// func testCopyUnderline() throws {
|
||||
// let list = MTMathList()
|
||||
// let atom = MTMathAtomFactory.placeholder()
|
||||
// let atom2 = MTMathAtomFactory.times()
|
||||
// let atom3 = MTMathAtomFactory.divide()
|
||||
// list.add(atom)
|
||||
// list.add(atom2);
|
||||
// list.add(atom3)
|
||||
//
|
||||
// let under = MTUnderLine()
|
||||
// XCTAssertEqual(under.type, .underline);
|
||||
// under.innerList = list;
|
||||
//
|
||||
// let copy = [under copy)
|
||||
// checkAtomCopy(copy, original:under, forTest:self)
|
||||
// checkListCopy(copy.innerList original:under.innerList forTest:self)
|
||||
// }
|
||||
//
|
||||
// func testCopyAcccent() throws {
|
||||
// let list = MTMathList()
|
||||
// let atom = MTMathAtomFactory.placeholder()
|
||||
// let atom2 = MTMathAtomFactory.times()
|
||||
// let atom3 = MTMathAtomFactory.divide()
|
||||
// list.add(atom)
|
||||
// list.add(atom2);
|
||||
// list.add(atom3)
|
||||
//
|
||||
// let accent = [[MTAccent alloc] initWithValue:"^")
|
||||
// XCTAssertEqual(accent.type, kMTMathAtomAccent);
|
||||
// accent.innerList = list;
|
||||
//
|
||||
// let copy = [accent copy)
|
||||
// checkAtomCopy(copy original:accent forTest:self)
|
||||
// checkListCopy(copy.innerList original:accent.innerList forTest:self)
|
||||
// }
|
||||
//
|
||||
// func testCopySpace() throws {
|
||||
// let space = MTMathSpace(space: 3)
|
||||
// XCTAssertEqual(space.type, .space);
|
||||
//
|
||||
// let copy = [space copy)
|
||||
// checkAtomCopy(copy, original:space, forTest:self)
|
||||
// XCTAssertEqual(space.space, copy.space);
|
||||
// }
|
||||
//
|
||||
// func testCopyStyle() throws {
|
||||
// let style = MTMathStyle(style: .script)
|
||||
// XCTAssertEqual(style.type, .style);
|
||||
//
|
||||
// let copy = style.copy() as! MTMathStyle
|
||||
// checkAtomCopy(copy, original:style, forTest:self)
|
||||
// XCTAssertEqual(style.style, copy.style);
|
||||
// }
|
||||
//
|
||||
// func testCreateMathTable() throws {
|
||||
// let table = MTMathTable()
|
||||
// XCTAssertEqual(table.type, .table);
|
||||
//
|
||||
// let list = MTMathList()
|
||||
// let atom = MTMathAtomFactory.placeholder()
|
||||
// let atom2 = MTMathAtomFactory.times()
|
||||
// let atom3 = MTMathAtomFactory.divide()
|
||||
// list.add(atom)
|
||||
// list.add(atom2);
|
||||
// list.add(atom3)
|
||||
//
|
||||
// let list2 = MTMathList()
|
||||
// list2.add(atom3)
|
||||
// list2.add(atom2)
|
||||
//
|
||||
// table.set(cell: list, forRow:3, column:2)
|
||||
// table.set(cell: list2, forRow:1, column:0)
|
||||
//
|
||||
// table.set(alignment: .left, forColumn: 2)
|
||||
// table.set(alignment: .right, forColumn:1)
|
||||
//
|
||||
// // Verify that everything is created correctly
|
||||
// XCTAssertEqual(table.cells.count, 4); // 4 rows
|
||||
// XCTAssertNotNil(table.cells[0]);
|
||||
// XCTAssertEqual(table.cells[0].count, 0); // 0 elements in row 0
|
||||
// XCTAssertEqual(table.cells[1].count, 1); // 1 element in row 1
|
||||
// XCTAssertNotNil(table.cells[2]);
|
||||
// XCTAssertEqual(table.cells[2].count, 0);
|
||||
// XCTAssertEqual(table.cells[3].count, 3);
|
||||
//
|
||||
// // Verify the elements in the rows
|
||||
// XCTAssertEqual(table.cells[1][0].atoms.count, 2);
|
||||
// XCTAssertEqual(table.cells[1][0], list2);
|
||||
// XCTAssertNotNil(table.cells[3][0]);
|
||||
// XCTAssertEqual(table.cells[3][0].atoms.count, 0);
|
||||
//
|
||||
// XCTAssertNotNil(table.cells[3][0]);
|
||||
// XCTAssertEqual(table.cells[3][0].atoms.count, 0);
|
||||
//
|
||||
// XCTAssertNotNil(table.cells[3][1]);
|
||||
// XCTAssertEqual(table.cells[3][1].atoms.count, 0);
|
||||
//
|
||||
// XCTAssertEqual(table.cells[3][2], list);
|
||||
//
|
||||
// XCTAssertEqual(table.numRows, 4);
|
||||
// XCTAssertEqual(table.numColumns, 3);
|
||||
//
|
||||
// // Verify the alignments
|
||||
// XCTAssertEqual(table.alignments.count, 3);
|
||||
// XCTAssertEqual(table.alignments[0], .center);
|
||||
// XCTAssertEqual(table.alignments[1], .right);
|
||||
// XCTAssertEqual(table.alignments[2], .left);
|
||||
// }
|
||||
//
|
||||
// func testCopyMathTable() throws {
|
||||
// let table = MTMathTable()
|
||||
// XCTAssertEqual(table.type, .table);
|
||||
//
|
||||
// let list = MTMathList()
|
||||
// let atom = MTMathAtomFactory.placeholder()
|
||||
// let atom2 = MTMathAtomFactory.times()
|
||||
// let atom3 = MTMathAtomFactory.divide()
|
||||
// list.add(atom)
|
||||
// list.add(atom2);
|
||||
// list.add(atom3)
|
||||
//
|
||||
// let list2 = MTMathList()
|
||||
// list2.add(atom3)
|
||||
// list2.add(atom2)
|
||||
//
|
||||
// table.set(cell:list, forRow:0, column:1)
|
||||
// table.set(cell:list2, forRow:0, column:2)
|
||||
//
|
||||
// table.set(alignment: .left, forColumn:2)
|
||||
// table.set(alignment: .right, forColumn:1)
|
||||
// table.interRowAdditionalSpacing = 3;
|
||||
// table.interColumnSpacing = 10;
|
||||
//
|
||||
// let copy = table.copy() as! MTMathTable
|
||||
// try checkAtomCopy(copy, original:table, forTest:self)
|
||||
// XCTAssertEqual(copy.interColumnSpacing, table.interColumnSpacing);
|
||||
// XCTAssertEqual(copy.interRowAdditionalSpacing, table.interRowAdditionalSpacing);
|
||||
// XCTAssertEqual(copy.alignments, table.alignments);
|
||||
// XCTAssertNotEqual(copy.alignments, table.alignments);
|
||||
//
|
||||
// XCTAssertNotEqual(copy.cells, table.cells);
|
||||
// XCTAssertNotEqual(copy.cells[0], table.cells[0]);
|
||||
// XCTAssertEqual(copy.cells[0].count, table.cells[0].count);
|
||||
// XCTAssertEqual(copy.cells[0][0].atoms.count, 0);
|
||||
// XCTAssertNotEqual(copy.cells[0][0], table.cells[0][0]);
|
||||
// try checkListCopy(copy.cells[0][1], original:list, forTest:self)
|
||||
// try checkListCopy(copy.cells[0][2], original:list2, forTest:self)
|
||||
// }
|
||||
//
|
||||
}
|
||||
Reference in New Issue
Block a user