http://git-wip-us.apache.org/repos/asf/flex-tlf/blob/d92c169e/automation_tests/src/UnitTest/Tests/GeneralFunctionsTest.as ---------------------------------------------------------------------- diff --git a/automation_tests/src/UnitTest/Tests/GeneralFunctionsTest.as b/automation_tests/src/UnitTest/Tests/GeneralFunctionsTest.as index 134f99c..fd022cb 100644 --- a/automation_tests/src/UnitTest/Tests/GeneralFunctionsTest.as +++ b/automation_tests/src/UnitTest/Tests/GeneralFunctionsTest.as @@ -18,33 +18,30 @@ //////////////////////////////////////////////////////////////////////////////// package UnitTest.Tests { - import UnitTest.ExtendedClasses.TestDescriptor; - import UnitTest.ExtendedClasses.TestSuiteExtended; - import UnitTest.ExtendedClasses.VellumTestCase; - import UnitTest.Fixtures.TestConfig; - import UnitTest.Fixtures.TestEditManager; - - import flash.display.Sprite; - import flash.events.*; - import flash.text.engine.FontPosture; - import flash.text.engine.FontWeight; - import flash.ui.Keyboard; - import flash.utils.getDefinitionByName; - import flash.utils.getQualifiedClassName; - - import flashx.textLayout.container.ContainerController; - import flashx.textLayout.conversion.ITextImporter; - import flashx.textLayout.conversion.TextConverter; - import flashx.textLayout.edit.EditManager; - import flashx.textLayout.elements.*; - import flashx.textLayout.events.FlowOperationEvent; - import flashx.textLayout.events.SelectionEvent; - import flashx.textLayout.events.StatusChangeEvent; - import flashx.textLayout.formats.*; - import flashx.textLayout.operations.FlowOperation; - import flashx.textLayout.operations.UndoOperation; - import flashx.textLayout.tlf_internal; - import flashx.undo.UndoManager; + import UnitTest.ExtendedClasses.VellumTestCase; + import UnitTest.Fixtures.TestConfig; + import UnitTest.Fixtures.TestEditManager; + + import flash.display.Sprite; + import flash.events.*; + import flash.text.engine.FontPosture; + import flash.text.engine.FontWeight; + import flash.ui.Keyboard; + import flash.utils.getQualifiedClassName; + + import flashx.textLayout.container.ContainerController; + import flashx.textLayout.conversion.ITextImporter; + import flashx.textLayout.conversion.TextConverter; + import flashx.textLayout.edit.EditManager; + import flashx.textLayout.elements.*; + import flashx.textLayout.events.FlowOperationEvent; + import flashx.textLayout.events.SelectionEvent; + import flashx.textLayout.events.StatusChangeEvent; + import flashx.textLayout.formats.*; + import flashx.textLayout.operations.FlowOperation; + import flashx.textLayout.operations.UndoOperation; + import flashx.textLayout.tlf_internal; + import flashx.undo.UndoManager; import org.flexunit.asserts.assertTrue; import org.flexunit.asserts.fail; @@ -52,1296 +49,1336 @@ package UnitTest.Tests use namespace tlf_internal; - public class GeneralFunctionsTest extends VellumTestCase - { - public var SelectionChanged:Boolean; - private var callback:Boolean; - - public function GeneralFunctionsTest(methodName:String, testID:String, testConfig:TestConfig, testXML:XML = null) - { - super(methodName, testID, testConfig); - - // Note: These must correspond to a Watson product area (case-sensitive) - metaData.productArea = "Editing"; - } - - public static function suite(testConfig:TestConfig, ts:TestSuiteExtended):void - { - ts.addTestDescriptor (new TestDescriptor(GeneralFunctionsTest, "arrowLeft", testConfig) ); - ts.addTestDescriptor (new TestDescriptor(GeneralFunctionsTest, "arrowRight", testConfig) ); - //ts.addTestDescriptor (new TestDescriptor(GeneralFunctionsTest, "arrowDown", testConfig) ); - //ts.addTestDescriptor (new TestDescriptor(GeneralFunctionsTest, "arrowUp", testConfig) ); - ts.addTestDescriptor (new TestDescriptor(GeneralFunctionsTest, "replaceSelectionTest", testConfig) ); - ts.addTestDescriptor (new TestDescriptor(GeneralFunctionsTest, "backSpaceSelectionTest", testConfig) ); // KJT - ts.addTestDescriptor (new TestDescriptor(GeneralFunctionsTest, "backSpaceInsertionPointTest", testConfig) ); - ts.addTestDescriptor (new TestDescriptor(GeneralFunctionsTest, "backSpaceLowerLimitTest", testConfig) ); - ts.addTestDescriptor (new TestDescriptor(GeneralFunctionsTest, "deleteSelectionTest", testConfig) ); - ts.addTestDescriptor (new TestDescriptor(GeneralFunctionsTest, "deleteInsertionPointTest", testConfig) ); - ts.addTestDescriptor (new TestDescriptor(GeneralFunctionsTest, "deleteUpperLimitTest", testConfig) ); - ts.addTestDescriptor (new TestDescriptor(GeneralFunctionsTest, "splitParagraphInsertionPointTest", testConfig) ); - ts.addTestDescriptor (new TestDescriptor(GeneralFunctionsTest, "splitParagraphSelectionTest", testConfig) ); - ts.addTestDescriptor (new TestDescriptor(GeneralFunctionsTest, "splitParagraphFormatTest", testConfig) ); - ts.addTestDescriptor (new TestDescriptor(GeneralFunctionsTest, "unDoOp", testConfig) ); // undo redo// KJT - ts.addTestDescriptor (new TestDescriptor(GeneralFunctionsTest, "setSelectionRangeTest", testConfig) );// select range and listen for change event // KJT - ts.addTestDescriptor (new TestDescriptor(GeneralFunctionsTest, "insertTextTest", testConfig) ); // KJT - ts.addTestDescriptor (new TestDescriptor(GeneralFunctionsTest, "joinedBackspaceUndoTest", testConfig) ); - ts.addTestDescriptor (new TestDescriptor(GeneralFunctionsTest, "joinedDeleteUndoTest", testConfig) ); - /* Waiting for troubleshooting -*/ ts.addTestDescriptor (new TestDescriptor(GeneralFunctionsTest, "joinedInsertUndoTest", testConfig) ); - ts.addTestDescriptor (new TestDescriptor(GeneralFunctionsTest, "joinedSplitParagraphUndoTest", testConfig) ); - ts.addTestDescriptor (new TestDescriptor(GeneralFunctionsTest, "undoLimitTest", testConfig) ); - ts.addTestDescriptor (new TestDescriptor(GeneralFunctionsTest, "transParagraphDeleteTest", testConfig) ); - ts.addTestDescriptor (new TestDescriptor(GeneralFunctionsTest, "emptyParagraphTest", testConfig) ); - ts.addTestDescriptor (new TestDescriptor(GeneralFunctionsTest, "splitUTF16Test", testConfig) ); - ts.addTestDescriptor (new TestDescriptor(GeneralFunctionsTest, "splitUTF32Test", testConfig) ); - ts.addTestDescriptor (new TestDescriptor(GeneralFunctionsTest, "undoWithModelChangeTest", testConfig) ); - ts.addTestDescriptor (new TestDescriptor(GeneralFunctionsTest, "doubleClickTest", testConfig) ); - ts.addTestDescriptor (new TestDescriptor(GeneralFunctionsTest, "doubleClickHyphenTest", testConfig) ); - ts.addTestDescriptor (new TestDescriptor(GeneralFunctionsTest, "doubleClickPunctuationTest", testConfig) ); - ts.addTestDescriptor (new TestDescriptor(GeneralFunctionsTest, "undoRedoStackTest", testConfig) ); - if (testConfig.writingDirection[0] == BlockProgression.TB && testConfig.writingDirection[1] == Direction.LTR) - { - ts.addTestDescriptor (new TestDescriptor(GeneralFunctionsTest, "replaceChildrenFlowTest", testConfig) ); - ts.addTestDescriptor (new TestDescriptor(GeneralFunctionsTest, "resolveInlinesTest", testConfig) ); - ts.addTestDescriptor (new TestDescriptor(GeneralFunctionsTest, "nestingTest", testConfig) ); - ts.addTestDescriptor (new TestDescriptor(GeneralFunctionsTest, "errorThrowing", testConfig ) ); - ts.addTestDescriptor (new TestDescriptor(GeneralFunctionsTest, "AllNestingTest", testConfig ) ); - } - } - - /** - * selecting text from 10 to 20 - */ - - public function selChange(e:Event):void //KJT selection change event method - { - SelectionChanged = true; - } - - public function setSelectionRangeTest():void //KJT test selection range and change event - { - var startIndx:int = 800; - var endIndx:int = 933; - //trace('CALL SET SELECTION'); - - SelManager.textFlow.addEventListener(SelectionEvent.SELECTION_CHANGE, selChange, false, 0, true); - SelManager.selectRange(startIndx,endIndx); - - assertTrue("beginning index should be 800, but is " + SelManager.anchorPosition, - SelManager.anchorPosition == 800); - assertTrue("end index should be 933, but is " + SelManager.activePosition, - SelManager.activePosition == 933); - assertTrue("SelectionChanged returned false", SelectionChanged == true); - } - /** - * Select 40 characters and replaces them with new text - */ - public function replaceSelectionTest():void - { - var startIndx:int = 10; - var endIndx:int = 50; - - var attributes:TextLayoutFormat = new TextLayoutFormat(); - attributes.fontWeight = FontWeight.BOLD; - attributes.lineThrough = true; - - SelManager.selectRange(startIndx,endIndx); - SelManager.applyLeafFormat(attributes); - - SelManager.insertText("New"); - SelManager.flushPendingOperations(); - - var leaf:FlowLeafElement = SelManager.textFlow.findLeaf(startIndx); - var attributesNew:ITextLayoutFormat = leaf.format; - assertTrue("Invalid point format after block deletion", TextLayoutFormat.isEqual(attributes, attributesNew)); - } - /** - * Select 40 characters and delete them. - */ - public function backSpaceSelectionTest():void - { - var startIndx:int = 10; - var endIndx:int = 50; - - var attributes:TextLayoutFormat = new TextLayoutFormat(); - attributes.fontWeight = FontWeight.BOLD; - attributes.lineThrough = true; - - SelManager.selectRange(startIndx,endIndx); - SelManager.applyLeafFormat(attributes); - - var initLength:uint = SelManager.textFlow.textLength; - SelManager.deletePreviousCharacter(); - var endLength:uint = SelManager.textFlow.textLength; - - assertTrue("deleting the selection should have removed " +(endIndx - startIndx) + - " characters. It actually removed " + (initLength - endLength), - endLength == initLength - (endIndx - startIndx) ); - - SelManager.insertText("New"); - SelManager.flushPendingOperations(); - - var leaf:FlowLeafElement = SelManager.textFlow.findLeaf(startIndx); - var attributesNew:ITextLayoutFormat = leaf.format; - assertTrue("Invalid point format after block deletion", TextLayoutFormat.isEqual(attributes, attributesNew)); - } - - /** - * Set the cursor position back ten characters and delete the first ten characters. - */ - public function backSpaceInsertionPointTest():void - { - var n:int = 10; - SelManager.selectRange(n,n); - - var initLength:uint = SelManager.textFlow.textLength; - - for(var i:int = 0; i < n; i++){ - SelManager.deletePreviousCharacter(); - } - - var endLength:uint = SelManager.textFlow.textLength; - - assertTrue("should have removed " + n + " characters. Actually removed " + - (initLength - endLength) , endLength == initLength - n); - } - - /** - * Set the cursor position back nine characters and delete the first ten characters. - * Ensure that only nine characters are deleted. - */ - public function backSpaceLowerLimitTest():void - { - var n:int = 9; - SelManager.selectRange(n,n); - - var initLength:uint = SelManager.textFlow.textLength; - - for(var i:int = 0; i <= n; i++){ - SelManager.deletePreviousCharacter(); - } - - var endLength:uint = SelManager.textFlow.textLength; - - assertTrue("should have removed " + n + " characters. Actually removed " + - (initLength - endLength) , endLength == initLength - n); - } - - /** - * Select 40 characters and delete them. - */ - public function deleteSelectionTest():void - { - var startIndx:int = 10; - var endIndx:int = 50; - - SelManager.selectRange(startIndx,endIndx); - - var initLength:uint = SelManager.textFlow.textLength; - SelManager.deleteNextCharacter(); - var endLength:uint = SelManager.textFlow.textLength; - - assertTrue("should have removed " + (endIndx - startIndx) + " characters. Actually removed " + - (initLength - endLength) , endLength == initLength - (endIndx - startIndx) ); - } - - /** - * Delete the first ten characters. - */ - public function deleteInsertionPointTest():void - { - var n:int = 10; - SelManager.selectRange(0,0); - - var initLength:uint = SelManager.textFlow.textLength; - - for(var i:int = 0; i < n; i++){ - SelManager.deleteNextCharacter(); - } - - var endLength:uint = SelManager.textFlow.textLength; - - assertTrue("should have removed " + n + " characters. Actually removed " + - (initLength - endLength), endLength == initLength - n); - } - - /** - * Set the cursor position back nine characters and delete the first ten characters. - * Ensure that only nine characters are deleted. - */ - public function deleteUpperLimitTest():void - { - var n:int = 9; - - var initLength:uint = SelManager.textFlow.textLength; - SelManager.selectRange(initLength - (n+1), initLength - (n+1)); - - for(var i:int = 0; i < n; i++){ - SelManager.deleteNextCharacter(); - } - - var endLength:uint = SelManager.textFlow.textLength; - - assertTrue("should have removed " + n + " characters. Actually removed " + - (initLength - endLength) , endLength == initLength - n); - } + public class GeneralFunctionsTest extends VellumTestCase + { + public static const childParentTable:Array = + [ + [ "child\parent", TextFlow, DivElement, ParagraphElement, LinkElement, TCYElement, SpanElement, InlineGraphicElement, BreakElement, TabElement, ListElement, ListItemElement, SubParagraphGroupElement ], + [ TextFlow, "no", "no", "no", "no", "no", "no", "no", "no", "no", "no", "no", "no" ], + [ DivElement, "yes", "yes", "no", "no", "no", "no", "no", "no", "no", "yes", "yes", "no" ], + [ ParagraphElement, "yes", "yes", "no", "no", "no", "no", "no", "no", "no", "yes", "yes", "no" ], + [ LinkElement, "no", "no", "yes", "no", "yes", "no", "no", "no", "no", "no", "no", "yes" ], + [ TCYElement, "no", "no", "yes", "yes", "no", "no", "no", "no", "no", "no", "no", "yes" ], + [ SpanElement, "no", "no", "yes", "yes", "yes", "no", "no", "no", "no", "no", "no", "yes" ], + [ InlineGraphicElement, "no", "no", "yes", "yes", "yes", "no", "no", "no", "no", "no", "no", "yes" ], + [ BreakElement, "no", "no", "yes", "yes", "yes", "no", "no", "no", "no", "no", "no", "yes" ], + [ TabElement, "no", "no", "yes", "yes", "yes", "no", "no", "no", "no", "no", "no", "yes" ], + [ ListElement, "yes", "yes", "no", "no", "no", "no", "no", "no", "no", "yes", "yes", "no" ], + [ ListItemElement, "no", "no", "no", "no", "no", "no", "no", "no", "no", "yes", "no", "no" ], + [ SubParagraphGroupElement, "no", "no", "yes", "yes", "yes", "no", "no", "no", "no", "no", "no", "yes" ] + ]; + + private static const customResourceDict:Object = + { + invalidFlowElementConstruct_custom: "Attempted construct of invalid FlowElement subclass", + badMXMLChildrenArgument_custom: "Bad element of type {0} passed to mxmlChildren", + malformedTag: "Malformed tag </p/>", + XMLParserFailure: "TypeError: Error #1090: XML parser failure: element is malformed." + }; + + /** + * pick up the actual operation + */ + private var flowOp:FlowOperation; + private var SelectionChanged:Boolean; + private var ilgStatus:String; + + public function GeneralFunctionsTest() + { + super("", "EventOverrideTest", TestConfig.getInstance()); + + metaData = {}; + // Note: These must correspond to a Watson product area (case-sensitive) + metaData.productArea = "Editing"; + } + + + [Before] + override public function setUpTest():void + { + super.setUpTest(); + } + + [After] + override public function tearDownTest():void + { + super.tearDownTest(); + } + + + [Test] + public function setSelectionRangeTest():void //KJT test selection range and change event + { + var startIndx:int = 800; + var endIndx:int = 933; + //trace('CALL SET SELECTION'); + + SelManager.textFlow.addEventListener(SelectionEvent.SELECTION_CHANGE, selChange, false, 0, true); + SelManager.selectRange(startIndx, endIndx); + + assertTrue("beginning index should be 800, but is " + SelManager.anchorPosition, + SelManager.anchorPosition == 800); + assertTrue("end index should be 933, but is " + SelManager.activePosition, + SelManager.activePosition == 933); + assertTrue("SelectionChanged returned false", SelectionChanged == true); + } + + [Test] + /** + * Select 40 characters and replaces them with new text + */ + public function replaceSelectionTest():void + { + var startIndx:int = 10; + var endIndx:int = 50; + + var attributes:TextLayoutFormat = new TextLayoutFormat(); + attributes.fontWeight = FontWeight.BOLD; + attributes.lineThrough = true; + + SelManager.selectRange(startIndx, endIndx); + SelManager.applyLeafFormat(attributes); + + SelManager.insertText("New"); + SelManager.flushPendingOperations(); + + var leaf:FlowLeafElement = SelManager.textFlow.findLeaf(startIndx); + var attributesNew:ITextLayoutFormat = leaf.format; + assertTrue("Invalid point format after block deletion", TextLayoutFormat.isEqual(attributes, attributesNew)); + } + + [Test] + /** + * Select 40 characters and delete them. + */ + public function backSpaceSelectionTest():void + { + var startIndx:int = 10; + var endIndx:int = 50; + + var attributes:TextLayoutFormat = new TextLayoutFormat(); + attributes.fontWeight = FontWeight.BOLD; + attributes.lineThrough = true; + + SelManager.selectRange(startIndx, endIndx); + SelManager.applyLeafFormat(attributes); + + var initLength:uint = SelManager.textFlow.textLength; + SelManager.deletePreviousCharacter(); + var endLength:uint = SelManager.textFlow.textLength; + + assertTrue("deleting the selection should have removed " + (endIndx - startIndx) + + " characters. It actually removed " + (initLength - endLength), + endLength == initLength - (endIndx - startIndx)); + + SelManager.insertText("New"); + SelManager.flushPendingOperations(); + + var leaf:FlowLeafElement = SelManager.textFlow.findLeaf(startIndx); + var attributesNew:ITextLayoutFormat = leaf.format; + assertTrue("Invalid point format after block deletion", TextLayoutFormat.isEqual(attributes, attributesNew)); + } + + [Test] + /** + * Set the cursor position back ten characters and delete the first ten characters. + */ + public function backSpaceInsertionPointTest():void + { + var n:int = 10; + SelManager.selectRange(n, n); + + var initLength:uint = SelManager.textFlow.textLength; + + for (var i:int = 0; i < n; i++) + { + SelManager.deletePreviousCharacter(); + } + + var endLength:uint = SelManager.textFlow.textLength; + + assertTrue("should have removed " + n + " characters. Actually removed " + + (initLength - endLength), endLength == initLength - n); + } + + [Test] + /** + * Set the cursor position back nine characters and delete the first ten characters. + * Ensure that only nine characters are deleted. + */ + public function backSpaceLowerLimitTest():void + { + var n:int = 9; + SelManager.selectRange(n, n); + + var initLength:uint = SelManager.textFlow.textLength; + + for (var i:int = 0; i <= n; i++) + { + SelManager.deletePreviousCharacter(); + } + + var endLength:uint = SelManager.textFlow.textLength; + + assertTrue("should have removed " + n + " characters. Actually removed " + + (initLength - endLength), endLength == initLength - n); + } + + [Test] + /** + * Select 40 characters and delete them. + */ + public function deleteSelectionTest():void + { + var startIndx:int = 10; + var endIndx:int = 50; + + SelManager.selectRange(startIndx, endIndx); + + var initLength:uint = SelManager.textFlow.textLength; + SelManager.deleteNextCharacter(); + var endLength:uint = SelManager.textFlow.textLength; + + assertTrue("should have removed " + (endIndx - startIndx) + " characters. Actually removed " + + (initLength - endLength), endLength == initLength - (endIndx - startIndx)); + } + + [Test] + /** + * Delete the first ten characters. + */ + public function deleteInsertionPointTest():void + { + var n:int = 10; + SelManager.selectRange(0, 0); + + var initLength:uint = SelManager.textFlow.textLength; + + for (var i:int = 0; i < n; i++) + { + SelManager.deleteNextCharacter(); + } + + var endLength:uint = SelManager.textFlow.textLength; + + assertTrue("should have removed " + n + " characters. Actually removed " + + (initLength - endLength), endLength == initLength - n); + } + + [Test] + /** + * Set the cursor position back nine characters and delete the first ten characters. + * Ensure that only nine characters are deleted. + */ + public function deleteUpperLimitTest():void + { + var n:int = 9; + + var initLength:uint = SelManager.textFlow.textLength; + SelManager.selectRange(initLength - (n + 1), initLength - (n + 1)); + + for (var i:int = 0; i < n; i++) + { + SelManager.deleteNextCharacter(); + } + + var endLength:uint = SelManager.textFlow.textLength; + + assertTrue("should have removed " + n + " characters. Actually removed " + + (initLength - endLength), endLength == initLength - n); + } + + [Test] + /** + * Splits the paragraph after the first fifty characters. + * Verifies that there is one more line in the textFlow than it started with. + * Verifies that the first leaf has only 50 characters in it. + */ + public function splitParagraphInsertionPointTest():void + { + var insertPoint:int = 50; + + SelManager.selectRange(insertPoint, insertPoint); + + var initLines:int = SelManager.textFlow.flowComposer.numLines; + SelManager.splitParagraph(); + var endLines:int = SelManager.textFlow.flowComposer.numLines; + + assertTrue("expected one additional line after splitting the paragraph. Actually found " + + (endLines - initLines), initLines = endLines - 1); + + var lengthFirst:int = SelManager.textFlow.getFirstLeaf().textLength; + + assertTrue("expected the first paragraph would have " + insertPoint + + " characters. Actually found " + lengthFirst, lengthFirst = insertPoint); + } + + [Test] + /** + * 1. Sets attributes before (A, B), after (B', C) and at (B'', D) at split point. + * Splits paragraphs, adds new text and verifies that it has attributes (A, B'', C, D) + * 2. Tests special case for splitting a paragraph at the end of a link; point format is reset in this case + */ + public function splitParagraphFormatTest():void + { + var insertPoint:int = 50; + + var attributes:TextLayoutFormat = new TextLayoutFormat(); + + attributes.fontWeight = FontWeight.BOLD; + attributes.lineThrough = true; + SelManager.selectRange(insertPoint - 5, insertPoint); + SelManager.applyLeafFormat(attributes); + + attributes.fontWeight = undefined; + attributes.textDecoration = TextDecoration.UNDERLINE; + attributes.fontSize = 72; + SelManager.selectRange(insertPoint, insertPoint + 5); + SelManager.applyLeafFormat(attributes); + + attributes.textDecoration = TextDecoration.UNDERLINE; + attributes.lineThrough = true; + attributes.fontFamily = "Verdana"; + SelManager.selectRange(insertPoint, insertPoint); + SelManager.applyLeafFormat(attributes); + + SelManager.splitParagraph(); + + SelManager.insertText("New"); + SelManager.flushPendingOperations(); + + var leaf:FlowLeafElement = SelManager.textFlow.findLeaf(insertPoint + 1); + attributes = new TextLayoutFormat(leaf.format); + + assertTrue("Invalid point format for start of a new paragraph", attributes.fontWeight = FontWeight.BOLD); + assertTrue("Invalid point format for start of a new paragraph", attributes.fontSize = 72); + assertTrue("Invalid point format for start of a new paragraph", attributes.fontFamily = "Verdana"); + assertTrue("Invalid point format for start of a new paragraph", attributes.textDecoration == TextDecoration.UNDERLINE && attributes.lineThrough); + + insertPoint = 40; + + SelManager.selectRange(insertPoint - 10, insertPoint); + SelManager.applyLink("http://www.google.com", "_self", false); + + SelManager.selectRange(insertPoint, insertPoint); + SelManager.splitParagraph(); + + SelManager.insertText("New"); + SelManager.flushPendingOperations(); + + leaf = SelManager.textFlow.findLeaf(insertPoint + 1); + attributes = new TextLayoutFormat(leaf.format); + assertTrue("Invalid point format for start of a new paragraph after a link", TextLayoutFormat.isEqual(attributes, TextLayoutFormat.emptyTextLayoutFormat)); + } + + [Test] + /** + * Selects the characters between the 10th and 50th characters and splits the paragraph. + * Verifies that there is one more line in the textFlow than it started with. + * Verifies that the first leaf has only 10 characters in it. + * Verifies that the final length has 39 less characters in it. + */ + public function splitParagraphSelectionTest():void + { + var startIndx:int = 10; + var endIndx:int = 50; + + + SelManager.selectRange(startIndx, endIndx); + + var initLength:int = SelManager.textFlow.textLength; + var initLines:int = SelManager.textFlow.flowComposer.numLines; + + SelManager.splitParagraph(); + + var endLength:int = SelManager.textFlow.textLength; + var endLines:int = SelManager.textFlow.flowComposer.numLines; + + assertTrue("expected one additional line after splitting the paragraph. Actually found " + + (endLines - initLines), initLines = endLines - 1); + + var lengthFirst:int = SelManager.textFlow.getFirstLeaf().textLength; + + assertTrue("expected the first paragraph would have " + startIndx + + " characters. Actually found " + lengthFirst, lengthFirst = startIndx); + assertTrue("expected the entire flow would have " + (initLength - (endIndx - startIndx) + 1) + + " characters. Actually found " + endLength, + endLength == initLength - (endIndx - startIndx) + 1); + } + + [Test] + /** + * Creates a selection area of six characters at the last index of the flow root + * then inserts " BOOGA" into the selection area and verifies the length of the + * flow root has increased by 6. + */ + public function insertTextTest():void //KJT + { + var textLength:uint = SelManager.textFlow.textLength; + SelManager.selectRange(textLength - 1, textLength + 5); + + SelManager.insertText(" BOOGA"); + SelManager.selectRange(textLength - 1, textLength + 5); + + assertTrue("expected to find " + (textLength + 6) + " characters. Actually found " + + SelManager.textFlow.textLength, SelManager.textFlow.textLength == textLength + 6); + } + + [Test] + /** + * Sets the insertion point at 50, then generates the "0" keyboard event + * and verifies that the selBegIdx is 49. + */ + public function arrowLeft():void + { + var event:KeyboardEvent = new KeyboardEvent(KeyboardEvent.KEY_UP, true, false, 0, Keyboard.LEFT); + SelManager.selectRange(50, 50); + SelManager.keyDownHandler(event); + + if (SelManager.textFlow.computedFormat.blockProgression == BlockProgression.RL) + { + // assertTrue("expected insertion point at position 87. Actually found + " + + // SelManager.anchorPosition, SelManager.anchorPosition == 87); + } + else + { + if (SelManager.textFlow.computedFormat.direction == Direction.LTR) + { + assertTrue("expected insertion point at position 49. Actually found + " + + SelManager.activePosition, SelManager.activePosition == 49); + } + else + { + assertTrue("expected insertion point at position 51. Actually found + " + + SelManager.activePosition, SelManager.activePosition == 51); + } + } + } + + [Test] + /** + * Sets the insertion point at 50, then generates the "0" keyboard event + * and verifies that the selBegIdx is 51. + */ + public function arrowRight():void + { + var event:KeyboardEvent = new KeyboardEvent(KeyboardEvent.KEY_UP, true, false, 0, Keyboard.RIGHT); + SelManager.selectRange(50, 50); + SelManager.keyDownHandler(event); + if (SelManager.textFlow.computedFormat.blockProgression == BlockProgression.RL) + { + // assertTrue("expected insertion point at position 11. Actually found + " + + // SelManager.anchorPosition, SelManager.anchorPosition == 11); + } + else + { + if (SelManager.textFlow.computedFormat.direction == Direction.LTR) + { + assertTrue("expected insertion point at position 51. Actually found " + + SelManager.activePosition, SelManager.activePosition == 51); + } + else + { + assertTrue("expected insertion point at position 49. Actually found " + + SelManager.activePosition, SelManager.activePosition == 49); + } + } + } + + [Test] + /** + * Sets the insertion point at 0, then generates the "40" keyboard event + * and verifies that the cursor is on the second line. + */ + public function arrowDown():void + { + var event:KeyboardEvent = new KeyboardEvent(KeyboardEvent.KEY_UP, true, false, 40); + SelManager.selectRange(0, 0); + SelManager.keyDownHandler(event); + if (SelManager.textFlow.computedFormat.blockProgression == BlockProgression.TB) + { + //NYI + } + else + { + var ap:int = SelManager.activePosition; + var index:int = SelManager.textFlow.findChildIndexAtPosition(ap); + assertTrue("expected index at 2. Actually found " + index, index == 2); + } + } + + [Test] + /** + * Sets the insertion point at the last char, then generates the "38" keyboard event + * and verifies that the cursor is on the second to last line. + */ + public function arrowUp():void + { + var event:KeyboardEvent = new KeyboardEvent(KeyboardEvent.KEY_UP, true, false, 38); + var lastChar:int = SelManager.absoluteEnd; + var lastLine:int = SelManager.textFlow.findChildIndexAtPosition(lastChar); + SelManager.selectRange(lastChar, lastChar); + SelManager.keyDownHandler(event); + if (SelManager.textFlow.computedFormat.blockProgression == BlockProgression.TB) + { + //NYI + } + else + { + var index:int = SelManager.textFlow.findChildIndexAtPosition(SelManager.activePosition); + assertTrue("expected index at " + (lastChar - 1) + + ". Actually found " + index, + index == (lastChar - 1) + ); + } + } + + [Test] + /** + * Tests the undo and redo stacks by applying typeface changes by undoing + * and redoing them. + */ + public function unDoOp():void //KJT + { + var ca:TextLayoutFormat = new TextLayoutFormat(); + ca.fontWeight = FontWeight.BOLD; + SelManager.applyLeafFormat(ca); + + SelManager.undo(); + Redo(); + + ca.fontStyle = FontPosture.ITALIC; + SelManager.applyLeafFormat(ca); + + SelManager.undo(); + SelManager.undo(); + } + + [Test] + /** + * Performs successive backspaces and one undo to see if all the deleted content + * is returned, then performs a redo to see if the content is correctly removed + * again. + */ + public function joinedBackspaceUndoTest():void + { + var n:int = 10; + SelManager.selectRange(10, 10); + + var initLength:uint = SelManager.textFlow.textLength; + + for (var i:int = 0; i < n; i++) + { + var event:KeyboardEvent = new KeyboardEvent(KeyboardEvent.KEY_DOWN, true, false, 8); + dispatchEvent(event); + } + + var endLength:uint = SelManager.textFlow.textLength; + + SelManager.undo(); + + var undoLength:uint = SelManager.textFlow.textLength; + + assertTrue("expected text length before undo to be " + n + " less. Was actually " + + (endLength - initLength) + " less.", endLength == initLength - n); + assertTrue("expected text length after undo to be identical to the start, but it was off by " + + (undoLength - initLength), undoLength == initLength); + + Redo(); + + var redoLength:uint = SelManager.textFlow.textLength; + + assertTrue("expected redo length to equal undo length, but found " + + redoLength + " and " + endLength, redoLength == endLength); + } + + [Test] + /** + * Performs successive deletes and one undo to see if all the deleted content + * is returned, then performs a redo to see if the content is correctly removed + * again. + */ + public function joinedDeleteUndoTest():void + { + var n:int = 10; + SelManager.selectRange(10, 10); + + var initLength:uint = SelManager.textFlow.textLength; + + for (var i:int = 0; i < n; i++) + { + var event:KeyboardEvent = new KeyboardEvent(KeyboardEvent.KEY_DOWN, true, false, 127, Keyboard.DELETE); + dispatchEvent(event); + } + SelManager.flushPendingOperations(); + + var endLength:uint = SelManager.textFlow.textLength; + + SelManager.undo(); + + var undoLength:uint = SelManager.textFlow.textLength; + + assertTrue("expected text length before undo to be " + n + " less. Was actually " + + (endLength - initLength) + " less.", endLength == initLength - n); + assertTrue("expected text length after undo to be identical to the start, but it was off by " + + (undoLength - initLength), undoLength == initLength); + + Redo(); + + var redoLength:uint = SelManager.textFlow.textLength; + + assertTrue("expected redo length to equal undo length, but found " + + redoLength + " and " + endLength, redoLength == endLength); + } + + [Test] + /** + * Places a series of letter a's in and does one undo to see if all the a's + * are removed, then performs a redo to see if they're returned. + */ + public function joinedInsertUndoTest():void + { + var n:int = 10; + SelManager.selectRange(10, 10); + + var initLength:uint = SelManager.textFlow.textLength; - /** - * Splits the paragraph after the first fifty characters. - * Verifies that there is one more line in the textFlow than it started with. - * Verifies that the first leaf has only 50 characters in it. - */ - public function splitParagraphInsertionPointTest():void - { - var insertPoint:int = 50; - - SelManager.selectRange(insertPoint, insertPoint); - - var initLines:int = SelManager.textFlow.flowComposer.numLines; - SelManager.splitParagraph(); - var endLines:int = SelManager.textFlow.flowComposer.numLines; - - assertTrue("expected one additional line after splitting the paragraph. Actually found " + - (endLines - initLines), initLines = endLines - 1); - - var lengthFirst:int = SelManager.textFlow.getFirstLeaf().textLength; - - assertTrue("expected the first paragraph would have " + insertPoint + - " characters. Actually found " + lengthFirst, lengthFirst = insertPoint); - } - - /** - * 1. Sets attributes before (A, B), after (B', C) and at (B'', D) at split point. - * Splits paragraphs, adds new text and verifies that it has attributes (A, B'', C, D) - * 2. Tests special case for splitting a paragraph at the end of a link; point format is reset in this case - */ - public function splitParagraphFormatTest():void - { - var insertPoint:int = 50; - - var attributes:TextLayoutFormat = new TextLayoutFormat(); - - attributes.fontWeight = FontWeight.BOLD; - attributes.lineThrough = true; - SelManager.selectRange(insertPoint-5, insertPoint); - SelManager.applyLeafFormat(attributes); - - attributes.fontWeight = undefined; - attributes.textDecoration = flashx.textLayout.formats.TextDecoration.UNDERLINE; - attributes.fontSize = 72; - SelManager.selectRange(insertPoint, insertPoint+5); - SelManager.applyLeafFormat(attributes); - - attributes.textDecoration = flashx.textLayout.formats.TextDecoration.UNDERLINE; - attributes.lineThrough = true; - attributes.fontFamily = "Verdana"; - SelManager.selectRange(insertPoint, insertPoint); - SelManager.applyLeafFormat(attributes); - - SelManager.splitParagraph(); - - SelManager.insertText("New"); - SelManager.flushPendingOperations(); - - var leaf:FlowLeafElement = SelManager.textFlow.findLeaf(insertPoint+1); - attributes = new TextLayoutFormat(leaf.format); - - assertTrue("Invalid point format for start of a new paragraph", attributes.fontWeight = FontWeight.BOLD); - assertTrue("Invalid point format for start of a new paragraph", attributes.fontSize = 72); - assertTrue("Invalid point format for start of a new paragraph", attributes.fontFamily = "Verdana"); - assertTrue("Invalid point format for start of a new paragraph", attributes.textDecoration == flashx.textLayout.formats.TextDecoration.UNDERLINE && attributes.lineThrough); - - insertPoint = 40; - - SelManager.selectRange(insertPoint-10, insertPoint); - SelManager.applyLink("http://www.google.com", "_self", false); - - SelManager.selectRange(insertPoint, insertPoint); - SelManager.splitParagraph(); - - SelManager.insertText("New"); - SelManager.flushPendingOperations(); - - leaf = SelManager.textFlow.findLeaf(insertPoint+1); - attributes = new TextLayoutFormat(leaf.format); - assertTrue("Invalid point format for start of a new paragraph after a link", TextLayoutFormat.isEqual(attributes, TextLayoutFormat.emptyTextLayoutFormat)); - } - - /** - * Selects the characters between the 10th and 50th characters and splits the paragraph. - * Verifies that there is one more line in the textFlow than it started with. - * Verifies that the first leaf has only 10 characters in it. - * Verifies that the final length has 39 less characters in it. - */ - public function splitParagraphSelectionTest():void - { - var startIndx:int = 10; - var endIndx:int = 50; - - - SelManager.selectRange(startIndx, endIndx); - - var initLength:int = SelManager.textFlow.textLength; - var initLines:int = SelManager.textFlow.flowComposer.numLines; - - SelManager.splitParagraph(); - - var endLength:int = SelManager.textFlow.textLength; - var endLines:int = SelManager.textFlow.flowComposer.numLines; - - assertTrue("expected one additional line after splitting the paragraph. Actually found " + - (endLines - initLines), initLines = endLines - 1); - - var lengthFirst:int = SelManager.textFlow.getFirstLeaf().textLength; - - assertTrue("expected the first paragraph would have " + startIndx + - " characters. Actually found " + lengthFirst, lengthFirst = startIndx); - assertTrue("expected the entire flow would have " + (initLength - (endIndx - startIndx) + 1) + - " characters. Actually found " + endLength, - endLength == initLength - (endIndx - startIndx) + 1); - } - - /** - * Creates a selection area of six characters at the last index of the flow root - * then inserts " BOOGA" into the selection area and verifies the length of the - * flow root has increased by 6. - */ - public function insertTextTest():void //KJT - { - var textLength:uint = SelManager.textFlow.textLength; - SelManager.selectRange(textLength - 1, textLength + 5); - - SelManager.insertText(" BOOGA"); - SelManager.selectRange(textLength - 1,textLength + 5); - - assertTrue("expected to find " + (textLength + 6) + " characters. Actually found " + - SelManager.textFlow.textLength, SelManager.textFlow.textLength == textLength + 6); - } - - /** - * Sets the insertion point at 50, then generates the "0" keyboard event - * and verifies that the selBegIdx is 49. - */ - public function arrowLeft():void - { - var event:KeyboardEvent = new KeyboardEvent(KeyboardEvent.KEY_UP, true, false, 0, Keyboard.LEFT); - SelManager.selectRange(50,50); - SelManager.keyDownHandler(event); - - if(SelManager.textFlow.computedFormat.blockProgression == BlockProgression.RL) - { -// assertTrue("expected insertion point at position 87. Actually found + " + -// SelManager.anchorPosition, SelManager.anchorPosition == 87); - } - else - { - if(SelManager.textFlow.computedFormat.direction == Direction.LTR) - { - assertTrue("expected insertion point at position 49. Actually found + " + - SelManager.activePosition, SelManager.activePosition == 49); - } - else - { - assertTrue("expected insertion point at position 51. Actually found + " + - SelManager.activePosition, SelManager.activePosition == 51); - } - } - } - - /** - * Sets the insertion point at 50, then generates the "0" keyboard event - * and verifies that the selBegIdx is 51. - */ - public function arrowRight():void - { - var event:KeyboardEvent = new KeyboardEvent(KeyboardEvent.KEY_UP, true, false, 0, Keyboard.RIGHT); - SelManager.selectRange(50,50); - SelManager.keyDownHandler(event); - if(SelManager.textFlow.computedFormat.blockProgression == BlockProgression.RL) - { -// assertTrue("expected insertion point at position 11. Actually found + " + -// SelManager.anchorPosition, SelManager.anchorPosition == 11); - } - else - { - if(SelManager.textFlow.computedFormat.direction == Direction.LTR) - { - assertTrue("expected insertion point at position 51. Actually found " + - SelManager.activePosition, SelManager.activePosition == 51); - } - else - { - assertTrue("expected insertion point at position 49. Actually found " + - SelManager.activePosition, SelManager.activePosition == 49); - } - } - } - - /** - * Sets the insertion point at 0, then generates the "40" keyboard event - * and verifies that the cursor is on the second line. - */ - public function arrowDown():void - { - var event:KeyboardEvent = new KeyboardEvent(KeyboardEvent.KEY_UP, true, false,40); - SelManager.selectRange(0,0); - SelManager.keyDownHandler(event); - if(SelManager.textFlow.computedFormat.blockProgression == BlockProgression.TB) - { - //NYI - } - else - { - var ap:int = SelManager.activePosition; - var index:int = SelManager.textFlow.findChildIndexAtPosition(ap); - assertTrue("expected index at 2. Actually found " + index, index == 2); - } - } - - /** - * Sets the insertion point at the last char, then generates the "38" keyboard event - * and verifies that the cursor is on the second to last line. - */ - public function arrowUp():void - { - var event:KeyboardEvent = new KeyboardEvent(KeyboardEvent.KEY_UP, true, false,38); - var lastChar:int = SelManager.absoluteEnd; - var lastLine:int = SelManager.textFlow.findChildIndexAtPosition(lastChar); - SelManager.selectRange(lastChar,lastChar); - SelManager.keyDownHandler(event); - if(SelManager.textFlow.computedFormat.blockProgression == BlockProgression.TB) - { - //NYI - } - else - { - var index:int = SelManager.textFlow.findChildIndexAtPosition(SelManager.activePosition); - assertTrue("expected index at " + (lastChar - 1) + - ". Actually found " + index, - index == (lastChar - 1) - ); - } - } - - /** - * Tests the undo and redo stacks by applying typeface changes by undoing - * and redoing them. - */ - public function unDoOp():void //KJT - { - var ca:TextLayoutFormat = new TextLayoutFormat(); - ca.fontWeight = FontWeight.BOLD; - SelManager.applyLeafFormat(ca); - - SelManager.undo(); - Redo(); - - ca.fontStyle = FontPosture.ITALIC; - SelManager.applyLeafFormat(ca); - - SelManager.undo(); - SelManager.undo(); - } - - /** - * Performs successive backspaces and one undo to see if all the deleted content - * is returned, then performs a redo to see if the content is correctly removed - * again. - */ - public function joinedBackspaceUndoTest():void - { - var n:int = 10; - SelManager.selectRange(10,10); - - var initLength:uint = SelManager.textFlow.textLength; - - for(var i:int = 0; i < n; i++){ - var event:KeyboardEvent = new KeyboardEvent(KeyboardEvent.KEY_DOWN, true, false, 8); - dispatchEvent(event); - } - - var endLength:uint = SelManager.textFlow.textLength; - - SelManager.undo(); - - var undoLength:uint = SelManager.textFlow.textLength; - - assertTrue("expected text length before undo to be " + n + " less. Was actually " + - (endLength - initLength) + " less.", endLength == initLength - n ); - assertTrue("expected text length after undo to be identical to the start, but it was off by " + - (undoLength-initLength), undoLength == initLength); - - Redo(); - - var redoLength:uint = SelManager.textFlow.textLength; - - assertTrue("expected redo length to equal undo length, but found " + - redoLength + " and " + endLength, redoLength == endLength); - } - - /** - * Performs successive deletes and one undo to see if all the deleted content - * is returned, then performs a redo to see if the content is correctly removed - * again. - */ - public function joinedDeleteUndoTest():void - { - var n:int = 10; - SelManager.selectRange(10,10); - - var initLength:uint = SelManager.textFlow.textLength; - - for(var i:int = 0; i < n; i++){ - var event:KeyboardEvent = new KeyboardEvent(KeyboardEvent.KEY_DOWN, true, false, 127, Keyboard.DELETE); - dispatchEvent(event); - } - SelManager.flushPendingOperations(); - - var endLength:uint = SelManager.textFlow.textLength; - - SelManager.undo(); - - var undoLength:uint = SelManager.textFlow.textLength; - - assertTrue("expected text length before undo to be " + n + " less. Was actually " + - (endLength - initLength) + " less.", endLength == initLength - n ); - assertTrue("expected text length after undo to be identical to the start, but it was off by " + - (undoLength-initLength), undoLength == initLength); - - Redo(); - - var redoLength:uint = SelManager.textFlow.textLength; - - assertTrue("expected redo length to equal undo length, but found " + - redoLength + " and " + endLength, redoLength == endLength); - } - - /** - * Places a series of letter a's in and does one undo to see if all the a's - * are removed, then performs a redo to see if they're returned. - */ - public function joinedInsertUndoTest():void - { - var n:int = 10; - SelManager.selectRange(10,10); - - var initLength:uint = SelManager.textFlow.textLength; - - for(var i:int = 0; i < n; i++){ - var event:TextEvent = new TextEvent(TextEvent.TEXT_INPUT,false,false,"a"); - dispatchEvent(event); - } - - SelManager.flushPendingOperations(); - - var endLength:uint = SelManager.textFlow.textLength; - - SelManager.undo(); - - var undoLength:uint = SelManager.textFlow.textLength; - - assertTrue("expected text length before undo to be " + n + " more. Was actually " + - (endLength - initLength) + " less.", endLength == initLength + n ); - assertTrue("expected text length after undo to be identical to the start, but it was off by " + - (undoLength-initLength), undoLength == initLength); - Redo(); - - var redoLength:uint = SelManager.textFlow.textLength; - - assertTrue("expected redo length to equal undo length, but found " + - redoLength + " and " + endLength, redoLength == endLength); - } - - /** - * Performs successive enters and one undo to see if all paragraph splits are - * undone, then performs a redo to see if they're all redone. - */ - public function joinedSplitParagraphUndoTest():void - { - var n:int = 10; - SelManager.selectRange(10,10); - - var initLength:uint = SelManager.textFlow.textLength; - - for(var i:int = 0; i < n; i++){ - var event:KeyboardEvent = new KeyboardEvent(KeyboardEvent.KEY_DOWN, true, false, 13); - dispatchEvent(event); - } - - var endLength:uint = SelManager.textFlow.textLength; - - SelManager.undo(); - - var undoLength:uint = SelManager.textFlow.textLength; - - assertTrue("expected text length before undo to be " + n + " more. Was actually " + - (endLength - initLength) + " less.", endLength == initLength + n ); - assertTrue("expected text length after undo to be identical to the start, but it was off by " + - (undoLength-initLength), undoLength == initLength); - - Redo(); - - var redoLength:uint = SelManager.textFlow.textLength; - - assertTrue("expected redo length to equal undo length, but found " + - redoLength + " and " + endLength, redoLength == endLength); - } - - /** - * Create a new undo manager with an undo limit of ten, then perform eleven - * undoable operations and see how many times it will let you undo. - */ - public function undoLimitTest():void - { - var undo:UndoManager = new UndoManager(); - var n:int = 10; - undo.undoAndRedoItemLimit = n; - - var newSM:EditManager = new EditManager(undo); - SelManager = newSM; - TestFrame.rootElement.getTextFlow().interactionManager = newSM; - - //SelManager.selectRange(n,n); - - for(var i:int = 0; i < n + 1; i++){ - SelManager.selectRange(n,n+i); - var event:KeyboardEvent = (i % 2 == 0) ? - new KeyboardEvent(KeyboardEvent.KEY_DOWN, true, false, 13): - new KeyboardEvent(KeyboardEvent.KEY_DOWN, true, false, 8); - dispatchEvent(event); - SelManager.selectRange(-1,-1); - } - - var u:int = 0; - while(undo.canUndo()){ - SelManager.undo(); - u++; - } - - assertTrue("expected only " + n + " undos but found " + u, u == n); - } - - - public function undoRedoStackTest():void - { - var undo:UndoManager = new UndoManager(); - var n:int = 10; - undo.undoAndRedoItemLimit = n; - - var newSM:EditManager = new EditManager(undo); - SelManager = newSM; - TestFrame.rootElement.getTextFlow().interactionManager = newSM; - - //do n operations - for(var i:int = 0; i < n + 1; i++){ - SelManager.selectRange(n,n+i); - var event:KeyboardEvent = (i % 2 == 0) ? - new KeyboardEvent(KeyboardEvent.KEY_DOWN, true, false, 13): - new KeyboardEvent(KeyboardEvent.KEY_DOWN, true, false, 8); - dispatchEvent(event); - SelManager.selectRange(-1,-1); - } - var testManager:TestEditManager = new TestEditManager(undo); - var stackItemNum:int = testManager.UndoRedoEntireStack(undo); - - assertTrue("expected only " + n + " undos but found " + stackItemNum, stackItemNum == n); - } - - /** - * Select a section of text that spans paragraphs then delete it and see if the - * size of the flow goes down by the appropriate amount. - */ - public function transParagraphDeleteTest():void - { - var startLength:int = TestFrame.rootElement.textLength; - - var flow1:FlowElement; - var flow2:FlowElement; - - var start:int = 0; - var finish:int = 0; - - var origParas:int = TestFrame.rootElement.numChildren; - - //Look for two back to back paragraphs. - for(var i:int = 0; i < TestFrame.rootElement.numChildren-1; i++){ - flow1 = TestFrame.rootElement.getChildAt(i); - flow2 = TestFrame.rootElement.getChildAt(i+1); - - if(flow1 is ParagraphElement && flow2 is ParagraphElement){ - finish = start + flow1.textLength + flow2.textLength/2; - start = start + flow1.textLength/2; - break; - }else{ - start = start + flow1.textLength; - } - } - - assertTrue("expected finish to be in the middle of the second para, but it's still 0", finish != 0); - - var para1:ParagraphElement = flow1 as ParagraphElement; - var para2:ParagraphElement = flow2 as ParagraphElement; - - var attrib1:ITextLayoutFormat = para1.computedFormat; - var pa:TextLayoutFormat = new TextLayoutFormat(); - if(attrib1.textAlign == TextAlign.CENTER) - pa.textAlign = TextAlign.LEFT; - else - pa.textAlign = TextAlign.CENTER; - - - SelManager.selectRange(para2.getAbsoluteStart(),para2.getAbsoluteStart() + 1); - - SelManager.applyParagraphFormat(pa); - - var attrib2:ITextLayoutFormat = para2.computedFormat; - assertTrue("para1 and para2 paraAttrs must be different for this test to work!", - !TextLayoutFormat.isEqual(attrib1,attrib2) - ); - - SelManager.selectRange(start,finish); - SelManager.deleteNextCharacter(); - var finishLength:int = TestFrame.rootElement.textLength; - - assertTrue("expected " + (finish-start) + " less characters but found " + - (startLength - finishLength) + " less", startLength - finishLength == finish - start); - - /* - * TODO: this tests current behavior. Proper behavior would be only one - * remaining paragraph. - */ - - assertTrue("number of paragraphs should have decreased!", origParas > TestFrame.rootElement.numChildren); - - var finalPara:ParagraphElement = TestFrame.rootElement.getChildAt(i) as ParagraphElement; - var finalAttrs:ITextLayoutFormat = finalPara.computedFormat; - - assertTrue("paragraph attributes changed and should be the same!",TextLayoutFormat.isEqual(attrib1,finalAttrs)); - } - - /** - * Create an empty paragraph and select the 0 position in it. - * Then delete all the content on the flow and see if the position selected is 0. - */ - public function emptyParagraphTest():void - { - SelManager.selectRange(0,0); - - var returnevent:KeyboardEvent = - new KeyboardEvent(KeyboardEvent.KEY_DOWN, true, false, 13); - dispatchEvent(returnevent); - - SelManager.selectRange(0,0); - assertTrue("did not start with selection at 0,0", SelManager.anchorPosition == 0 && SelManager.activePosition == 0); - SelManager.selectAll(); - SelManager.deleteNextCharacter(); - assertTrue("did not end with selection at 0,0 after delete all", SelManager.anchorPosition == 0 && SelManager.activePosition == 0); - } - - public function splitUTF16Test():void - { - // remove all text - SelManager.selectAll(); - SelManager.deleteNextCharacter(); - - var a:uint = 0xD866; var b:uint = 0xDDC1; - var c:uint = 0xD869; var d:uint = 0xDED6; - var e:uint = 0xD8BF; var f:uint = 0xDFFD; - - var y:String = String.fromCharCode(a,b,c,d,e,f); - SelManager.insertText(y); - SelManager.flushPendingOperations(); - - var begin:int = 0; - var end:int = SelManager.textFlow.textLength; - var middle:int = ((end-1) - begin)/2; - SelManager.selectRange(middle, middle); - - var gotRangeError:Boolean = false; - try - { - SelManager.splitParagraph(); - SelManager.flushPendingOperations(); - } - catch ( e:RangeError ) - { - gotRangeError = true; - } - /* See bug #1798067 */ - assertTrue( "Spliting a surrogate pair did not throw an error", gotRangeError ); - - SelManager.selectAll(); - - var charAttr:TextLayoutFormat = new TextLayoutFormat(); - charAttr.fontFamily = "Adobe Song Std L"; - - SelManager.applyLeafFormat(charAttr); - SelManager.flushPendingOperations(); - - //trace(begin + ", " + middle + ", " + end); - } - - public function splitUTF32Test():void - { - // remove all text - SelManager.selectAll(); - SelManager.deleteNextCharacter(); - - var y:String = String.fromCharCode(0x00028023); - y = y + y + y; - - SelManager.insertText(y); - SelManager.flushPendingOperations(); - - var begin:int = 0; - var end:int = SelManager.textFlow.textLength; - var middle:int = ((end-1) - begin)/2; - SelManager.selectRange(middle, middle); - - SelManager.splitParagraph(); - SelManager.flushPendingOperations(); - - SelManager.selectAll(); - - var charAttr:TextLayoutFormat = new TextLayoutFormat(); - charAttr.fontFamily = "Adobe Song Std L"; - - SelManager.applyLeafFormat(charAttr); - SelManager.flushPendingOperations(); - - //trace(begin + ", " + middle + ", " + end); - } - - - // pick up the actual operation - private var flowOp:FlowOperation; - - private function listenForOpBegin(opEvent:FlowOperationEvent):void - { - flowOp = opEvent.operation; - } - - /** - * Performs an operation, clear the selection manager and then make sure the operation doesn't undo - */ - public function undoWithModelChangeTest():void - { - var tf:TextFlow = SelManager.textFlow; - var selManager:EditManager = SelManager; - - selManager.selectAll(); - - var initLength:uint = SelManager.textFlow.textLength; - - - flowOp = null; - tf.addEventListener(FlowOperationEvent.FLOW_OPERATION_BEGIN,listenForOpBegin,false,0,true); - - // now do an operation - var ca:TextLayoutFormat = new TextLayoutFormat(); - ca.color = 0xff; - selManager.applyFormatToElement(tf, ca); - - assertTrue("no begin operation event",flowOp != null); - assertTrue("textFlow characterFormat.color should be 0xff",tf.format && tf.format.color == 0xff); - - // clear the selection manager - tf.interactionManager = null; - // now I've got a hold of the operation. do an out of bounds model modification and then attempt an undo - tf.color = 0xff00; - assertTrue("textFlow characterFormat.color should be 0xff",tf.format.color == 0xff00); - - // now restore the interactionManager - tf.interactionManager = selManager; - // CONFIG::debug { trace("GeneralFunctionsTest.undoWithModelChangeTest: expect to see message regarding skipping undo due to mismatched generation numbers."); } - // try to do an undo - selManager.undo(); - - // it should be skipped - assertTrue("no begin operation event",flowOp != null); - assertTrue("wrong begin operation event",flowOp is UndoOperation); - assertTrue("textFlow characterFormat.color should be 0xff00",tf.format && tf.format.color == 0xff00); - - selManager.selectRange(0,0); // prevent assert in tearDown - } - - private function Redo():void // KJT - { - try { - SelManager.redo(); - } - catch(e:Error){ - fail("Redo operation failed."); - } - } - - private function dispatchEvent(event:Event):void - { - // assume containers support dispatchEvent. Otherwise we get an error - TestFrame.container["dispatchEvent"](event); - } - - public function doubleClickTest():void - { - SelManager.selectRange( 68, 68 ); - var mEvent:MouseEvent = new MouseEvent( MouseEvent.DOUBLE_CLICK ); - TestFrame.container["dispatchEvent"](mEvent); - - assertTrue( "Double click failed to correctly select word", - SelManager.anchorPosition == 65 && - SelManager.activePosition == 72 ); - - SelManager.selectRange( 955, 955 ); - mEvent = new MouseEvent( MouseEvent.DOUBLE_CLICK ); - TestFrame.container["dispatchEvent"](mEvent); - - assertTrue( "Double click failed to correctly select word", - SelManager.anchorPosition == 954 && - SelManager.activePosition == 957 ); - } - - public function doubleClickHyphenTest():void - { - SelManager.selectRange( 24, 24 ); - var mEvent:MouseEvent = new MouseEvent( MouseEvent.DOUBLE_CLICK ); - TestFrame.container["dispatchEvent"](mEvent); - - assertTrue( "Double click failed on a hyphen", - SelManager.anchorPosition == 24 && - SelManager.activePosition == 25 ); - - SelManager.selectRange( 498, 498 ); - mEvent = new MouseEvent( MouseEvent.DOUBLE_CLICK ); - TestFrame.container["dispatchEvent"](mEvent); - - assertTrue( "Double click failed on a hyphenated word", - SelManager.anchorPosition == 496 && - SelManager.activePosition == 502 ); - } - - public function doubleClickPunctuationTest():void - { - SelManager.selectRange( 951, 951 ); - var mEvent:MouseEvent = new MouseEvent( MouseEvent.DOUBLE_CLICK ); - TestFrame.container["dispatchEvent"](mEvent); - - assertTrue( "Double click failed on a word next to punctuation", - SelManager.anchorPosition == 945 && - SelManager.activePosition == 952 ); - - SelManager.selectRange( 1964, 1964 ); - mEvent = new MouseEvent( MouseEvent.DOUBLE_CLICK ); - TestFrame.container["dispatchEvent"](mEvent); - - assertTrue( "Double click failed on punctuation", - SelManager.anchorPosition == 1963 && - SelManager.activePosition == 1966 ); - } - - public function replaceChildrenFlowTest():void - { - var caught:Boolean = false; - - try - { - SelManager.textFlow.replaceChildren( 0,0, new TextFlow() ); - } - catch ( err:ArgumentError ) - { - caught = true; - } - - assertTrue( "TextFlow.replaceChildren with a TextFlow argument should throw an error", caught ); - } - private function resolveInlines(ilg:InlineGraphicElement):Object - { - return ilg.source == "placeholder" ? new Sprite() : ilg.source; - } - - private var _ilgStatus:String; - private function graphicStatusChangeEvent(e:StatusChangeEvent):void - { - _ilgStatus = e.status; - } - - public function resolveInlinesTest():void - { - var textFlow:TextFlow; - const markup:String = "<flow:TextFlow xmlns:flow='http://ns.adobe.com/textLayout/2008'><flow:p><flow:img source='placeholder'/></flow:p></flow:TextFlow>"; - - var config:Configuration = new Configuration(); - config.inlineGraphicResolverFunction = resolveInlines; - textFlow = TextConverter.importToFlow(markup, TextConverter.TEXT_LAYOUT_FORMAT, config); - - textFlow.addEventListener(StatusChangeEvent.INLINE_GRAPHIC_STATUS_CHANGE,graphicStatusChangeEvent); - - textFlow.flowComposer.addController(new ContainerController(new Sprite(), 400, 200)); - textFlow.flowComposer.updateAllControllers(); - - assertTrue( "Inline Graphic resolution failed", _ilgStatus == InlineGraphicElementStatus.READY ); // - - } - - public function nestingTest():void - { - var link1:LinkElement = new LinkElement(); - var tcy1:TCYElement = new TCYElement(); - var link2:LinkElement = new LinkElement(); - - var exceptionThrown:Boolean = false; - try - { - link1.addChild(link2); - } - catch (e:*) - { - exceptionThrown = true; - } - assertTrue("Should not be able to add a link child to a link", exceptionThrown); - - exceptionThrown = false; - link1.addChild(tcy1); - - try - { - tcy1.addChild(link2); - } - catch (e:*) - { - exceptionThrown = true; - } - assertTrue("Should not be able to add a link child to a TCY if the latter is contained in a link", exceptionThrown); - - exceptionThrown = false; - link1.removeChild (tcy1); - tcy1.addChild(link2); - - try - { - link1.addChild(tcy1); - } - catch (e:*) - { - exceptionThrown = true; - } - assertTrue("Should not be able to add a TCY child to a link if the former contains a link", exceptionThrown); - - } - - private static const customResourceDict:Object = - { - invalidFlowElementConstruct_custom: "Attempted construct of invalid FlowElement subclass", - badMXMLChildrenArgument_custom: "Bad element of type {0} passed to mxmlChildren", - malformedTag: "Malformed tag </p/>", - XMLParserFailure: "TypeError: Error #1090: XML parser failure: element is malformed." - } - - tlf_internal static function customResourceStringFunction(resourceName:String, parameters:Array = null):String - { - var value:String = String(customResourceDict[resourceName]); - - if (value == null) - { - value = String(customResourceDict["missingStringResource"]); - parameters = [ resourceName ]; - } - - if (parameters) - value = customSubstitute(value, parameters); - - return value; - } - - /** @private */ - tlf_internal static function customSubstitute(str:String, ... rest):String - { - if (str == null) - return ''; - - // Replace all of the parameters in the msg string. - var len:uint = rest.length; - var args:Array; - if (len == 1 && rest[0] is Array) - { - args = rest[0] as Array; - len = args.length; - } - else - { - args = rest; - } - - for (var i:int = 0; i < len; i++) - { - str = str.replace(new RegExp("\\{"+i+"\\}", "g"), args[i]); - } - - return str; - } - - /** Generate errors and make sure we get the right string */ - public function errorThrowing():void - { - var exceptionThrown:Boolean; - - //use defaultResourceStringFunction to check the error message - // Invalid flowElement - exceptionThrown = false; - try - { - new FlowGroupElement(); - } - catch (e:Error) - { - exceptionThrown = true; - var invalidFlowElementConstruct_message:String = e.message; - assertTrue("errorThrowing: Error thrown but message is incorrect",e.message == GlobalSettings.resourceStringFunction("invalidFlowElementConstruct")); - - } - assertTrue("errorThrowing: Expected error on new FlowGroupElement did not occur", exceptionThrown); - - // invalid mxmlchildren assignment - exceptionThrown = false; - try - { - var s:Sprite = new Sprite(); - new DivElement().mxmlChildren = [ s ]; - } - catch (e:Error) - { - exceptionThrown = true; - var badMXMLChildrenArgument_message:String = e.message; - assertTrue("errorThrowing: Error thrown but message is incorrect",e.message == GlobalSettings.resourceStringFunction("badMXMLChildrenArgument",[ getQualifiedClassName(s) ])); - } - assertTrue("errorThrowing: Expected error on bad MXMLChildren argument did not occur", exceptionThrown); - - //use customResourceStringFunction to check the error message - try - { - GlobalSettings.resourceStringFunction= customResourceStringFunction; - - //check Invalid flowElement and invalid mxmlchildren assignment - assertTrue("errorThrowing: Error thrown but message is incorrect", GlobalSettings.resourceStringFunction("invalidFlowElementConstruct_custom") == invalidFlowElementConstruct_message); - assertTrue("errorThrowing: Error thrown but message is incorrect", GlobalSettings.resourceStringFunction("badMXMLChildrenArgument_custom",[ getQualifiedClassName(s) ]) == badMXMLChildrenArgument_message); - - //use custom resource string function to test HTML importer error - exceptionThrown = false; - var textImporter:ITextImporter = TextConverter.getImporter(TextConverter.TEXT_FIELD_HTML_FORMAT); - var textFlow:TextFlow; - - var markup:String = '<p>Malformed tag next</p/>'; - textFlow = textImporter.importToFlow(markup); - - if (textImporter.errors) - { - exceptionThrown = true; - assertTrue("errorThrowing: Error thrown but message is incorrect",textImporter.errors == GlobalSettings.resourceStringFunction("malformedTag")); - } - assertTrue("errorThrowing: Expected error on importer did not occur", exceptionThrown); - - //use custom resource string function to test Text importer error - exceptionThrown = false; - markup = "<TextFlow columnCount='inherit'" - + "<span>Ethan Brand</span></a></p></TextFlow>"; - - textImporter = TextConverter.getImporter(TextConverter.TEXT_LAYOUT_FORMAT); - textFlow = textImporter.importToFlow(markup); - - if (textImporter.errors) - { - exceptionThrown = true; - assertTrue("errorThrowing: Error thrown but message is incorrect",textImporter.errors == GlobalSettings.resourceStringFunction("XMLParserFailure")); - } - assertTrue("errorThrowing: Expected error on XML Parser Failure did not occur", exceptionThrown); - } - finally - { - GlobalSettings.resourceStringFunction = GlobalSettings.defaultResourceStringFunction; - } - - } - - public static const childParentTable:Array = - [ - [ "child\parent", TextFlow, DivElement, ParagraphElement, LinkElement, TCYElement, SpanElement, InlineGraphicElement, BreakElement, TabElement, ListElement, ListItemElement, SubParagraphGroupElement ], - [ TextFlow, "no", "no", "no", "no", "no", "no", "no", "no", "no", "no", "no", "no" ], - [ DivElement, "yes", "yes", "no", "no", "no", "no", "no", "no", "no", "yes", "yes", "no" ], - [ ParagraphElement, "yes", "yes", "no", "no", "no", "no", "no", "no", "no", "yes", "yes", "no" ], - [ LinkElement, "no", "no", "yes", "no", "yes", "no", "no", "no", "no", "no", "no", "yes" ], - [ TCYElement, "no", "no", "yes", "yes", "no", "no", "no", "no", "no", "no", "no", "yes" ], - [ SpanElement, "no", "no", "yes", "yes", "yes", "no", "no", "no", "no", "no", "no", "yes" ], - [ InlineGraphicElement, "no", "no", "yes", "yes", "yes", "no", "no", "no", "no", "no", "no", "yes" ], - [ BreakElement, "no", "no", "yes", "yes", "yes", "no", "no", "no", "no", "no", "no", "yes" ], - [ TabElement, "no", "no", "yes", "yes", "yes", "no", "no", "no", "no", "no", "no", "yes" ], - [ ListElement, "yes", "yes", "no", "no", "no", "no", "no", "no", "no", "yes", "yes", "no" ], - [ ListItemElement, "no", "no", "no", "no", "no", "no", "no", "no", "no", "yes", "no", "no" ], - [ SubParagraphGroupElement, "no", "no", "yes", "yes", "yes", "no", "no", "no", "no", "no", "no", "yes" ] - ]; - - /** Using above table for permitted child/parent relationships verify that canOwnFlowElement matches the table. */ - public function AllNestingTest():void - { - var parentRow:Array = childParentTable[0].slice(1); - var childRow:Array; - var childClassName:String; - var childClass:Class; - - for each (childRow in childParentTable.slice(1)) - { - childClassName = "flashx.textLayout.elements." + childRow[0]; - childClass = childRow[0] as Class; - var childElement:FlowElement = new childClass as FlowElement; - assertTrue(childElement.defaultTypeName != null,"Bad defaultTypeName in " + childClassName); - - childRow = childRow.slice(1); - for (var idx:int = 0; idx < childRow.length; idx++) - { - var parentClass:Class = parentRow[idx] as Class - var parentElement:FlowElement = new parentClass as FlowElement; - - // trace(parentClass.toString(),childClass.toString(),childRow[idx]); - - if (parentElement is FlowGroupElement) - { - if (FlowGroupElement(parentElement).canOwnFlowElement(childElement)) - assertTrue("Bad canOwnFlowElement value for expected allowed "+parentClass.toString()+" "+childClass.toString(),childRow[idx] == "yes"); - else - assertTrue("Bad canOwnFlowElement value for expected not allowed "+parentClass.toString()+" "+childClass.toString(), childRow[idx] == "no"); - } - else - assertTrue("Bad canOwnFlowElement value for a non FlowGroupElement parent "+parentClass.toString()+" "+childClass.toString(),childRow[idx] == "no"); - } - } - - // Check for indirect nesting of SubParagraphGroupElements - var textFlow:TextFlow = new TextFlow(); - var paragraph:ParagraphElement = new ParagraphElement(); - textFlow.replaceChildren(0, 0, paragraph); - var parentGroup:SubParagraphGroupElement = new SubParagraphGroupElement(); - paragraph.replaceChildren(0, 0, parentGroup); - for each (childRow in childParentTable.slice(1)) - { - childClassName = "flashx.textLayout.elements." + childRow[0]; - childClass = childRow[0] as Class; - var spgeChildElement:SubParagraphGroupElementBase = new childClass as SubParagraphGroupElementBase; - if (spgeChildElement) - { - var groupElement:SubParagraphGroupElement = new SubParagraphGroupElement(); - groupElement.replaceChildren(0, 0, new SubParagraphGroupElement()); - - groupElement.replaceChildren(0, 0, spgeChildElement); - - assertTrue (parentGroup.canOwnFlowElement(groupElement), "Expected this nesting to work"); - - if (!spgeChildElement.allowNesting) - { - var nestingParent:SubParagraphGroupElementBase = new childClass as SubParagraphGroupElementBase; - parentGroup.replaceChildren(parentGroup.numChildren, parentGroup.numChildren, nestingParent); - var nestingGroup:SubParagraphGroupElement = new SubParagraphGroupElement(); - nestingParent.replaceChildren(nestingParent.numChildren, nestingParent.numChildren, nestingGroup); - assertTrue("Expected this nesting to fail because of nesting of Link or TCY", !nestingGroup.canOwnFlowElement(groupElement)); - } - } - } - } - } + for (var i:int = 0; i < n; i++) + { + var event:TextEvent = new TextEvent(TextEvent.TEXT_INPUT, false, false, "a"); + dispatchEvent(event); + } + + SelManager.flushPendingOperations(); + + var endLength:uint = SelManager.textFlow.textLength; + + SelManager.undo(); + + var undoLength:uint = SelManager.textFlow.textLength; + + assertTrue("expected text length before undo to be " + n + " more. Was actually " + + (endLength - initLength) + " less.", endLength == initLength + n); + assertTrue("expected text length after undo to be identical to the start, but it was off by " + + (undoLength - initLength), undoLength == initLength); + Redo(); + + var redoLength:uint = SelManager.textFlow.textLength; + + assertTrue("expected redo length to equal undo length, but found " + + redoLength + " and " + endLength, redoLength == endLength); + } + + [Test] + /** + * Performs successive enters and one undo to see if all paragraph splits are + * undone, then performs a redo to see if they're all redone. + */ + public function joinedSplitParagraphUndoTest():void + { + var n:int = 10; + SelManager.selectRange(10, 10); + + var initLength:uint = SelManager.textFlow.textLength; + + for (var i:int = 0; i < n; i++) + { + var event:KeyboardEvent = new KeyboardEvent(KeyboardEvent.KEY_DOWN, true, false, 13); + dispatchEvent(event); + } + + var endLength:uint = SelManager.textFlow.textLength; + + SelManager.undo(); + + var undoLength:uint = SelManager.textFlow.textLength; + + assertTrue("expected text length before undo to be " + n + " more. Was actually " + + (endLength - initLength) + " less.", endLength == initLength + n); + assertTrue("expected text length after undo to be identical to the start, but it was off by " + + (undoLength - initLength), undoLength == initLength); + + Redo(); + + var redoLength:uint = SelManager.textFlow.textLength; + + assertTrue("expected redo length to equal undo length, but found " + + redoLength + " and " + endLength, redoLength == endLength); + } + + [Test] + /** + * Create a new undo manager with an undo limit of ten, then perform eleven + * undoable operations and see how many times it will let you undo. + */ + public function undoLimitTest():void + { + var undo:UndoManager = new UndoManager(); + var n:int = 10; + undo.undoAndRedoItemLimit = n; + + var newSM:EditManager = new EditManager(undo); + SelManager = newSM; + TestFrame.rootElement.getTextFlow().interactionManager = newSM; + + //SelManager.selectRange(n,n); + + for (var i:int = 0; i < n + 1; i++) + { + SelManager.selectRange(n, n + i); + var event:KeyboardEvent = (i % 2 == 0) ? + new KeyboardEvent(KeyboardEvent.KEY_DOWN, true, false, 13) : + new KeyboardEvent(KeyboardEvent.KEY_DOWN, true, false, 8); + dispatchEvent(event); + SelManager.selectRange(-1, -1); + } + + var u:int = 0; + while (undo.canUndo()) + { + SelManager.undo(); + u++; + } + + assertTrue("expected only " + n + " undos but found " + u, u == n); + } + + [Test] + public function undoRedoStackTest():void + { + var undo:UndoManager = new UndoManager(); + var n:int = 10; + undo.undoAndRedoItemLimit = n; + + var newSM:EditManager = new EditManager(undo); + SelManager = newSM; + TestFrame.rootElement.getTextFlow().interactionManager = newSM; + + //do n operations + for (var i:int = 0; i < n + 1; i++) + { + SelManager.selectRange(n, n + i); + var event:KeyboardEvent = (i % 2 == 0) ? + new KeyboardEvent(KeyboardEvent.KEY_DOWN, true, false, 13) : + new KeyboardEvent(KeyboardEvent.KEY_DOWN, true, false, 8); + dispatchEvent(event); + SelManager.selectRange(-1, -1); + } + var testManager:TestEditManager = new TestEditManager(undo); + var stackItemNum:int = testManager.UndoRedoEntireStack(undo); + + assertTrue("expected only " + n + " undos but found " + stackItemNum, stackItemNum == n); + } + + [Test] + /** + * Select a section of text that spans paragraphs then delete it and see if the + * size of the flow goes down by the appropriate amount. + */ + public function transParagraphDeleteTest():void + { + var startLength:int = TestFrame.rootElement.textLength; + + var flow1:FlowElement; + var flow2:FlowElement; + + var start:int = 0; + var finish:int = 0; + + var origParas:int = TestFrame.rootElement.numChildren; + + //Look for two back to back paragraphs. + for (var i:int = 0; i < TestFrame.rootElement.numChildren - 1; i++) + { + flow1 = TestFrame.rootElement.getChildAt(i); + flow2 = TestFrame.rootElement.getChildAt(i + 1); + + if (flow1 is ParagraphElement && flow2 is ParagraphElement) + { + finish = start + flow1.textLength + flow2.textLength / 2; + start = start + flow1.textLength / 2; + break; + } else + { + start = start + flow1.textLength; + } + } + + assertTrue("expected finish to be in the middle of the second para, but it's still 0", finish != 0); + + var para1:ParagraphElement = flow1 as ParagraphElement; + var para2:ParagraphElement = flow2 as ParagraphElement; + + var attrib1:ITextLayoutFormat = para1.computedFormat; + var pa:TextLayoutFormat = new TextLayoutFormat(); + if (attrib1.textAlign == TextAlign.CENTER) + pa.textAlign = TextAlign.LEFT; + else + pa.textAlign = TextAlign.CENTER; + + + SelManager.selectRange(para2.getAbsoluteStart(), para2.getAbsoluteStart() + 1); + + SelManager.applyParagraphFormat(pa); + + var attrib2:ITextLayoutFormat = para2.computedFormat; + assertTrue("para1 and para2 paraAttrs must be different for this test to work!", + !TextLayoutFormat.isEqual(attrib1, attrib2) + ); + + SelManager.selectRange(start, finish); + SelManager.deleteNextCharacter(); + var finishLength:int = TestFrame.rootElement.textLength; + + assertTrue("expected " + (finish - start) + " less characters but found " + + (startLength - finishLength) + " less", startLength - finishLength == finish - start); + + /* + * TODO: this tests current behavior. Proper behavior would be only one + * remaining paragraph. + */ + + assertTrue("number of paragraphs should have decreased!", origParas > TestFrame.rootElement.numChildren); + + var finalPara:ParagraphElement = TestFrame.rootElement.getChildAt(i) as ParagraphElement; + var finalAttrs:ITextLayoutFormat = finalPara.computedFormat; + + assertTrue("paragraph attributes changed and should be the same!", TextLayoutFormat.isEqual(attrib1, finalAttrs)); + } + + [Test] + /** + * Create an empty paragraph and select the 0 position in it. + * Then delete all the content on the flow and see if the position selected is 0. + */ + public function emptyParagraphTest():void + { + SelManager.selectRange(0, 0); + + var returnevent:KeyboardEvent = + new KeyboardEvent(KeyboardEvent.KEY_DOWN, true, false, 13); + dispatchEvent(returnevent); + + SelManager.selectRange(0, 0); + assertTrue("did not start with selection at 0,0", SelManager.anchorPosition == 0 && SelManager.activePosition == 0); + SelManager.selectAll(); + SelManager.deleteNextCharacter(); + assertTrue("did not end with selection at 0,0 after delete all", SelManager.anchorPosition == 0 && SelManager.activePosition == 0); + } + + [Test] + public function splitUTF16Test():void + { + // remove all text + SelManager.selectAll(); + SelManager.deleteNextCharacter(); + + var a:uint = 0xD866; + var b:uint = 0xDDC1; + var c:uint = 0xD869; + var d:uint = 0xDED6; + var e:uint = 0xD8BF; + var f:uint = 0xDFFD; + + var y:String = String.fromCharCode(a, b, c, d, e, f); + SelManager.insertText(y); + SelManager.flushPendingOperations(); + + var begin:int = 0; + var end:int = SelManager.textFlow.textLength; + var middle:int = ((end - 1) - begin) / 2; + SelManager.selectRange(middle, middle); + + var gotRangeError:Boolean = false; + try + { + SelManager.splitParagraph(); + SelManager.flushPendingOperations(); + } + catch (e:RangeError) + { + gotRangeError = true; + } + /* See bug #1798067 */ + assertTrue("Spliting a surrogate pair did not throw an error", gotRangeError); + + SelManager.selectAll(); + + var charAttr:TextLayoutFormat = new TextLayoutFormat(); + charAttr.fontFamily = "Adobe Song Std L"; + + SelManager.applyLeafFormat(charAttr); + SelManager.flushPendingOperations(); + + //trace(begin + ", " + middle + ", " + end); + } + + [Test] + public function splitUTF32Test():void + { + // remove all text + SelManager.selectAll(); + SelManager.deleteNextCharacter(); + + var y:String = String.fromCharCode(0x00028023); + y = y + y + y; + + SelManager.insertText(y); + SelManager.flushPendingOperations(); + + var begin:int = 0; + var end:int = SelManager.textFlow.textLength; + var middle:int = ((end - 1) - begin) / 2; + SelManager.selectRange(middle, middle); + + SelManager.splitParagraph(); + SelManager.flushPendingOperations(); + + SelManager.selectAll(); + + var charAttr:TextLayoutFormat = new TextLayoutFormat(); + charAttr.fontFamily = "Adobe Song Std L"; + + SelManager.applyLeafFormat(charAttr); + SelManager.flushPendingOperations(); + + //trace(begin + ", " + middle + ", " + end); + } + + [Test] + /** + * Performs an operation, clear the selection manager and then make sure the operation doesn't undo + */ + public function undoWithModelChangeTest():void + { + var tf:TextFlow = SelManager.textFlow; + var selManager:EditManager = SelManager; + + selManager.selectAll(); + + var initLength:uint = SelManager.textFlow.textLength; + + + flowOp = null; + tf.addEventListener(FlowOperationEvent.FLOW_OPERATION_BEGIN, listenForOpBegin, false, 0, true); + + // now do an operation + var ca:TextLayoutFormat = new TextLayoutFormat(); + ca.color = 0xff; + selManager.applyFormatToElement(tf, ca); + + assertTrue("no begin operation event", flowOp != null); + assertTrue("textFlow characterFormat.color should be 0xff", tf.format && tf.format.color == 0xff); + + // clear the selection manager + tf.interactionManager = null; + // now I've got a hold of the operation. do an out of bounds model modification and then attempt an undo + tf.color = 0xff00; + assertTrue("textFlow characterFormat.color should be 0xff", tf.format.color == 0xff00); + + // now restore the interactionManager + tf.interactionManager = selManager; + // CONFIG::debug { trace("GeneralFunctionsTest.undoWithModelChangeTest: expect to see message regarding skipping undo due to mismatched generation numbers."); } + // try to do an undo + selManager.undo(); + + // it should be skipped + assertTrue("no begin operation event", flowOp != null); + assertTrue("wrong begin operation event", flowOp is UndoOperation); + assertTrue("textFlow characterFormat.color should be 0xff00", tf.format && tf.format.color == 0xff00); + + selManager.selectRange(0, 0); // prevent assert in tearDown + } + + [Test] + public function doubleClickTest():void + { + SelManager.selectRange(68, 68); + var mEvent:MouseEvent = new MouseEve
<TRUNCATED>
