Passed all tests in MTMathListTest and MTMathListbuilderTest suites.

This commit is contained in:
Michael Griebling
2023-01-10 10:53:26 -05:00
parent 04de18e5c9
commit 82f8b08c61
4 changed files with 548 additions and 527 deletions

View File

@@ -580,10 +580,7 @@ public class MTMathAtomFactory {
} }
if let atom = supportedLatexSymbols[name] { if let atom = supportedLatexSymbols[name] {
// FIXME: A kludge - objects should be copied here return atom.copy()
if name == "int" { return MTMathAtomFactory.operatorWithName( "\u{222B}", limits: false) }
if name == "sum" { return MTMathAtomFactory.operatorWithName( "\u{2211}", limits: true) }
return atom
} }
return nil return nil

View File

@@ -78,11 +78,25 @@ public enum MTFontStyle:Int {
boldItalic boldItalic
} }
public class MTMathAtom: NSObject, NSCopying { public class MTMathAtom: NSObject {
public var type: MTMathAtomType public var type = MTMathAtomType.ordinary
public var subScript: MTMathList? public var subScript: MTMathList? {
public var superScript: MTMathList? didSet {
if subScript != nil && !self.isScriptAllowed() {
subScript = nil
NSException(name: NSExceptionName(rawValue: "Error"), reason: "Subscripts not allowed for atom of type \(self.type)").raise()
}
}
}
public var superScript: MTMathList? {
didSet {
if superScript != nil && !self.isScriptAllowed() {
superScript = nil
NSException(name: NSExceptionName(rawValue: "Error"), reason: "Superscripts not allowed for atom of type \(self.type)").raise()
}
}
}
public var nucleus: String = "" public var nucleus: String = ""
public var childAtoms = [MTMathAtom]() // atoms that fused to create this one public var childAtoms = [MTMathAtom]() // atoms that fused to create this one
public var indexRange = NSRange(location: 0, length: 0) // indexRange in list that this atom tracks: public var indexRange = NSRange(location: 0, length: 0) // indexRange in list that this atom tracks:
@@ -90,43 +104,53 @@ public class MTMathAtom: NSObject, NSCopying {
var fontStyle: MTFontStyle = .defaultStyle var fontStyle: MTFontStyle = .defaultStyle
var fusedAtoms: MTMathList? var fusedAtoms: MTMathList?
public func copy(with zone: NSZone? = nil) -> Any { init(_ atom:MTMathAtom?) {
let atom = MTMathAtom.atom(withType: type, value: nucleus) guard let atom = atom else { return }
atom.type = self.type self.type = atom.type
atom.nucleus = self.nucleus self.nucleus = atom.nucleus
atom.subScript = self.subScript?.copy() as? MTMathList self.subScript = MTMathList(atom.subScript)
atom.superScript = self.subScript?.copy() as? MTMathList self.superScript = MTMathList(atom.superScript)
atom.indexRange = self.indexRange self.indexRange = atom.indexRange
atom.fontStyle = self.fontStyle self.fontStyle = atom.fontStyle
return atom self.childAtoms = [MTMathAtom](atom.childAtoms)
self.fusedAtoms = MTMathList(atom.fusedAtoms)
} }
public static func atom(withType type:MTMathAtomType, value:String) -> MTMathAtom { override init() { }
switch type {
init(type:MTMathAtomType, value:String) {
self.type = type
self.nucleus = type == .radical ? "" : value
}
public func copy() -> MTMathAtom {
switch self.type {
case .largeOperator: case .largeOperator:
return MTLargeOperator(value: value, limits: true) return MTLargeOperator(self as? MTLargeOperator)
case .fraction: case .fraction:
return MTFraction() return MTFraction(self as? MTFraction)
case .radical: case .radical:
return MTRadical() return MTRadical(self as? MTRadical)
case .placeholder: case .style:
return MTMathAtom(type: type, value: UnicodeSymbol.whiteSquare) return MTMathStyle(self as? MTMathStyle)
case .inner: case .inner:
return MTInner() return MTInner(self as? MTInner)
case .underline: case .underline:
return MTUnderLine() return MTUnderLine(self as? MTUnderLine)
case .overline: case .overline:
return MTOverLine() return MTOverLine(self as? MTOverLine)
case .accent: case .accent:
return MTAccent(value: value) return MTAccent(self as? MTAccent)
case .space: case .space:
return MTMathSpace(space: 0) return MTMathSpace(self as? MTMathSpace)
case .color: case .color:
return MTMathColor() return MTMathColor(self as? MTMathColor)
case .colorBox: case .colorBox:
return MTMathColorbox() return MTMathColorbox(self as? MTMathColorbox)
case .table:
return MTMathTable(self as! MTMathTable)
default: default:
return MTMathAtom(type: type, value: value) return MTMathAtom(self)
} }
} }
@@ -148,7 +172,6 @@ public class MTMathAtom: NSObject, NSCopying {
public override var description: String { public override var description: String {
var string = "" var string = ""
string += self.nucleus string += self.nucleus
if self.superScript != nil { if self.superScript != nil {
string += "^{\(self.superScript!.description)}" string += "^{\(self.superScript!.description)}"
@@ -156,7 +179,6 @@ public class MTMathAtom: NSObject, NSCopying {
if self.subScript != nil { if self.subScript != nil {
string += "_{\(self.subScript!.description)}" string += "_{\(self.subScript!.description)}"
} }
return string return string
} }
@@ -213,12 +235,6 @@ public class MTMathAtom: NSObject, NSCopying {
} }
func isScriptAllowed() -> Bool { self.type.isScriptAllowed() } func isScriptAllowed() -> Bool { self.type.isScriptAllowed() }
public init(type: MTMathAtomType, value: String) {
self.type = type
self.nucleus = value
}
func isNotBinaryOperator() -> Bool { self.type.isNotBinaryOperator() } func isNotBinaryOperator() -> Bool { self.type.isNotBinaryOperator() }
} }
@@ -232,17 +248,23 @@ public class MTFraction: MTMathAtom {
public var hasRule: Bool = true public var hasRule: Bool = true
public var leftDelimiter: String? public var leftDelimiter: String?
public var rightDelimiter: String? public var rightDelimiter: String?
public var numerator: MTMathList? = MTMathList() public var numerator: MTMathList?
public var denominator: MTMathList? = MTMathList() public var denominator: MTMathList?
public override func copy(with zone: NSZone? = nil) -> Any { init(_ frac: MTFraction?) {
let frac = super.copy(with: zone) as! MTFraction super.init(frac)
frac.numerator = self.numerator?.copy() as? MTMathList self.type = .fraction
frac.denominator = self.denominator?.copy() as? MTMathList self.numerator = MTMathList(frac?.numerator)
frac.hasRule = self.hasRule self.denominator = MTMathList(frac?.denominator)
frac.leftDelimiter = self.leftDelimiter self.hasRule = frac?.hasRule ?? true
frac.rightDelimiter = self.rightDelimiter self.leftDelimiter = frac?.leftDelimiter
return frac self.rightDelimiter = frac?.rightDelimiter
}
init(hasRule rule:Bool = true) {
super.init()
self.type = .fraction
self.hasRule = rule
} }
override public var description: String { override public var description: String {
@@ -280,28 +302,27 @@ public class MTFraction: MTMathAtom {
return finalized return finalized
} }
convenience init(hasRule: Bool = true) {
self.init(type: .fraction, value: "")
self.hasRule = hasRule
}
} }
public class MTRadical: MTMathAtom { public class MTRadical: MTMathAtom {
// Under the roof // Under the roof
public var radicand: MTMathList? = MTMathList() public var radicand: MTMathList?
// Value on radical sign // Value on radical sign
public var degree: MTMathList? public var degree: MTMathList?
convenience init() { init(_ rad:MTRadical?) {
self.init(type: .radical, value: "") super.init(rad)
self.type = .radical
self.radicand = MTMathList(rad?.radicand)
self.degree = MTMathList(rad?.degree)
self.nucleus = ""
} }
public override func copy(with zone: NSZone? = nil) -> Any { override init() {
let rad = super.copy(with: zone) as! MTRadical super.init()
rad.radicand = self.radicand?.copy() as? MTMathList self.type = .radical
rad.degree = self.degree?.copy() as? MTMathList self.nucleus = ""
return rad
} }
override public var description: String { override public var description: String {
@@ -338,15 +359,17 @@ public class MTRadical: MTMathAtom {
public class MTLargeOperator: MTMathAtom { public class MTLargeOperator: MTMathAtom {
public var limits: Bool = false public var limits: Bool = false
init(value: String, limits: Bool) { init(_ op:MTLargeOperator?) {
super.init(type: .largeOperator, value: value) super.init(op)
self.limits = limits self.type = .largeOperator
self.limits = op?.limits ?? false
} }
public override func copy(with zone: NSZone? = nil) -> Any { init(value: String, limits: Bool) {
let op = super.copy(with: zone) as! MTLargeOperator super.init()
op.limits = self.limits self.type = .largeOperator
return op self.nucleus = value
self.limits = limits
} }
} }
@@ -357,36 +380,31 @@ public class MTInner: MTMathAtom {
public var leftBoundary: MTMathAtom? { public var leftBoundary: MTMathAtom? {
didSet { didSet {
if leftBoundary != nil && leftBoundary!.type != .boundary { if leftBoundary != nil && leftBoundary!.type != .boundary {
assertionFailure("Left boundary must be of type .boundary") leftBoundary = nil
NSException(name: NSExceptionName(rawValue: "Error"), reason: "Left boundary must be of type .boundary").raise()
} }
} }
} }
public var rightBoundary: MTMathAtom? { public var rightBoundary: MTMathAtom? {
didSet { didSet {
if rightBoundary != nil && rightBoundary!.type != .boundary { if rightBoundary != nil && rightBoundary!.type != .boundary {
assertionFailure("Right boundary must be of type .boundary") rightBoundary = nil
NSException(name: NSExceptionName(rawValue: "Error"), reason: "Right boundary must be of type .boundary").raise()
} }
} }
} }
public override func copy(with zone: NSZone? = nil) -> Any { init(_ inner:MTInner?) {
let inner = super.copy(with: zone) as! MTInner super.init(inner)
inner.innerList = self.innerList?.copy() as? MTMathList self.type = .inner
inner.leftBoundary = self.leftBoundary?.copy() as? MTMathAtom self.innerList = MTMathList(inner?.innerList)
inner.rightBoundary = self.rightBoundary?.copy() as? MTMathAtom self.leftBoundary = MTMathAtom(inner?.leftBoundary)
return inner self.rightBoundary = MTMathAtom(inner?.rightBoundary)
} }
init() { override init() {
super.init(type: .inner, value: "") super.init()
} self.type = .inner
public override convenience init(type: MTMathAtomType, value: String) {
if type == .inner {
self.init(); return
}
assertionFailure("MTInner(type:value:) cannot be called. Use MTInner() instead.")
self.init()
} }
override public var description: String { override public var description: String {
@@ -427,14 +445,15 @@ public class MTOverLine: MTMathAtom {
return finalized return finalized
} }
public override func copy(with zone: NSZone? = nil) -> Any { init(_ over: MTOverLine?) {
let op = super.copy(with: zone) as! MTOverLine super.init(over)
op.innerList = self.innerList?.copy() as? MTMathList self.type = .overline
return op self.innerList = MTMathList(self.innerList)
} }
convenience init() { override init() {
self.init(type: .overline, value: "") super.init()
self.type = .overline
} }
} }
@@ -447,14 +466,15 @@ public class MTUnderLine: MTMathAtom {
return finalized return finalized
} }
public override func copy(with zone: NSZone? = nil) -> Any { init(_ under: MTUnderLine?) {
let op = super.copy(with: zone) as! MTUnderLine super.init(under)
op.innerList = self.innerList?.copy() as? MTMathList self.type = .underline
return op self.innerList = MTMathList(under?.innerList)
} }
convenience init() { override init() {
self.init(type: .underline, value: "") super.init()
self.type = .underline
} }
} }
@@ -467,31 +487,33 @@ public class MTAccent: MTMathAtom {
return finalized return finalized
} }
public override func copy(with zone: NSZone? = nil) -> Any { init(_ accent: MTAccent?) {
let op = super.copy(with: zone) as! MTAccent super.init(accent)
op.innerList = self.innerList?.copy() as? MTMathList self.type = .accent
return op self.innerList = MTMathList(accent?.innerList)
} }
convenience init(value: String) { init(value: String) {
self.init(type: .accent, value: value) super.init()
self.type = .accent
self.nucleus = value
} }
} }
public class MTMathSpace: MTMathAtom { public class MTMathSpace: MTMathAtom {
public var space: CGFloat = 0 public var space: CGFloat = 0
convenience init(space: CGFloat) { init(_ space: MTMathSpace?) {
self.init(type: .space, value: "") super.init(space)
self.type = .space
self.space = space?.space ?? 0
}
init(space:CGFloat) {
super.init()
self.type = .space
self.space = space self.space = space
} }
public override func copy(with zone: NSZone? = nil) -> Any {
let op = super.copy(with: zone) as! MTMathSpace
op.space = self.space
return op
}
} }
public enum MTLineStyle { public enum MTLineStyle {
@@ -517,15 +539,16 @@ public enum MTLineStyle {
public class MTMathStyle: MTMathAtom { public class MTMathStyle: MTMathAtom {
public var style: MTLineStyle = .display public var style: MTLineStyle = .display
convenience init(style: MTLineStyle = .display) { init(_ style:MTMathStyle?) {
self.init(type: .style, value: "") super.init(style)
self.style = style self.type = .style
self.style = style?.style ?? .display
} }
public override func copy(with zone: NSZone? = nil) -> Any { init(style:MTLineStyle) {
let op = super.copy(with: zone) as! MTMathStyle super.init()
op.style = self.style self.type = .style
return op self.style = style
} }
} }
@@ -533,23 +556,16 @@ public class MTMathColor: MTMathAtom {
public var colorString:String="" public var colorString:String=""
public var innerList:MTMathList? public var innerList:MTMathList?
init() { init(_ color: MTMathColor?) {
super.init(type: .color, value: "") super.init(color)
self.type = .color
self.colorString = color?.colorString ?? ""
self.innerList = MTMathList(color?.innerList)
} }
public override convenience init(type: MTMathAtomType, value: String) { override init() {
if type == .color { super.init()
self.init(); return self.type = .color
}
NSException(name: NSExceptionName("InvalidMethod"), reason: "MTMathColor(type:value) cannot be called. Use MTMathColor() instead.").raise()
self.init()
}
public override func copy(with zone: NSZone? = nil) -> Any {
let op = super.copy(with: zone) as! MTMathColor
op.colorString = self.colorString
op.innerList = self.innerList?.copy() as? MTMathList
return op
} }
public override var string: String { public override var string: String {
@@ -561,23 +577,16 @@ public class MTMathColorbox: MTMathAtom {
public var colorString:String="" public var colorString:String=""
public var innerList:MTMathList? public var innerList:MTMathList?
init() { init(_ cbox: MTMathColorbox?) {
super.init(type: .color, value: "") super.init(cbox)
self.type = .colorBox
self.colorString = cbox?.colorString ?? ""
self.innerList = MTMathList(cbox?.innerList)
} }
public override convenience init(type: MTMathAtomType, value: String) { override init() {
if type == .color { super.init()
self.init(); return self.type = .colorBox
}
NSException(name: NSExceptionName("InvalidMethod"), reason: "MTMathColorbox(type:value) cannot be called. Use MTMathColorbox() instead.").raise()
self.init()
}
public override func copy(with zone: NSZone? = nil) -> Any {
let op = super.copy(with: zone) as! MTMathColorbox
op.colorString = self.colorString
op.innerList = self.innerList?.copy() as? MTMathList
return op
} }
public override var string: String { public override var string: String {
@@ -611,24 +620,33 @@ public class MTMathTable: MTMathAtom {
return finalized return finalized
} }
convenience init(environment: String? = nil) { init(environment: String?) {
self.init(type: .table, value: "") super.init()
self.type = .table
self.environment = environment self.environment = environment
} }
public override func copy(with zone: NSZone? = nil) -> Any { init(_ table:MTMathTable) {
let op = super.copy(with: zone) as! MTMathTable super.init(table)
op.interRowAdditionalSpacing = self.interRowAdditionalSpacing self.type = .table
op.interColumnSpacing = self.interColumnSpacing self.alignments = table.alignments
op.environment = self.environment self.interRowAdditionalSpacing = table.interRowAdditionalSpacing
self.interColumnSpacing = table.interColumnSpacing
self.environment = table.environment
var cellCopy = [[MTMathList]]() var cellCopy = [[MTMathList]]()
cellCopy.reserveCapacity(self.cells.count) for row in table.cells {
for row in self.cells { var newRow = [MTMathList]()
let newRow = [MTMathList](row) for col in row {
newRow.append(MTMathList(col)!)
}
cellCopy.append(newRow) cellCopy.append(newRow)
} }
op.cells = cellCopy self.cells = cellCopy
return op }
override init() {
super.init()
self.type = .table
} }
public func set(cell list: MTMathList, forRow row:Int, column:Int) { public func set(cell list: MTMathList, forRow row:Int, column:Int) {
@@ -685,12 +703,13 @@ extension MTMathList {
public var string: String { self.description } public var string: String { self.description }
} }
public class MTMathList: NSObject, NSCopying { public class MTMathList : NSObject {
public func copy(with zone: NSZone? = nil) -> Any { init?(_ list:MTMathList?) {
let list = MTMathList() guard let list = list else { return nil }
list.atoms = [MTMathAtom](self.atoms) for atom in list.atoms {
return list self.atoms.append(atom.copy())
}
} }
public var atoms = [MTMathAtom]() public var atoms = [MTMathAtom]()
@@ -753,9 +772,7 @@ public class MTMathList: NSObject, NSCopying {
self.atoms.append(atom) self.atoms.append(atom)
} }
public override init() { public override init() { super.init() }
self.atoms = []
}
func NSParamException(_ param:Any?) { func NSParamException(_ param:Any?) {
if param == nil { if param == nil {

View File

@@ -546,7 +546,7 @@ public class MTMathListBuilder {
return mathColor return mathColor
} else if command == "colorbox" { } else if command == "colorbox" {
// A color command has 2 arguments // A color command has 2 arguments
let mathColorbox = MTMathColorbox(); let mathColorbox = MTMathColorbox()
mathColorbox.colorString = self.readColor()! mathColorbox.colorString = self.readColor()!
mathColorbox.innerList = self.buildInternal(true) mathColorbox.innerList = self.buildInternal(true)
return mathColorbox return mathColorbox

View File

@@ -139,7 +139,7 @@ final class MTMathListTests: XCTestCase {
let list = MTMathList() let list = MTMathList()
var atom : MTMathAtom? = nil var atom : MTMathAtom? = nil
list.add(atom) list.add(atom)
atom = MTMathAtom.atom(withType: .boundary, value: "") atom = MTMathAtom(type: .boundary, value: "")
XCTExpectFailure("Test adding an illegal atom", options:options) { XCTExpectFailure("Test adding an illegal atom", options:options) {
XCTAssertThrowsError(list.add(atom)) XCTAssertThrowsError(list.add(atom))
} }
@@ -169,7 +169,7 @@ final class MTMathListTests: XCTestCase {
let list = MTMathList() let list = MTMathList()
var atom : MTMathAtom? = nil var atom : MTMathAtom? = nil
list.insert(atom, at: 0) list.insert(atom, at: 0)
atom = MTMathAtom.atom(withType: .boundary, value:"") atom = MTMathAtom(type: .boundary, value:"")
XCTExpectFailure("Test adding an illegal atom", options:options) { XCTExpectFailure("Test adding an illegal atom", options:options) {
XCTAssertThrowsError(list.insert(atom, at:0)) XCTAssertThrowsError(list.insert(atom, at:0))
} }
@@ -262,356 +262,363 @@ final class MTMathListTests: XCTestCase {
// func MTAssertNotEqual(test, expression1, expression2, ...) \ // func MTAssertNotEqual(test, expression1, expression2, ...) \
// _XCTPrimitiveAssertNotEqual(test, expression1, @#expression1, expression2, @#expression2, __VA_ARGS__) // _XCTPrimitiveAssertNotEqual(test, expression1, @#expression1, expression2, @#expression2, __VA_ARGS__)
// func checkAtomCopy(_ copy:MTMathAtom, original:MTMathAtom, forTest test:XCTestCase?) throws { func checkAtomCopy(_ copy:MTMathAtom?, original:MTMathAtom?, forTest test:String) throws {
// MTAssertEqual(test, copy.type, original.type); guard let copy = copy, let original = original else { return }
// MTAssertEqual(test, copy.nucleus, original.nucleus); XCTAssertEqual(copy.type, original.type, test)
// // Deep copy XCTAssertEqual(copy.nucleus, original.nucleus, test)
// MTAssertNotEqual(test, copy, original); // Should be different objects with the same content
// } XCTAssertNotEqual(copy, original, test)
// }
// func checkListCopy(_ copy:MTMathList, original:MTMathList, forTest test:XCTestCase?) throws {
// MTAssertEqual(test, copy.atoms.count, original.atoms.count) func checkListCopy(_ copy:MTMathList?, original:MTMathList?, forTest test:String) throws {
// for (i, copyAtom) in copy.atoms.enumerated() { guard let copy = copy, let original = original else { return }
// let origAtom = original.atoms[i]; XCTAssertEqual(copy.atoms.count, original.atoms.count, test)
// try self.checkAtomCopy(copyAtom, original:origAtom, forTest:test) 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() func testCopy() throws {
// let atom2 = MTMathAtomFactory.times() let list = MTMathList()
// let atom3 = MTMathAtomFactory.divide() let atom = MTMathAtomFactory.placeholder()
// list.add(atom) let atom2 = MTMathAtomFactory.times()
// list.add(atom2); let atom3 = MTMathAtomFactory.divide()
// list.add(atom3) list.add(atom)
// list.add(atom2);
// let list2 = list.copy() list.add(atom3)
// checkListCopy(list2, original:list, forTest:self)
// } let list2 = MTMathList(list)
// try checkListCopy(list2, original:list, forTest:self.description)
// func testAtomInit() throws { }
// var atom = MTMathAtom.atom(withType: .open, value:"(")
// XCTAssertEqual(atom.nucleus, "("); func testAtomInit() throws {
// XCTAssertEqual(atom.type, .open); var atom = MTMathAtom(type: .open, value: "(")
// XCTAssertEqual(atom.nucleus, "(")
// atom = MTMathAtom.atom(withType: .radical, value:"(") XCTAssertEqual(atom.type, .open)
// XCTAssertEqual(atom.nucleus, "");
// XCTAssertEqual(atom.type, .radical); atom = MTMathAtom(type: .radical, value:"(")
// } XCTAssertEqual(atom.nucleus, "");
// XCTAssertEqual(atom.type, .radical);
// func testAtomScripts() throws { }
// var atom = MTMathAtom.atom(withType: .open, value:"(")
// XCTAssertTrue(atom.isScriptAllowed()) func testAtomScripts() throws {
// atom.subScript = MTMathList() var atom = MTMathAtom(type: .open, value:"(")
// XCTAssertNotNil(atom.subScript); XCTAssertTrue(atom.isScriptAllowed())
// atom.superScript = MTMathList() atom.subScript = MTMathList()
// XCTAssertNotNil(atom.superScript); XCTAssertNotNil(atom.subScript);
// atom.superScript = MTMathList()
// atom = MTMathAtom.atom(withType: .boundary, value:"(") XCTAssertNotNil(atom.superScript);
// XCTAssertFalse(atom.isScriptAllowed());
// // Can set to nil atom = MTMathAtom(type: .boundary, value:"(")
// atom.subScript = nil; XCTAssertFalse(atom.isScriptAllowed());
// XCTAssertNil(atom.subScript); // Can set to nil
// atom.superScript = nil; atom.subScript = nil;
// XCTAssertNil(atom.superScript); XCTAssertNil(atom.subScript);
// // Can't set to value atom.superScript = nil;
// let list = MTMathList() XCTAssertNil(atom.superScript);
// XCTAssertThrowsError(atom.subScript = list); // Can't set to value
// XCTAssertThrowsError(atom.superScript = list); let list = MTMathList()
// }
// XCTExpectFailure("No sub/super-script on boundary atoms", options: options) {
// func testAtomCopy() throws { XCTAssertThrowsError(atom.subScript = list)
// let list = MTMathList() XCTAssertThrowsError(atom.superScript = list)
// let atom1 = MTMathAtomFactory.placeholder() }
// let atom2 = MTMathAtomFactory.times() }
// let atom3 = MTMathAtomFactory.divide()
// list.add(atom1) func testAtomCopy() throws {
// list.add(atom2); let list = MTMathList()
// list.add(atom3) let atom1 = MTMathAtomFactory.placeholder()
// let atom2 = MTMathAtomFactory.times()
// let list2 = MTMathList() let atom3 = MTMathAtomFactory.divide()
// list2.add(atom3) list.add(atom1)
// list2.add(atom2) list.add(atom2);
// list.add(atom3)
// let atom = MTMathAtom.atom(withType: .open, value:"(")
// atom.subScript = list; let list2 = MTMathList()
// atom.superScript = list2; list2.add(atom3)
// let copy = atom.copy() list2.add(atom2)
//
// checkAtomCopy(copy, original:atom, forTest:self) let atom = MTMathAtom(type: .open, value:"(")
// checkListCopy(copy.superScript, original:atom.superScript, forTest:self) atom.subScript = list;
// checkListCopy(copy.subScript, original:atom.subScript, forTest:self) atom.superScript = list2;
// } let copy : MTMathAtom = atom.copy()
//
// func testCopyFraction() throws { try checkAtomCopy(copy, original:atom, forTest:self.description)
// let list = MTMathList() try checkListCopy(copy.superScript, original:atom.superScript, forTest:self.description)
// let atom = MTMathAtomFactory.placeholder() try checkListCopy(copy.subScript, original:atom.subScript, forTest:self.description)
// let atom2 = MTMathAtomFactory.times() }
// let atom3 = MTMathAtomFactory.divide()
// list.add(atom) func testCopyFraction() throws {
// list.add(atom2); let list = MTMathList()
// list.add(atom3) let atom = MTMathAtomFactory.placeholder()
// let atom2 = MTMathAtomFactory.times()
// let list2 = MTMathList() let atom3 = MTMathAtomFactory.divide()
// list2.add(atom3) list.add(atom)
// list2.add(atom2) list.add(atom2);
// list.add(atom3)
// let frac = MTFraction(hasRule: false)
// XCTAssertEqual(frac.type, .fraction); let list2 = MTMathList()
// frac.numerator = list; list2.add(atom3)
// frac.denominator = list2; list2.add(atom2)
// frac.leftDelimiter = "a";
// frac.rightDelimiter = "b"; let frac = MTFraction(hasRule: false)
// XCTAssertEqual(frac.type, .fraction);
// let copy = frac.copy() as! MTFraction frac.numerator = list;
// try checkAtomCopy(copy, original:frac, forTest:self) frac.denominator = list2;
// checkListCopy(copy.numerator, original:frac.numerator, forTest:self) frac.leftDelimiter = "a";
// checkListCopy(copy.denominator, original:frac.denominator, forTest:self) frac.rightDelimiter = "b";
// XCTAssertFalse(copy.hasRule)
// XCTAssertEqual(copy.leftDelimiter, "a"); let copy = MTFraction(frac)
// XCTAssertEqual(copy.rightDelimiter, "b"); try checkAtomCopy(copy, original:frac, forTest:self.description)
// } try checkListCopy(copy.numerator, original:frac.numerator, forTest:self.description)
// try checkListCopy(copy.denominator, original:frac.denominator, forTest:self.description)
// func testCopyRadical() throws { XCTAssertFalse(copy.hasRule)
// let list = MTMathList() XCTAssertEqual(copy.leftDelimiter, "a");
// let atom = MTMathAtomFactory.placeholder() XCTAssertEqual(copy.rightDelimiter, "b");
// let atom2 = MTMathAtomFactory.times() }
// let atom3 = MTMathAtomFactory.divide()
// list.add(atom) func testCopyRadical() throws {
// list.add(atom2); let list = MTMathList()
// list.add(atom3) let atom = MTMathAtomFactory.placeholder()
// let atom2 = MTMathAtomFactory.times()
// let list2 = MTMathList() let atom3 = MTMathAtomFactory.divide()
// list2.add(atom3) list.add(atom)
// list2.add(atom2) list.add(atom2);
// list.add(atom3)
// let rad = [[MTRadical alloc] init)
// XCTAssertEqual(rad.type, kMTMathAtomRadical); let list2 = MTMathList()
// rad.radicand = list; list2.add(atom3)
// rad.degree = list2; list2.add(atom2)
//
// let copy = [rad copy) let rad = MTRadical()
// checkAtomCopy(copy original:rad forTest:self) XCTAssertEqual(rad.type, .radical)
// checkListCopy(copy.radicand original:rad.radicand forTest:self) rad.radicand = list;
// checkListCopy(copy.degree original:rad.degree forTest:self) rad.degree = list2;
// }
// let copy = MTRadical(rad)
// func testCopyLargeOperator() throws { try checkAtomCopy(copy, original:rad, forTest:self.description)
// let lg = [[MTLargeOperator alloc] initWithValue:"lim" limits:true) try checkListCopy(copy.radicand, original:rad.radicand ,forTest:self.description)
// XCTAssertEqual(lg.type, kMTMathAtomLargeOperator); try checkListCopy(copy.degree, original:rad.degree, forTest:self.description)
// XCTAssertTrue(lg.limits); }
//
// let copy = [lg copy) func testCopyLargeOperator() throws {
// checkAtomCopy(copy original:lg forTest:self) let lg = MTLargeOperator(value: "lim", limits:true)
// XCTAssertEqual(copy.limits, lg.limits); XCTAssertEqual(lg.type, .largeOperator);
// } XCTAssertTrue(lg.limits);
// func testCopyInner() throws {
// let list = MTMathList() let copy = MTLargeOperator(lg)
// let atom = MTMathAtomFactory.placeholder() try checkAtomCopy(copy, original:lg, forTest:self.description)
// let atom2 = MTMathAtomFactory.times() XCTAssertEqual(copy.limits, lg.limits);
// let atom3 = MTMathAtomFactory.divide() }
// list.add(atom)
// list.add(atom2); func testCopyInner() throws {
// list.add(atom3) let list = MTMathList()
// let atom = MTMathAtomFactory.placeholder()
// let inner = MTInner() let atom2 = MTMathAtomFactory.times()
// inner.innerList = list; let atom3 = MTMathAtomFactory.divide()
// inner.leftBoundary = MTMathAtom.atom(withType: .boundary, value: "(") list.add(atom)
// inner.rightBoundary = MTMathAtom.atom(withType: .boundary, value:")") list.add(atom2);
// XCTAssertEqual(inner.type, .inner); list.add(atom3)
//
// let copy = [inner copy) let inner = MTInner()
// checkAtomCopy(copy original:inner forTest:self) inner.innerList = list;
// checkListCopy(copy.innerList original:inner.innerList forTest:self) inner.leftBoundary = MTMathAtom(type: .boundary, value: "(")
// checkAtomCopy(copy.leftBoundary original:inner.leftBoundary forTest:self) inner.rightBoundary = MTMathAtom(type: .boundary, value:")")
// checkAtomCopy(copy.rightBoundary original:inner.rightBoundary forTest:self) XCTAssertEqual(inner.type, .inner);
// }
// let copy = MTInner(inner)
// func testSetInnerBoundary() throws { try checkAtomCopy(copy, original:inner, forTest:self.description)
// let inner = MTInner() try checkListCopy(copy.innerList, original:inner.innerList, forTest:self.description)
// try checkAtomCopy(copy.leftBoundary!, original:inner.leftBoundary, forTest:self.description)
// // Can set non-nil try checkAtomCopy(copy.rightBoundary, original:inner.rightBoundary, forTest:self.description)
// inner.leftBoundary = MTMathAtom.atom(withType: .boundary, value:"(") }
// inner.rightBoundary = MTMathAtom.atom(withType: .boundary, value:")")
// XCTAssertNotNil(inner.leftBoundary); func testSetInnerBoundary() throws {
// XCTAssertNotNil(inner.rightBoundary); let inner = MTInner()
// // Can set nil
// inner.leftBoundary = nil; // Can set non-nil
// inner.rightBoundary = nil; inner.leftBoundary = MTMathAtom(type: .boundary, value:"(")
// XCTAssertNil(inner.leftBoundary); inner.rightBoundary = MTMathAtom(type: .boundary, value:")")
// XCTAssertNil(inner.rightBoundary); XCTAssertNotNil(inner.leftBoundary);
// // Can't set non boundary XCTAssertNotNil(inner.rightBoundary);
// let atom = MTMathAtomFactory.placeholder() // Can set nil
// XCTAssertThrowsError(inner.leftBoundary = atom); inner.leftBoundary = nil;
// XCTAssertThrowsError(inner.rightBoundary = atom); inner.rightBoundary = nil;
// } XCTAssertNil(inner.leftBoundary);
// XCTAssertNil(inner.rightBoundary);
// func testCopyOverline() throws { // Can't set non boundary
// let list = MTMathList() let atom = MTMathAtomFactory.placeholder()
// let atom = MTMathAtomFactory.placeholder() XCTExpectFailure("Setting illegal boundary atoms", options: options) {
// let atom2 = MTMathAtomFactory.times() XCTAssertThrowsError(inner.leftBoundary = atom);
// let atom3 = MTMathAtomFactory.divide() XCTAssertThrowsError(inner.rightBoundary = atom);
// list.add(atom) }
// list.add(atom2); }
// list.add(atom3)
// func testCopyOverline() throws {
// let over = MTOverLine() let list = MTMathList()
// XCTAssertEqual(over.type, .overline); let atom = MTMathAtomFactory.placeholder()
// over.innerList = list; let atom2 = MTMathAtomFactory.times()
// let atom3 = MTMathAtomFactory.divide()
// let copy = [over copy) list.add(atom)
// checkAtomCopy(copy original:over forTest:self) list.add(atom2);
// checkListCopy(copy.innerList original:over.innerList forTest:self) list.add(atom3)
// }
// let over = MTOverLine()
// func testCopyUnderline() throws { XCTAssertEqual(over.type, .overline);
// let list = MTMathList() over.innerList = list;
// let atom = MTMathAtomFactory.placeholder()
// let atom2 = MTMathAtomFactory.times() let copy = MTOverLine(over)
// let atom3 = MTMathAtomFactory.divide() try checkAtomCopy(copy, original:over, forTest:self.description)
// list.add(atom) try checkListCopy(copy.innerList, original:over.innerList, forTest:self.description)
// list.add(atom2); }
// list.add(atom3)
// func testCopyUnderline() throws {
// let under = MTUnderLine() let list = MTMathList()
// XCTAssertEqual(under.type, .underline); let atom = MTMathAtomFactory.placeholder()
// under.innerList = list; let atom2 = MTMathAtomFactory.times()
// let atom3 = MTMathAtomFactory.divide()
// let copy = [under copy) list.add(atom)
// checkAtomCopy(copy, original:under, forTest:self) list.add(atom2);
// checkListCopy(copy.innerList original:under.innerList forTest:self) list.add(atom3)
// }
// let under = MTUnderLine()
// func testCopyAcccent() throws { XCTAssertEqual(under.type, .underline);
// let list = MTMathList() under.innerList = list;
// let atom = MTMathAtomFactory.placeholder()
// let atom2 = MTMathAtomFactory.times() let copy = MTUnderLine(under)
// let atom3 = MTMathAtomFactory.divide() try checkAtomCopy(copy, original:under, forTest:self.description)
// list.add(atom) try checkListCopy(copy.innerList, original:under.innerList, forTest:self.description)
// list.add(atom2); }
// list.add(atom3)
// func testCopyAcccent() throws {
// let accent = [[MTAccent alloc] initWithValue:"^") let list = MTMathList()
// XCTAssertEqual(accent.type, kMTMathAtomAccent); let atom = MTMathAtomFactory.placeholder()
// accent.innerList = list; let atom2 = MTMathAtomFactory.times()
// let atom3 = MTMathAtomFactory.divide()
// let copy = [accent copy) list.add(atom)
// checkAtomCopy(copy original:accent forTest:self) list.add(atom2);
// checkListCopy(copy.innerList original:accent.innerList forTest:self) list.add(atom3)
// }
// let accent = MTAccent(value: "^")
// func testCopySpace() throws { XCTAssertEqual(accent.type, .accent);
// let space = MTMathSpace(space: 3) accent.innerList = list;
// XCTAssertEqual(space.type, .space);
// let copy = MTAccent(accent)
// let copy = [space copy) try checkAtomCopy(copy, original:accent, forTest:self.description)
// checkAtomCopy(copy, original:space, forTest:self) try checkListCopy(copy.innerList ,original:accent.innerList, forTest:self.description)
// XCTAssertEqual(space.space, copy.space); }
// }
// func testCopySpace() throws {
// func testCopyStyle() throws { let space = MTMathSpace(space: 3)
// let style = MTMathStyle(style: .script) XCTAssertEqual(space.type, .space);
// XCTAssertEqual(style.type, .style);
// let copy = MTMathSpace(space)
// let copy = style.copy() as! MTMathStyle try checkAtomCopy(copy, original:space, forTest:self.description)
// checkAtomCopy(copy, original:style, forTest:self) XCTAssertEqual(space.space, copy.space);
// XCTAssertEqual(style.style, copy.style); }
// }
// func testCopyStyle() throws {
// func testCreateMathTable() throws { let style = MTMathStyle(style: .script)
// let table = MTMathTable() XCTAssertEqual(style.type, .style);
// XCTAssertEqual(table.type, .table);
// let copy = MTMathStyle(style)
// let list = MTMathList() try checkAtomCopy(copy, original:style, forTest:self.description)
// let atom = MTMathAtomFactory.placeholder() XCTAssertEqual(style.style, copy.style);
// let atom2 = MTMathAtomFactory.times() }
// let atom3 = MTMathAtomFactory.divide()
// list.add(atom) func testCreateMathTable() throws {
// list.add(atom2); let table = MTMathTable()
// list.add(atom3) XCTAssertEqual(table.type, .table);
//
// let list2 = MTMathList() let list = MTMathList()
// list2.add(atom3) let atom = MTMathAtomFactory.placeholder()
// list2.add(atom2) let atom2 = MTMathAtomFactory.times()
// let atom3 = MTMathAtomFactory.divide()
// table.set(cell: list, forRow:3, column:2) list.add(atom)
// table.set(cell: list2, forRow:1, column:0) list.add(atom2);
// list.add(atom3)
// table.set(alignment: .left, forColumn: 2)
// table.set(alignment: .right, forColumn:1) let list2 = MTMathList()
// list2.add(atom3)
// // Verify that everything is created correctly list2.add(atom2)
// XCTAssertEqual(table.cells.count, 4); // 4 rows
// XCTAssertNotNil(table.cells[0]); table.set(cell: list, forRow:3, column:2)
// XCTAssertEqual(table.cells[0].count, 0); // 0 elements in row 0 table.set(cell: list2, forRow:1, column:0)
// XCTAssertEqual(table.cells[1].count, 1); // 1 element in row 1
// XCTAssertNotNil(table.cells[2]); table.set(alignment: .left, forColumn: 2)
// XCTAssertEqual(table.cells[2].count, 0); table.set(alignment: .right, forColumn:1)
// XCTAssertEqual(table.cells[3].count, 3);
// // Verify that everything is created correctly
// // Verify the elements in the rows XCTAssertEqual(table.cells.count, 4); // 4 rows
// XCTAssertEqual(table.cells[1][0].atoms.count, 2); XCTAssertNotNil(table.cells[0]);
// XCTAssertEqual(table.cells[1][0], list2); XCTAssertEqual(table.cells[0].count, 0); // 0 elements in row 0
// XCTAssertNotNil(table.cells[3][0]); XCTAssertEqual(table.cells[1].count, 1); // 1 element in row 1
// XCTAssertEqual(table.cells[3][0].atoms.count, 0); XCTAssertNotNil(table.cells[2]);
// XCTAssertEqual(table.cells[2].count, 0);
// XCTAssertNotNil(table.cells[3][0]); XCTAssertEqual(table.cells[3].count, 3);
// XCTAssertEqual(table.cells[3][0].atoms.count, 0);
// // Verify the elements in the rows
// XCTAssertNotNil(table.cells[3][1]); XCTAssertEqual(table.cells[1][0].atoms.count, 2);
// XCTAssertEqual(table.cells[3][1].atoms.count, 0); XCTAssertEqual(table.cells[1][0], list2);
// XCTAssertNotNil(table.cells[3][0]);
// XCTAssertEqual(table.cells[3][2], list); XCTAssertEqual(table.cells[3][0].atoms.count, 0);
//
// XCTAssertEqual(table.numRows, 4); XCTAssertNotNil(table.cells[3][0]);
// XCTAssertEqual(table.numColumns, 3); XCTAssertEqual(table.cells[3][0].atoms.count, 0);
//
// // Verify the alignments XCTAssertNotNil(table.cells[3][1]);
// XCTAssertEqual(table.alignments.count, 3); XCTAssertEqual(table.cells[3][1].atoms.count, 0);
// XCTAssertEqual(table.alignments[0], .center);
// XCTAssertEqual(table.alignments[1], .right); XCTAssertEqual(table.cells[3][2], list);
// XCTAssertEqual(table.alignments[2], .left);
// } XCTAssertEqual(table.numRows, 4);
// XCTAssertEqual(table.numColumns, 3);
// func testCopyMathTable() throws {
// let table = MTMathTable() // Verify the alignments
// XCTAssertEqual(table.type, .table); XCTAssertEqual(table.alignments.count, 3);
// XCTAssertEqual(table.alignments[0], .center);
// let list = MTMathList() XCTAssertEqual(table.alignments[1], .right);
// let atom = MTMathAtomFactory.placeholder() XCTAssertEqual(table.alignments[2], .left);
// let atom2 = MTMathAtomFactory.times() }
// let atom3 = MTMathAtomFactory.divide()
// list.add(atom) func testCopyMathTable() throws {
// list.add(atom2); let table = MTMathTable()
// list.add(atom3) XCTAssertEqual(table.type, .table);
//
// let list2 = MTMathList() let list = MTMathList()
// list2.add(atom3) let atom = MTMathAtomFactory.placeholder()
// list2.add(atom2) let atom2 = MTMathAtomFactory.times()
// let atom3 = MTMathAtomFactory.divide()
// table.set(cell:list, forRow:0, column:1) list.add(atom)
// table.set(cell:list2, forRow:0, column:2) list.add(atom2);
// list.add(atom3)
// table.set(alignment: .left, forColumn:2)
// table.set(alignment: .right, forColumn:1) let list2 = MTMathList()
// table.interRowAdditionalSpacing = 3; list2.add(atom3)
// table.interColumnSpacing = 10; list2.add(atom2)
//
// let copy = table.copy() as! MTMathTable table.set(cell:list, forRow:0, column:1)
// try checkAtomCopy(copy, original:table, forTest:self) table.set(cell:list2, forRow:0, column:2)
// XCTAssertEqual(copy.interColumnSpacing, table.interColumnSpacing);
// XCTAssertEqual(copy.interRowAdditionalSpacing, table.interRowAdditionalSpacing); table.set(alignment: .left, forColumn:2)
// XCTAssertEqual(copy.alignments, table.alignments); table.set(alignment: .right, forColumn:1)
// XCTAssertNotEqual(copy.alignments, table.alignments); table.interRowAdditionalSpacing = 3;
// table.interColumnSpacing = 10;
// XCTAssertNotEqual(copy.cells, table.cells);
// XCTAssertNotEqual(copy.cells[0], table.cells[0]); let copy = MTMathTable(table)
// XCTAssertEqual(copy.cells[0].count, table.cells[0].count); try checkAtomCopy(copy, original:table, forTest:self.description)
// XCTAssertEqual(copy.cells[0][0].atoms.count, 0); XCTAssertEqual(copy.interColumnSpacing, table.interColumnSpacing);
// XCTAssertNotEqual(copy.cells[0][0], table.cells[0][0]); XCTAssertEqual(copy.interRowAdditionalSpacing, table.interRowAdditionalSpacing);
// try checkListCopy(copy.cells[0][1], original:list, forTest:self) XCTAssertEqual(copy.alignments, table.alignments)
// try checkListCopy(copy.cells[0][2], original:list2, forTest:self)
// } 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.description)
try checkListCopy(copy.cells[0][2], original:list2, forTest:self.description)
}
} }