You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@flex.apache.org by pi...@apache.org on 2014/10/12 23:12:52 UTC
[1/2] Add FactoryImportTest.as and FlowModelTest.as
Repository: flex-tlf
Updated Branches:
refs/heads/FlexUnit4TestsTLF c10591211 -> 7961f3323
http://git-wip-us.apache.org/repos/asf/flex-tlf/blob/7961f332/automation_tests/src/UnitTest/Tests/FlowModelTest.as
----------------------------------------------------------------------
diff --git a/automation_tests/src/UnitTest/Tests/FlowModelTest.as b/automation_tests/src/UnitTest/Tests/FlowModelTest.as
index ea0d482..0af28df 100644
--- a/automation_tests/src/UnitTest/Tests/FlowModelTest.as
+++ b/automation_tests/src/UnitTest/Tests/FlowModelTest.as
@@ -18,967 +18,985 @@
////////////////////////////////////////////////////////////////////////////////
package UnitTest.Tests
{
- import UnitTest.ExtendedClasses.TestDescriptor;
- import UnitTest.ExtendedClasses.TestSuiteExtended;
- import UnitTest.ExtendedClasses.VellumTestCase;
- import UnitTest.Fixtures.TestConfig;
-
- import flash.display.Bitmap;
- import flash.display.BitmapData;
- import flash.display.DisplayObjectContainer;
- import flash.display.Sprite;
- import flash.geom.Rectangle;
- import flash.text.engine.FontDescription;
- import flash.text.engine.FontWeight;
- import flash.text.engine.TextLine;
- import flash.utils.ByteArray;
- import flash.utils.getTimer;
-
- import flashx.textLayout.compose.StandardFlowComposer;
- import flashx.textLayout.compose.TextFlowLine;
- import flashx.textLayout.container.ContainerController;
- import flashx.textLayout.edit.EditManager;
- import flashx.textLayout.edit.IEditManager;
- import flashx.textLayout.elements.Configuration;
- import flashx.textLayout.elements.DivElement;
- import flashx.textLayout.elements.FlowElement;
- import flashx.textLayout.elements.FlowLeafElement;
- import flashx.textLayout.elements.GlobalSettings;
- import flashx.textLayout.elements.InlineGraphicElement;
- import flashx.textLayout.elements.LinkElement;
- import flashx.textLayout.elements.ListElement;
- import flashx.textLayout.elements.ListItemElement;
- import flashx.textLayout.elements.ParagraphElement;
- import flashx.textLayout.elements.SpanElement;
- import flashx.textLayout.elements.TCYElement;
- import flashx.textLayout.elements.TextFlow;
- import flashx.textLayout.formats.BlockProgression;
- import flashx.textLayout.formats.Direction;
- import flashx.textLayout.formats.FormatValue;
- import flashx.textLayout.formats.ITextLayoutFormat;
- import flashx.textLayout.formats.ListStyleType;
- import flashx.textLayout.formats.TextAlign;
- import flashx.textLayout.formats.TextLayoutFormat;
- import flashx.textLayout.property.*;
- import flashx.textLayout.tlf_internal;
- import flashx.undo.IUndoManager;
- import flashx.undo.UndoManager;
-
- import mx.core.FTETextField;
- import mx.utils.LoaderUtil;
+ import UnitTest.ExtendedClasses.TestDescriptor;
+ import UnitTest.ExtendedClasses.TestSuiteExtended;
+ import UnitTest.ExtendedClasses.VellumTestCase;
+ import UnitTest.Fixtures.TestConfig;
+
+ import flash.display.Bitmap;
+ import flash.display.BitmapData;
+ import flash.display.DisplayObjectContainer;
+ import flash.display.Sprite;
+ import flash.geom.Rectangle;
+ import flash.text.engine.FontDescription;
+ import flash.text.engine.FontWeight;
+ import flash.text.engine.TextLine;
+ import flash.utils.ByteArray;
+ import flash.utils.getTimer;
+
+ import flashx.textLayout.compose.StandardFlowComposer;
+ import flashx.textLayout.compose.TextFlowLine;
+ import flashx.textLayout.container.ContainerController;
+ import flashx.textLayout.edit.EditManager;
+ import flashx.textLayout.edit.IEditManager;
+ import flashx.textLayout.elements.Configuration;
+ import flashx.textLayout.elements.DivElement;
+ import flashx.textLayout.elements.FlowElement;
+ import flashx.textLayout.elements.FlowLeafElement;
+ import flashx.textLayout.elements.GlobalSettings;
+ import flashx.textLayout.elements.InlineGraphicElement;
+ import flashx.textLayout.elements.LinkElement;
+ import flashx.textLayout.elements.ListElement;
+ import flashx.textLayout.elements.ListItemElement;
+ import flashx.textLayout.elements.ParagraphElement;
+ import flashx.textLayout.elements.SpanElement;
+ import flashx.textLayout.elements.TCYElement;
+ import flashx.textLayout.elements.TextFlow;
+ import flashx.textLayout.formats.BlockProgression;
+ import flashx.textLayout.formats.Direction;
+ import flashx.textLayout.formats.FormatValue;
+ import flashx.textLayout.formats.ITextLayoutFormat;
+ import flashx.textLayout.formats.ListStyleType;
+ import flashx.textLayout.formats.TextAlign;
+ import flashx.textLayout.formats.TextLayoutFormat;
+ import flashx.textLayout.property.*;
+ import flashx.textLayout.tlf_internal;
+ import flashx.undo.IUndoManager;
+ import flashx.undo.UndoManager;
+
+ import mx.core.FTETextField;
+ import mx.utils.LoaderUtil;
import org.flexunit.asserts.assertTrue;
use namespace tlf_internal;
- public class FlowModelTest extends VellumTestCase
- {
- public function FlowModelTest(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 = "Text Container";
- metaData.productSubArea = "Flow";
- }
-
- public static function suite(testConfig:TestConfig, ts:TestSuiteExtended):void
- {
- if (testConfig.writingDirection[0] == BlockProgression.TB && testConfig.writingDirection[1] == Direction.LTR)
- {
- ts.addTestDescriptor (new TestDescriptor (FlowModelTest, "basicAPITest1", testConfig ) );
- ts.addTestDescriptor (new TestDescriptor (FlowModelTest, "basicAPITest2", testConfig ) );
- ts.addTestDescriptor (new TestDescriptor (FlowModelTest, "basicAPITest3", testConfig ) );
- ts.addTestDescriptor (new TestDescriptor (FlowModelTest, "basicAPITest4", testConfig ) );
- ts.addTestDescriptor (new TestDescriptor (FlowModelTest, "basicAPITest5", testConfig ) );
- ts.addTestDescriptor (new TestDescriptor (FlowModelTest, "textFlowHostCharacterFormat", testConfig ) );
- ts.addTestDescriptor (new TestDescriptor (FlowModelTest, "iterateParagraphForward", testConfig ) );
- ts.addTestDescriptor (new TestDescriptor (FlowModelTest, "iterateParagraphBackward", testConfig ) );
- ts.addTestDescriptor (new TestDescriptor (FlowModelTest, "cascadeValidation", testConfig ) );
- ts.addTestDescriptor (new TestDescriptor (FlowModelTest, "elementMovingTest", testConfig ) );
- ts.addTestDescriptor (new TestDescriptor (FlowModelTest, "emptyTextFlowTests", testConfig ) );
- ts.addTestDescriptor (new TestDescriptor (FlowModelTest, "emptyElementCopyTests", testConfig ) );
- ts.addTestDescriptor (new TestDescriptor (FlowModelTest, "fontMappingTest", testConfig ) );
- ts.addTestDescriptor (new TestDescriptor (FlowModelTest, "insertLinkNoUpdateAPI", testConfig ) );
- ts.addTestDescriptor (new TestDescriptor (FlowModelTest, "insertLinkNoUpdateViaEditManager", testConfig ) );
- ts.addTestDescriptor (new TestDescriptor (FlowModelTest, "testUndo", testConfig ) );
- ts.addTestDescriptor (new TestDescriptor (FlowModelTest, "testFindControllerIndexAtPosition", testConfig ) );
- ts.addTestDescriptor (new TestDescriptor (FlowModelTest, "testFTETextField", testConfig ) );
-
- ts.addTestDescriptor (new TestDescriptor (FlowModelTest, "listItemInsertion", testConfig ) );
- ts.addTestDescriptor (new TestDescriptor (FlowModelTest, "replaceChildrenTest", testConfig ) );
- ts.addTestDescriptor (new TestDescriptor (FlowModelTest, "resolveFontLookupTest", testConfig ) );
- ts.addTestDescriptor (new TestDescriptor (FlowModelTest, "bindableSpan", testConfig ) );
- //ts.addTestDescriptor (new TestDescriptor (FlowModelTest, "softKeyboardFlagTest", testConfig ) );
- }
- }
-
- private var beginTime:int;
- private function beginAPITest():void
- {
- beginTime = getTimer();
- SelManager.selectRange(-1,-1);
- }
- private function endAPITest():void
- {
- SelManager.selectRange(0,0);
- SelManager.textFlow.flowComposer.updateAllControllers();
- }
-
- /**
- * Direct usage of the flow APIs. No validation - just look for crashes.
- * This test changes the color of the entire text.
- */
- public function basicAPITest1():void
- {
- // set the color on the entire flow
- beginAPITest();
- SelManager.textFlow.color = 0xff0000;
- endAPITest();
- }
-
- /**
- * Direct usage of the flow APIs. No validation - just look for crashes.
- * This test deletes every other character in the entire text.
- */
- public function basicAPITest2():void
- {
- // delete every other character in the textflow
- beginAPITest();
-
- var idx:int = 0;
- while (idx < SelManager.textFlow.textLength)
- {
- var span:SpanElement = SelManager.textFlow.findLeaf(idx) as SpanElement;
- if (span)
- {
- var spanStart:int = span.getAbsoluteStart();
- span.replaceText(idx-spanStart,idx-spanStart+1,null);
- }
- idx++;
-
- }
- endAPITest();
- }
-
- /**
- * Direct usage of the flow APIs. No validation - just look for crashes.
- * This test adds another paragraph to the flow containing the text "Hello World"
- * in 24 point font.
- */
- public function basicAPITest3():void
- {
- // add a paragraph
- beginAPITest();
- var p:ParagraphElement = new ParagraphElement();
- var s:SpanElement = new SpanElement();
- s.text = "Hello world";
- s.fontSize = 24;
- p.replaceChildren(0,0,s);
- SelManager.textFlow.replaceChildren(SelManager.textFlow.numChildren,SelManager.textFlow.numChildren,p);
- endAPITest();
- }
-
- /**
- * This test performs a series of changes and validates the changes after they're performed.
- */
- public function basicAPITest4():void
- {
- // more comprehensive set of tests - several manipulations to the flow and then display it
-
- // generic begin to an API test
- beginAPITest();
-
- // get the textflow
- var textFlow:TextFlow = SelManager.textFlow;
-
- // remove all the textflow children
- textFlow.replaceChildren(0,textFlow.numChildren);
- assertTrue("expected no elements on the flow, but found " + textFlow.numChildren,
- textFlow.numChildren == 0);
-
- // create a paragraph
- var p:ParagraphElement = new ParagraphElement();
-
- // create a span
- var s:SpanElement = new SpanElement();
- s.text = "Hello world. ";
- s.fontSize = 24;
-
- // split the span
- var nextSpan:SpanElement = s.splitAtPosition(6) as SpanElement;
- // set the color - color can be a string or an unsigned integer
- nextSpan.color = "0xff";
- assertTrue("expected that the color would be 255, but found " + uint(nextSpan.format.color),
- uint(nextSpan.format.color) == 255);
-
- // put the two spans in the paragraph
- p.replaceChildren(0,0,s);
- /*CONFIG::debug { assertTrue("debugCheckFlowElement() failed after adding one span",
- p.debugCheckFlowElement() == 0); } */
- p.replaceChildren(1,1,nextSpan);
- /*CONFIG::debug { assertTrue("debugCheckFlowElement() failed after adding second span",
- p.debugCheckFlowElement() == 0); } */
- assertTrue("expected the element count to be 2, but it was " + p.numChildren,
- p.numChildren == 2);
-
- // add another span
- s = new SpanElement();
- s.text = "Start:"
- p.replaceChildren(0,0,s);
- /* CONFIG::debug { assertTrue("debugCheckFlowElement() failed after adding third span",
- p.debugCheckFlowElement() == 0); } */
-
- // put the paragraph in the TextFlow
- textFlow.replaceChildren(0,0,p);
- assertTrue("text flow should have one element but has " + textFlow.numChildren,
- textFlow.numChildren == 1);
- /* CONFIG::debug { assertTrue("debugCheckFlowElement() failed after adding para to flow",
- textFlow.debugCheckFlowElement() == 0) } */
-
- // make another paragraph
- p = new ParagraphElement();
- s = new SpanElement();
- p.replaceChildren(0,0,s);
- s.text="NEW FIRST PARAGRAPH";
-
- // set the paragraph attributes directly
- p.textIndent = 20;
- // set the paragraph attributes via clone and set
- var pa:TextLayoutFormat = new TextLayoutFormat(p.format);
- pa.textAlign = TextAlign.RIGHT;
- p.format = pa;
-
- // into the textFlow at the beginning
- textFlow.replaceChildren(0,0,p);
- /*CONFIG::debug {assertTrue("debugCheckFlowElement() failed after adding para to beginning",
- textFlow.debugCheckFlowElement() == 0); } */
-
- // generic end to an API test
- endAPITest();
- }
-
- /**
- * This test inserts an FE in the middle of a paragraph
- */
- public function basicAPITest5():void
- {
- // more comprehensive set of tests - several manipulations to the flow and then display it
-
- // generic begin to an API test
- beginAPITest();
-
- // get the textflow
- var textFlow:TextFlow = SelManager.textFlow;
-
- // create a paragraph empty the flow and insert it
- var p:ParagraphElement = new ParagraphElement();
- textFlow.replaceChildren(0,textFlow.numChildren,p);
-
- // create a span
- var s:SpanElement = new SpanElement();
- s.text = "Hello world. ";
- s.fontSize = 24;
-
- // put it in the paragraph
- p.replaceChildren(0,0,s);
-
- // split the span
- var nextSpanElement:SpanElement = s.splitAtPosition(6) as SpanElement;
- assertTrue("Incorrect elementCount after split", p.numChildren == 2);
-
- // create and insert an image between the spans
- var image:InlineGraphicElement = new InlineGraphicElement();
- image.width = 19;
- image.height = 19;
- image.source = LoaderUtil.createAbsoluteURL(baseURL,"../../test/testFiles/assets/surprised.png");
- p.replaceChildren(1,1,image);
-
- assertTrue("failed length on new InlineGraphicElement", image.textLength == 1);
- assertTrue("failed elementCount after image insert", p.numChildren == 3);
- assertTrue("bad first child",p.getChildAt(0) is SpanElement);
- assertTrue("bad first child",p.getChildAt(1) is InlineGraphicElement);
- assertTrue("bad first child",p.getChildAt(2) is SpanElement);
-
- // set a userStyle on a ContainerController
- var saveFormat:ITextLayoutFormat = ContainerController.containerControllerInitialFormat;
- try
- {
- ContainerController.containerControllerInitialFormat = null;
- var controller:ContainerController = new ContainerController(new Sprite());
- controller.setStyle("foo","blah");
- }
- catch (e:Error)
- {
- ContainerController.containerControllerInitialFormat = saveFormat;
- throw(e);
- }
- ContainerController.containerControllerInitialFormat = saveFormat;
-
- // generic end to an API test
- endAPITest();
- }
-
- /** Test setting hostCharacterFormat on the TextFlow */
- public function textFlowHostCharacterFormat():void
- {
- // generic begin to an API test
- beginAPITest();
-
- // get the textflow
- var textFlow:TextFlow = SelManager.textFlow;
- var leaf:FlowLeafElement = textFlow.getFirstLeaf();
-
- // make it red
- var cf:TextLayoutFormat = new TextLayoutFormat();
- cf.color = 0xff0000;
- textFlow.hostFormat = cf;
- assertTrue("host character format set color failed",leaf.computedFormat.color == 0xff0000);
-
- // make it blue
- textFlow.color = 0xff;
- assertTrue("textFlow character format color override failed",leaf.computedFormat.color == 0xff);
-
- // clear the blue
- textFlow.color = undefined;
- assertTrue("textFlow color clear failed",leaf.computedFormat.color == 0xff0000);
-
- // clear the hostCharacterFormat
- textFlow.hostFormat = null;
- assertTrue("host character format clear failed",leaf.computedFormat.color == 0);
-
- endAPITest();
- }
-
- private function initTextFlowAAA():TextFlow
- {
- var textFlow:TextFlow = new TextFlow();
- var p:ParagraphElement = new ParagraphElement();
- var span:SpanElement = new SpanElement();
- span.text = "aaa";
- p.replaceChildren(0, 0, span);
- textFlow.replaceChildren(0, 0, p);
- return textFlow;
- }
-
- // Insert a link to a paragraph that hasn't ever been updated.
- public function insertLinkNoUpdateAPI():void
- {
- var textFlow:TextFlow = new TextFlow();
- var p:ParagraphElement = new ParagraphElement();
- var link:LinkElement = new LinkElement();
- link.href = "http://www.cnn.com";
- link.target = "_self";
- var span:SpanElement = new SpanElement();
- span.text = "aaa";
- link.replaceChildren(0, 0, span);
- p.replaceChildren(0, 0, link);
- textFlow.replaceChildren(0, 0, p);
- }
-
- // Insert a link to a paragraph that hasn't ever been updated.
- public function insertLinkNoUpdateViaEditManager():void
- {
- var textFlow:TextFlow = initTextFlowAAA();
- var editManager:IEditManager = new EditManager();
- textFlow.interactionManager = editManager;
-
- editManager.selectRange(1,2);
- editManager.applyLink("http://livedocs.adobe.com/", "_self", true);
- }
-
- // undo in a flow that has no controllers
- public function testUndo():void
- {
- var textFlow:TextFlow = initTextFlowAAA();
- var undoManager:IUndoManager = new UndoManager();
- var editManager:IEditManager = new EditManager(undoManager);
- textFlow.interactionManager = editManager;
-
- editManager.selectRange(1,2);
- var format:TextLayoutFormat = new TextLayoutFormat();
- format.fontWeight = FontWeight.BOLD;
- editManager.applyLeafFormat(format);
-
- undoManager.undo();
- }
-
- private function createParaIterationModel():TextFlow
- {
- // Creates 3 divs, each have 4 paras
- const paraTotal:int = 4;
- var paraCount:int;
- const divTotal:int = 3;
- var divCount:int;
-
- var flow:TextFlow = new TextFlow();
- for (var j:int = 0; j < divTotal; j++)
- {
- var div:DivElement = new DivElement();
- for (var i:int = 0; i < paraTotal; i++)
- {
- var para:ParagraphElement = new ParagraphElement();
- var span:SpanElement = new SpanElement();
- span.text = paraCount.toString();
- para.addChild(span);
- div.addChild(para);
- paraCount++;
- }
- flow.addChild(div);
- }
- return flow;
- }
-
- public function iterateParagraphForward():void
- {
- var flow:TextFlow = createParaIterationModel();
- var para:ParagraphElement = flow.getFirstLeaf().getParagraph();
- var i:int = 0;
- while (para != null)
- {
- var cStr:String = para.getText();
- assertTrue("Text not as expected", int(cStr) == i);
- para = para.getNextParagraph();
- i++;
- }
- assertTrue("Unexpected paragraph count", i == 12);
- }
-
- public function iterateParagraphBackward():void
- {
- //const kParaTerminator:String = '\u2029';
-
- var flow:TextFlow = createParaIterationModel();
- var para:ParagraphElement = flow.getLastLeaf().getParagraph();
- var i:int = 11;
- //These two tests are no longer valid due to PARB changes to removed the terminator
- //parameter from getText on a paragraph element.
- //
- //var terminatorTestStr:String = para.getText("\n");
- //assertTrue("Should have newline as terminator", terminatorTestStr.substr(terminatorTestStr.length - 1, 1) == '\n');
- //terminatorTestStr = para.getText();
- //assertTrue("Should have paragraph terminator as terminator", terminatorTestStr.substr(terminatorTestStr.length - 1, 1) == kParaTerminator);
- while (para != null)
- {
- var cStr:String = para.getText();
- assertTrue("Text not as expected", int(cStr) == i);
- para = para.getPreviousParagraph();
- i--;
- }
- assertTrue("Unexpected paragraph count", i == -1);
- }
- public function cascadeValidation():void
- {
- var flow:TextFlow = new TextFlow();
- var para:ParagraphElement = new ParagraphElement();
- var span:SpanElement = new SpanElement();
- flow.addChild(para);
- para.addChild(span);
- flow.backgroundColor = 0xff;
- assertTrue("backgroundColor should not inherit",TextLayoutFormat.backgroundColorProperty.inherited == false);
- assertTrue("bad flow backGroundColor", flow.computedFormat.backgroundColor == 0xff);
- assertTrue("bad para backGroundColor", para.computedFormat.backgroundColor == TextLayoutFormat.backgroundColorProperty.defaultValue);
- assertTrue("bad span backGroundColor", span.computedFormat.backgroundColor == TextLayoutFormat.backgroundColorProperty.defaultValue);
- }
-
- // tests api change to automatically remove a flowelements children when using replaceChildren
- public function elementMovingTest():void
- {
- var lengthBefore:int;
-
- // this flow should have two paragraphs as children
- var flow:TextFlow = SelManager.textFlow.deepCopy() as TextFlow; // clone the flow
-
- var firstPara:FlowElement = flow.getChildAt(0);
- lengthBefore = flow.textLength;
- //firstPara.parent.removeChild(firstPara); // soon to no longer be needed
- //assertTrue("elementMovingTest: removing para incorrect lengths",flow.textLength == lengthBefore-firstPara.textLength);
-
- lengthBefore = SelManager.textFlow.textLength;
- SelManager.textFlow.addChild(firstPara);
- assertTrue("elementMovingTest: adding para incorrect lengths",SelManager.textFlow.textLength == lengthBefore+firstPara.textLength);
-
- var lastLeaf:FlowElement = flow.getLastLeaf();
- var lastLeafLength:int = lastLeaf.textLength;
- //lastLeaf.parent.removeChild(lastLeaf); // soon to no longer be needed
- lengthBefore = SelManager.textFlow.textLength;
- SelManager.textFlow.getLastLeaf().parent.addChild(lastLeaf);
- assertTrue("elementMovingTest: adding span incorrect lengths",SelManager.textFlow.textLength == lengthBefore+lastLeafLength-1);
- }
-
- // Empty Flow Tests - verify that empty/partially empty TextFlow's are normalized correctly
- public function emptyTextFlowTests():void
- {
- var tf:TextFlow;
-
- // just an empty TextFlow
- tf = new TextFlow();
- tf.flowComposer.addController(new ContainerController(new Sprite()));
- tf.flowComposer.updateAllControllers();
-
- // empty TextFlow with paragraph
- tf = new TextFlow();
- tf.addChild(new ParagraphElement());
- tf.flowComposer.addController(new ContainerController(new Sprite()));
- tf.flowComposer.updateAllControllers();
-
- // empty TextFlow with paragraph and ILG
- tf = new TextFlow();
- var p:ParagraphElement = new ParagraphElement();
- p.addChild(new InlineGraphicElement());
- tf.addChild(p);
- tf.flowComposer.addController(new ContainerController(new Sprite()));
- tf.flowComposer.updateAllControllers();
-
- // empty TextFlow with paragraph and empty LinkElement
- tf = new TextFlow();
- p = new ParagraphElement();
- p.addChild(new LinkElement());
- tf.addChild(p);
- tf.flowComposer.addController(new ContainerController(new Sprite()));
- tf.flowComposer.updateAllControllers();
-
- // empty TextFlow with paragraph and empty TCYElement
- tf = new TextFlow();
- p = new ParagraphElement();
- p.addChild(new TCYElement());
- tf.addChild(p);
- tf.flowComposer.addController(new ContainerController(new Sprite()));
- tf.flowComposer.updateAllControllers();
-
- // a more complex example
- tf = new TextFlow();
- p = new ParagraphElement();
- var tcy:TCYElement = new TCYElement();
- tcy.addChild(new InlineGraphicElement());
- tcy.addChild(new SpanElement());
- p.addChild(tcy);
- tf.addChild(p);
- tcy.removeChildAt(1);
- tf.flowComposer.addController(new ContainerController(new Sprite()));
- tf.flowComposer.updateAllControllers();
-
- // several empty spans
- tf = new TextFlow();
- p = new ParagraphElement();
- tf.addChild(p);
- p.addChild(new SpanElement());
- p.addChild(new SpanElement());
- p.addChild(new SpanElement());
- tf.flowComposer.addController(new ContainerController(new Sprite()));
- tf.flowComposer.updateAllControllers();
- }
-
- public function emptyElementCopyTests():void
- {
- var elemList:Array = GeneralFunctionsTest.childParentTable[0];
- for (var idx:int = 1; idx < elemList.length; idx++)
- {
- var elem:FlowElement = new elemList[idx];
- elem.shallowCopy();
- elem.deepCopy();
- }
- }
-
- private function validateBitmap(actual:Bitmap, expected:Bitmap):Boolean
- {
- actual.bitmapData.draw(expected, null, null, "difference");
- var bounds:Rectangle = new Rectangle(0, 0, actual.width, actual.height);
- var diffPixels:ByteArray = actual.bitmapData.getPixels(bounds);
- diffPixels.position = 0;
- while (diffPixels.bytesAvailable > 0)
- {
- if (diffPixels.readByte() > 0)
- return false;
- }
-
- return true;
- }
-
- private function myFontMapper(fd:FontDescription):void
- {
- if (fd.fontName == "Arial Black")
- {
- fd.fontName = "Arial";
- fd.fontWeight = FontWeight.BOLD;
- }
- }
-
- /** Tests fontMapping */
- public function fontMappingTest():void
- {
- var textFlow:TextFlow = SelManager.textFlow;
- var container:DisplayObjectContainer = DisplayObjectContainer(textFlow.flowComposer.getControllerAt(0).container);
-
- textFlow.fontFamily = "Arial";
- textFlow.fontWeight = FontWeight.BOLD;
- textFlow.flowComposer.updateAllControllers();
-
- var arialBoldBits:BitmapData = new BitmapData(container.width,container.height);
- arialBoldBits.draw(container as DisplayObjectContainer);
- var arialBoldData:Bitmap = new Bitmap(arialBoldBits);
-
- textFlow.fontFamily = "Arial Black";
- textFlow.fontWeight = undefined;
- textFlow.flowComposer.updateAllControllers();
-
- var arialBlackBits:BitmapData = new BitmapData(container.width,container.height);
- arialBlackBits.draw(container as DisplayObjectContainer);
- var arialBlackData:Bitmap = new Bitmap(arialBlackBits);
-
- GlobalSettings.fontMapperFunction = myFontMapper;
- textFlow.invalidateAllFormats();
-
- try
- {
- textFlow.flowComposer.updateAllControllers();
- }
- finally
- {
- GlobalSettings.fontMapperFunction = null;
- textFlow.invalidateAllFormats();
- }
-
- var mappedBits:BitmapData = new BitmapData(container.width,container.height);
- mappedBits.draw(container as DisplayObjectContainer);
- var mappedData:Bitmap = new Bitmap(mappedBits);
-
- assertTrue("font mapping failed", validateBitmap(mappedData, arialBoldData));
-
- textFlow.flowComposer.updateAllControllers();
-
- var mappingClearedBits:BitmapData = new BitmapData(container.width,container.height);
- mappingClearedBits.draw(container as DisplayObjectContainer);
- var mappingClearedData:Bitmap = new Bitmap(mappingClearedBits);
-
- assertTrue("clearing font mapping failed", validateBitmap(mappingClearedData, arialBlackData));
-
- }
-
- /** test the binary search algorithm which in findControllerIndexAtPosition - tricky bits wrt handling of zero length containers */
- public function testFindControllerIndexAtPosition():void
- {
- var s:Sprite = new Sprite(); // scratch
- var controller:ContainerController; // scratch
- var composer:StandardFlowComposer = new StandardFlowComposer();
- // ideally shouldn't need TextFlow but because containercontrollers find their owning composer via the textflow its needed
- var textFlow:TextFlow = new TextFlow();
- textFlow.flowComposer = composer;
- textFlow.mxmlChildren = [ "012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678" ];
-
- controller = new ContainerController(s);
- controller.verticalScrollPolicy = "off";
- composer.addController(controller);
- controller.setTextLength(100);
- controller.verticalScrollPolicy = "off";
-
- assertTrue("Bad result in findControllerIndexAtPosition 9",composer.findControllerIndexAtPosition(0)== 0);
- assertTrue("Bad result in findControllerIndexAtPosition 10",composer.findControllerIndexAtPosition(100,true)== 0);
- assertTrue("Bad result in findControllerIndexAtPosition 11",composer.findControllerIndexAtPosition(100,false)== -1);
-
- for (var idx1:int = 0; idx1 < 4; idx1++)
- {
- for (var idx2:int = 0; idx2 < 4 ; idx2++)
- {
- var idx:int;
-
- composer = new StandardFlowComposer();
- textFlow = new TextFlow();
- textFlow.flowComposer = composer;
- textFlow.mxmlChildren = [ "012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678" ];
-
- // add some empties
- for (idx = 0; idx < idx1; idx++)
- composer.addController(new ContainerController(s));
- // add one of length one
- controller = new ContainerController(s);
- controller.verticalScrollPolicy = "off"; // scrolling confuses it
- composer.addController(controller);
- controller.setTextLength(100); // internal API
- // add some empties
- for (idx = 0; idx < idx2; idx++)
- composer.addController(new ContainerController(s));
- assertTrue("Bad result in findControllerIndexAtPosition 1",composer.findControllerIndexAtPosition(0)== 0);
- assertTrue("Bad result in findControllerIndexAtPosition 2",composer.findControllerIndexAtPosition(0,true)== 0);
- assertTrue("Bad result in findControllerIndexAtPosition 3",composer.findControllerIndexAtPosition(100,true)== idx1);
- assertTrue("Bad result in findControllerIndexAtPosition 4",composer.findControllerIndexAtPosition(100,false)== -1);
- // add one with some length
- textFlow.mxmlChildren = [ "0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678" ];
- controller.setTextLength(100);
- controller = new ContainerController(s);
- controller.verticalScrollPolicy = "off"; // scrolling confuses it
- composer.addController(controller);
- controller.setTextLength(100); // internal API
- assertTrue("Bad result in findControllerIndexAtPosition 5",composer.findControllerIndexAtPosition(100,true)== idx1);
- assertTrue("Bad result in findControllerIndexAtPosition 6",composer.findControllerIndexAtPosition(100,false)== idx1+1);
- assertTrue("Bad result in findControllerIndexAtPosition 7",composer.findControllerIndexAtPosition(200,true)== idx1+idx2+1);
- assertTrue("Bad result in findControllerIndexAtPosition 8",composer.findControllerIndexAtPosition(200,false)== -1);
- }
- }
-
- }
-
-
- private static function checkListLines(textFlow:TextFlow,numLines:int,prefix:String):void
- {
- for (var idx:int = 0; idx < numLines; idx++)
- {
- var tfl:TextFlowLine = textFlow.flowComposer.getLineAt(idx);
- assertTrue(prefix+": Missing TextFlowLine: "+idx,tfl != null);
- var textLine:TextLine = tfl.getTextLine();
- assertTrue(prefix+": Missing TextLine: "+idx,textLine != null);
- var numberLine:TextLine = textLine.getChildAt(0) as TextLine;
- assertTrue(prefix+": Missing NumberLine: "+idx,numberLine != null);
- /* var numberString:String = numberLine.userData as String;
- var expectedString:String = (idx+1).toString() + "."; // for numeric lists
- assertTrue(prefix+": NumberLine missing userData: "+idx,numberString != null);
- assertTrue(prefix+": Incorrect NumberLine userData: "+idx,numberLine.userData as String == expectedString);
- assertTrue(prefix+": Incorrect NumberLine rawTextLength: "+idx,numberString.length+1 == numberLine.rawTextLength); */
- }
- }
-
- public function listItemInsertion():void
- {
- // some validations that ensure ListElement is correctly setup for list processing
-
- // every ListStyleType must have an entry in ListElement.listSuffixes
- var handler:EnumPropertyHandler = TextLayoutFormat.listStyleTypeProperty.findHandler(EnumPropertyHandler) as EnumPropertyHandler;
- assertTrue("listItemInsertion: missing handler for ListStyleType", handler != null && handler.range != null);
-
- var range:Object = handler.range;
- var value:String;
-
- var numberedListStyles:Object = { };
- for (value in ListElement.algorithmicListStyles)
- {
- assertTrue("listItemInsertion: table entry duplicated",numberedListStyles[value] === undefined);
- numberedListStyles[value] = ListElement.algorithmicListStyles[value];
- }
- for (value in ListElement.numericListStyles)
- {
- assertTrue("listItemInsertion: table entry duplicated",numberedListStyles[value] === undefined);
- numberedListStyles[value] = ListElement.numericListStyles[value];
- }
- for (value in ListElement.alphabeticListStyles)
- {
- assertTrue("listItemInsertion: table entry duplicated",numberedListStyles[value] === undefined);
- numberedListStyles[value] = ListElement.alphabeticListStyles[value];
- }
-
- for (value in range)
- {
- if (value != FormatValue.INHERIT)
- {
- // must be a numbered list or an unnumbered list but not both
- assertTrue("listItemInsertion: listStyleType must be numbered or unnumbered but not both: "+value,
- numberedListStyles[value] !== undefined && ListElement.constantListStyles[value] === undefined
- || numberedListStyles[value] === undefined && ListElement.constantListStyles[value] !== undefined)
- // numbered lists must have a suffix
- if ( ListElement.constantListStyles[value] === undefined)
- assertTrue("listItemInsertion: missing suffix property: " + value,ListElement.listSuffixes[value] !== undefined);
- }
- }
-
- // verify that all constantListStyles are in range
- for (value in ListElement.constantListStyles)
- assertTrue("listItemInsertion: invalid value in constantListStyles: " + value, range[value] !== undefined);
- // verify that all numberedListStyles are in range
- for (value in numberedListStyles)
- assertTrue("listItemInsertion: invalid value in numberedListStyles: " + value, range[value] !== undefined);
- // verify that all listSuffixes are in range
- for (value in ListElement.listSuffixes)
- assertTrue("listItemInsertion: invalid value in listSuffixes: " + value, range[value] !== undefined);
-
- SelManager.selectRange(0,0);
-
- // remove all the children and put in a list
- var textFlow:TextFlow = SelManager.textFlow;
-
- textFlow.replaceChildren(0,textFlow.numChildren);
-
- var list:ListElement = new ListElement();
- list.listStyleType = ListStyleType.DECIMAL;
-
- textFlow.addChild(list);
- var item:ListItemElement = new ListItemElement();
- list.addChild(item);
-
- textFlow.flowComposer.updateAllControllers();
-
- assertTrue("listItemInsertion: incorrect normalize",textFlow.findAbsoluteParagraph(0).parent == item);
-
- // append two items and compose
- list.addChild(new ListItemElement());
- list.addChild(new ListItemElement());
- textFlow.flowComposer.updateAllControllers();
-
- // check the three textlines
- checkListLines(textFlow,3,"listItemInsertion1");
-
- // now insert a brand new ListItem at the head and verify
- list.replaceChildren(0,0,new ListItemElement());
- textFlow.flowComposer.updateAllControllers();
-
- // check four textlines
- checkListLines(textFlow,4,"listItemInsertion2");
-
- // remove a list item
- list.removeChildAt(1);
- textFlow.flowComposer.updateAllControllers();
-
- // check three textLines
- checkListLines(textFlow,3,"listItemInsertion3");
-
- // add another list in the first ListItemElement
- item = list.getChildAt(0) as ListItemElement;
- var newList:ListElement = new ListElement();
- item.addChild(newList);
- textFlow.flowComposer.updateAllControllers();
-
- // assert the empty list is deleted
- assertTrue("listItemInsertion: newList not normalized",newList.numChildren == 1);
-
- }
-
- public function testFTETextField():void
- {
- // use the TextFlow's container
- var fieldParent:Sprite = SelManager.textFlow.flowComposer.getControllerAt(0).container;
- // remove the controller so the the textFlow isn't displayed in it
- SelManager.textFlow.flowComposer.removeControllerAt(0);
-
- var field:FTETextField = new FTETextField();
- field.htmlText = "Hello world";
- fieldParent.addChild(field);
- }
-
- public function replaceChildrenTest():void
- {
- SelManager.selectRange(0,0);
-
- // remove all the children
- var textFlow:TextFlow = SelManager.textFlow;
- textFlow.replaceChildren(0,textFlow.numChildren);
-
- var p:ParagraphElement = new ParagraphElement();
- textFlow.addChild(p);
-
- var link:LinkElement = new LinkElement();
- link.href = "XXX";
- p.addChild(link);
- var span:SpanElement = new SpanElement();
- span.text = "Hello, ";
- span.fontSize = 24;
- link.addChild(span);
-
- var link2:LinkElement = new LinkElement();
- link2.href = "YYY";
- p.addChild(link2);
-
- var span2:SpanElement = new SpanElement();
- span2.text = "world ";
- span2.fontSize = 24;
- link2.addChild(span2);
-
- textFlow.flowComposer.updateAllControllers();
-
- link.replaceChildren(link2.numChildren,link2.numChildren,link2.mxmlChildren);
- p.removeChild(link2);
- textFlow.flowComposer.updateAllControllers();
-
- assertTrue("replaceChildrenTest: extra line - look for extra terminator",textFlow.flowComposer.numLines == 1);
- }
-
- private function myFontLookup(context:mySwfContext, tlf:ITextLayoutFormat):Function
- {
- return myFontLookup;
- }
-
- public function resolveFontLookupTest():void
- {
- var textFlow:TextFlow = SelManager.textFlow;
-
- textFlow.fontFamily = "Arial";
- textFlow.fontWeight = FontWeight.BOLD;
- textFlow.fontLookup = "device";
- textFlow.flowComposer.updateAllControllers();
-
- var swfContext:mySwfContext = new mySwfContext();
- try
- {
- GlobalSettings.resolveFontLookupFunction = myFontLookup(swfContext, textFlow.format);
- textFlow.flowComposer.updateAllControllers();
- assertTrue ("fontLookup not matched.", textFlow.fontLookup = swfContext.myFontlookup);
- }
- finally
- {
- GlobalSettings.resolveFontLookupFunction = null;
- }
- }
-
- public function bindableSpan():void
- {
- // Bindable span should not lose its formatting
- var textFlow:TextFlow = new TextFlow();
- var paragraph:ParagraphElement = new ParagraphElement();
- var span1:SpanElement = new SpanElement();
- var span2:SpanElement = new SpanElement();
- var format:TextLayoutFormat = new TextLayoutFormat();
- format.fontWeight = FontWeight.BOLD;
- span2.format = format;
- paragraph.mxmlChildren = [ span1, span2 ];
- textFlow.mxmlChildren = [ paragraph ];
- textFlow.flowComposer.addController(new ContainerController(new Sprite()));
- textFlow.flowComposer.compose(); // force normalize
- assertTrue("Spans should not be merged!", span2.parent == span1.parent && paragraph.numChildren == 2);
- assertTrue("Formatting on second span should be preserved!", span2.fontWeight == FontWeight.BOLD);
- }
-
- // This test does not work in our current build environment, since playerEnablesSpicyFeatures will always be false.
- // Once we have a method of compiling VellumUnit as a 10.2 swf, this test should be enabled.
- public function softKeyboardFlagTest():void
- {
- if (Configuration.playerEnablesSpicyFeatures) // only run the rest of the test if we're in 10.2 or higher
- {
- // test 1 - add controller, then interaction manager
- var sprite:Sprite = new Sprite();
- var textFlow:TextFlow = new TextFlow();
- textFlow.flowComposer.addController(new ContainerController(sprite));
- textFlow.interactionManager = new EditManager();
- assertTrue("needsSoftKeyboard should be true after adding EditManager", sprite["needsSoftKeyboard"] == true);
- // test 2 - add another controller
- var sprite1:Sprite = new Sprite();
- textFlow.flowComposer.addController(new ContainerController(sprite1));
- assertTrue("needsSoftKeyboard should be true for a second container", sprite1["needsSoftKeyboard"] == true);
-
- // test 3 - add interaction manager, then controller
- var sprite2:Sprite = new Sprite();
- var textFlow2:TextFlow = new TextFlow();
- textFlow2.interactionManager = new EditManager();
- textFlow2.flowComposer.addController(new ContainerController(sprite2));
- assertTrue("needsSoftKeyboard should be true after adding controller", sprite2["needsSoftKeyboard"] == true);
- }
- }
- }
+ public class FlowModelTest extends VellumTestCase
+ {
+ private var beginTime:int;
+
+ public function FlowModelTest()
+ {
+ super("", "FlowModelTest", TestConfig.getInstance());
+
+ metaData = {};
+ // Note: These must correspond to a Watson product area (case-sensitive)
+ metaData.productArea = "Text Container";
+ metaData.productSubArea = "Flow";
+ }
+
+ [Before]
+ override public function setUpTest():void
+ {
+ super.setUpTest();
+ }
+
+ [After]
+ override public function tearDownTest():void
+ {
+ super.tearDownTest();
+ }
+
+ [Test]
+ /**
+ * Direct usage of the flow APIs. No validation - just look for crashes.
+ * This test changes the color of the entire text.
+ */
+ public function basicAPITest1():void
+ {
+ // set the color on the entire flow
+ beginAPITest();
+ SelManager.textFlow.color = 0xff0000;
+ endAPITest();
+ }
+
+ [Test]
+ /**
+ * Direct usage of the flow APIs. No validation - just look for crashes.
+ * This test deletes every other character in the entire text.
+ */
+ public function basicAPITest2():void
+ {
+ // delete every other character in the textflow
+ beginAPITest();
+
+ var idx:int = 0;
+ while (idx < SelManager.textFlow.textLength)
+ {
+ var span:SpanElement = SelManager.textFlow.findLeaf(idx) as SpanElement;
+ if (span)
+ {
+ var spanStart:int = span.getAbsoluteStart();
+ span.replaceText(idx - spanStart, idx - spanStart + 1, null);
+ }
+ idx++;
+
+ }
+ endAPITest();
+ }
+
+ [Test]
+ /**
+ * Direct usage of the flow APIs. No validation - just look for crashes.
+ * This test adds another paragraph to the flow containing the text "Hello World"
+ * in 24 point font.
+ */
+ public function basicAPITest3():void
+ {
+ // add a paragraph
+ beginAPITest();
+ var p:ParagraphElement = new ParagraphElement();
+ var s:SpanElement = new SpanElement();
+ s.text = "Hello world";
+ s.fontSize = 24;
+ p.replaceChildren(0, 0, s);
+ SelManager.textFlow.replaceChildren(SelManager.textFlow.numChildren, SelManager.textFlow.numChildren, p);
+ endAPITest();
+ }
+
+ [Test]
+ /**
+ * This test performs a series of changes and validates the changes after they're performed.
+ */
+ public function basicAPITest4():void
+ {
+ // more comprehensive set of tests - several manipulations to the flow and then display it
+
+ // generic begin to an API test
+ beginAPITest();
+
+ // get the textflow
+ var textFlow:TextFlow = SelManager.textFlow;
+
+ // remove all the textflow children
+ textFlow.replaceChildren(0, textFlow.numChildren);
+ assertTrue("expected no elements on the flow, but found " + textFlow.numChildren,
+ textFlow.numChildren == 0);
+
+ // create a paragraph
+ var p:ParagraphElement = new ParagraphElement();
+
+ // create a span
+ var s:SpanElement = new SpanElement();
+ s.text = "Hello world. ";
+ s.fontSize = 24;
+
+ // split the span
+ var nextSpan:SpanElement = s.splitAtPosition(6) as SpanElement;
+ // set the color - color can be a string or an unsigned integer
+ nextSpan.color = "0xff";
+ assertTrue("expected that the color would be 255, but found " + uint(nextSpan.format.color),
+ uint(nextSpan.format.color) == 255);
+
+ // put the two spans in the paragraph
+ p.replaceChildren(0, 0, s);
+ p.replaceChildren(1, 1, nextSpan);
+
+ assertTrue("expected the element count to be 2, but it was " + p.numChildren,
+ p.numChildren == 2);
+
+ // add another span
+ s = new SpanElement();
+ s.text = "Start:"
+ p.replaceChildren(0, 0, s);
+
+ // put the paragraph in the TextFlow
+ textFlow.replaceChildren(0, 0, p);
+ assertTrue("text flow should have one element but has " + textFlow.numChildren,
+ textFlow.numChildren == 1);
+
+ // make another paragraph
+ p = new ParagraphElement();
+ s = new SpanElement();
+ p.replaceChildren(0, 0, s);
+ s.text = "NEW FIRST PARAGRAPH";
+
+ // set the paragraph attributes directly
+ p.textIndent = 20;
+ // set the paragraph attributes via clone and set
+ var pa:TextLayoutFormat = new TextLayoutFormat(p.format);
+ pa.textAlign = TextAlign.RIGHT;
+ p.format = pa;
+
+ // into the textFlow at the beginning
+ textFlow.replaceChildren(0, 0, p);
+
+ // generic end to an API test
+ endAPITest();
+ }
+
+ [Test]
+ /**
+ * This test inserts an FE in the middle of a paragraph
+ */
+ public function basicAPITest5():void
+ {
+ // more comprehensive set of tests - several manipulations to the flow and then display it
+
+ // generic begin to an API test
+ beginAPITest();
+
+ // get the textflow
+ var textFlow:TextFlow = SelManager.textFlow;
+
+ // create a paragraph empty the flow and insert it
+ var p:ParagraphElement = new ParagraphElement();
+ textFlow.replaceChildren(0, textFlow.numChildren, p);
+
+ // create a span
+ var s:SpanElement = new SpanElement();
+ s.text = "Hello world. ";
+ s.fontSize = 24;
+
+ // put it in the paragraph
+ p.replaceChildren(0, 0, s);
+
+ // split the span
+ var nextSpanElement:SpanElement = s.splitAtPosition(6) as SpanElement;
+ assertTrue("Incorrect elementCount after split", p.numChildren == 2);
+
+ // create and insert an image between the spans
+ var image:InlineGraphicElement = new InlineGraphicElement();
+ image.width = 19;
+ image.height = 19;
+ image.source = LoaderUtil.createAbsoluteURL(baseURL, "../../test/testFiles/assets/surprised.png");
+ p.replaceChildren(1, 1, image);
+
+ assertTrue("failed length on new InlineGraphicElement", image.textLength == 1);
+ assertTrue("failed elementCount after image insert", p.numChildren == 3);
+ assertTrue("bad first child", p.getChildAt(0) is SpanElement);
+ assertTrue("bad first child", p.getChildAt(1) is InlineGraphicElement);
+ assertTrue("bad first child", p.getChildAt(2) is SpanElement);
+
+ // set a userStyle on a ContainerController
+ var saveFormat:ITextLayoutFormat = ContainerController.containerControllerInitialFormat;
+ try
+ {
+ ContainerController.containerControllerInitialFormat = null;
+ var controller:ContainerController = new ContainerController(new Sprite());
+ controller.setStyle("foo", "blah");
+ }
+ catch (e:Error)
+ {
+ ContainerController.containerControllerInitialFormat = saveFormat;
+ throw(e);
+ }
+ ContainerController.containerControllerInitialFormat = saveFormat;
+
+ // generic end to an API test
+ endAPITest();
+ }
+
+ [Test]
+ /**
+ * Test setting hostCharacterFormat on the TextFlow
+ */
+ public function textFlowHostCharacterFormat():void
+ {
+ // generic begin to an API test
+ beginAPITest();
+
+ // get the textflow
+ var textFlow:TextFlow = SelManager.textFlow;
+ var leaf:FlowLeafElement = textFlow.getFirstLeaf();
+
+ // make it red
+ var cf:TextLayoutFormat = new TextLayoutFormat();
+ cf.color = 0xff0000;
+ textFlow.hostFormat = cf;
+ assertTrue("host character format set color failed", leaf.computedFormat.color == 0xff0000);
+
+ // make it blue
+ textFlow.color = 0xff;
+ assertTrue("textFlow character format color override failed", leaf.computedFormat.color == 0xff);
+
+ // clear the blue
+ textFlow.color = undefined;
+ assertTrue("textFlow color clear failed", leaf.computedFormat.color == 0xff0000);
+
+ // clear the hostCharacterFormat
+ textFlow.hostFormat = null;
+ assertTrue("host character format clear failed", leaf.computedFormat.color == 0);
+
+ endAPITest();
+ }
+
+ [Test]
+ /**
+ * Insert a link to a paragraph that hasn't ever been updated.
+ */
+ public function insertLinkNoUpdateAPI():void
+ {
+ var textFlow:TextFlow = new TextFlow();
+ var p:ParagraphElement = new ParagraphElement();
+ var link:LinkElement = new LinkElement();
+ link.href = "http://www.cnn.com";
+ link.target = "_self";
+ var span:SpanElement = new SpanElement();
+ span.text = "aaa";
+ link.replaceChildren(0, 0, span);
+ p.replaceChildren(0, 0, link);
+ textFlow.replaceChildren(0, 0, p);
+ }
+
+ [Test]
+ /**
+ *
+ */
+ public function insertLinkNoUpdateViaEditManager():void
+ {
+ var textFlow:TextFlow = initTextFlowAAA();
+ var editManager:IEditManager = new EditManager();
+ textFlow.interactionManager = editManager;
+
+ editManager.selectRange(1, 2);
+ editManager.applyLink("http://livedocs.adobe.com/", "_self", true);
+ }
+
+ [Test]
+ /**
+ * undo in a flow that has no controllers
+ */
+ public function testUndo():void
+ {
+ var textFlow:TextFlow = initTextFlowAAA();
+ var undoManager:IUndoManager = new UndoManager();
+ var editManager:IEditManager = new EditManager(undoManager);
+ textFlow.interactionManager = editManager;
+
+ editManager.selectRange(1, 2);
+ var format:TextLayoutFormat = new TextLayoutFormat();
+ format.fontWeight = FontWeight.BOLD;
+ editManager.applyLeafFormat(format);
+
+ undoManager.undo();
+ }
+
+ [Test]
+ public function iterateParagraphForward():void
+ {
+ var flow:TextFlow = createParaIterationModel();
+ var para:ParagraphElement = flow.getFirstLeaf().getParagraph();
+ var i:int = 0;
+ while (para != null)
+ {
+ var cStr:String = para.getText();
+ assertTrue("Text not as expected", int(cStr) == i);
+ para = para.getNextParagraph();
+ i++;
+ }
+ assertTrue("Unexpected paragraph count", i == 12);
+ }
+
+ [Test]
+ public function iterateParagraphBackward():void
+ {
+ //const kParaTerminator:String = '\u2029';
+
+ var flow:TextFlow = createParaIterationModel();
+ var para:ParagraphElement = flow.getLastLeaf().getParagraph();
+ var i:int = 11;
+ //These two tests are no longer valid due to PARB changes to removed the terminator
+ //parameter from getText on a paragraph element.
+ //
+ //var terminatorTestStr:String = para.getText("\n");
+ //assertTrue("Should have newline as terminator", terminatorTestStr.substr(terminatorTestStr.length - 1, 1) == '\n');
+ //terminatorTestStr = para.getText();
+ //assertTrue("Should have paragraph terminator as terminator", terminatorTestStr.substr(terminatorTestStr.length - 1, 1) == kParaTerminator);
+ while (para != null)
+ {
+ var cStr:String = para.getText();
+ assertTrue("Text not as expected", int(cStr) == i);
+ para = para.getPreviousParagraph();
+ i--;
+ }
+ assertTrue("Unexpected paragraph count", i == -1);
+ }
+
+ [Test]
+ public function cascadeValidation():void
+ {
+ var flow:TextFlow = new TextFlow();
+ var para:ParagraphElement = new ParagraphElement();
+ var span:SpanElement = new SpanElement();
+ flow.addChild(para);
+ para.addChild(span);
+ flow.backgroundColor = 0xff;
+ assertTrue("backgroundColor should not inherit", TextLayoutFormat.backgroundColorProperty.inherited == false);
+ assertTrue("bad flow backGroundColor", flow.computedFormat.backgroundColor == 0xff);
+ assertTrue("bad para backGroundColor", para.computedFormat.backgroundColor == TextLayoutFormat.backgroundColorProperty.defaultValue);
+ assertTrue("bad span backGroundColor", span.computedFormat.backgroundColor == TextLayoutFormat.backgroundColorProperty.defaultValue);
+ }
+
+ [Test]
+ /**
+ * tests api change to automatically remove a flowelements children when using replaceChildren
+ */
+ public function elementMovingTest():void
+ {
+ var lengthBefore:int;
+
+ // this flow should have two paragraphs as children
+ var flow:TextFlow = SelManager.textFlow.deepCopy() as TextFlow; // clone the flow
+
+ var firstPara:FlowElement = flow.getChildAt(0);
+ lengthBefore = flow.textLength;
+ //firstPara.parent.removeChild(firstPara); // soon to no longer be needed
+ //assertTrue("elementMovingTest: removing para incorrect lengths",flow.textLength == lengthBefore-firstPara.textLength);
+
+ lengthBefore = SelManager.textFlow.textLength;
+ SelManager.textFlow.addChild(firstPara);
+ assertTrue("elementMovingTest: adding para incorrect lengths", SelManager.textFlow.textLength == lengthBefore + firstPara.textLength);
+
+ var lastLeaf:FlowElement = flow.getLastLeaf();
+ var lastLeafLength:int = lastLeaf.textLength;
+ //lastLeaf.parent.removeChild(lastLeaf); // soon to no longer be needed
+ lengthBefore = SelManager.textFlow.textLength;
+ SelManager.textFlow.getLastLeaf().parent.addChild(lastLeaf);
+ assertTrue("elementMovingTest: adding span incorrect lengths", SelManager.textFlow.textLength == lengthBefore + lastLeafLength - 1);
+ }
+
+ [Test]
+ /**
+ * Empty Flow Tests - verify that empty/partially empty TextFlow's are normalized correctly
+ */
+ public function emptyTextFlowTests():void
+ {
+ var tf:TextFlow;
+
+ // just an empty TextFlow
+ tf = new TextFlow();
+ tf.flowComposer.addController(new ContainerController(new Sprite()));
+ tf.flowComposer.updateAllControllers();
+
+ // empty TextFlow with paragraph
+ tf = new TextFlow();
+ tf.addChild(new ParagraphElement());
+ tf.flowComposer.addController(new ContainerController(new Sprite()));
+ tf.flowComposer.updateAllControllers();
+
+ // empty TextFlow with paragraph and ILG
+ tf = new TextFlow();
+ var p:ParagraphElement = new ParagraphElement();
+ p.addChild(new InlineGraphicElement());
+ tf.addChild(p);
+ tf.flowComposer.addController(new ContainerController(new Sprite()));
+ tf.flowComposer.updateAllControllers();
+
+ // empty TextFlow with paragraph and empty LinkElement
+ tf = new TextFlow();
+ p = new ParagraphElement();
+ p.addChild(new LinkElement());
+ tf.addChild(p);
+ tf.flowComposer.addController(new ContainerController(new Sprite()));
+ tf.flowComposer.updateAllControllers();
+
+ // empty TextFlow with paragraph and empty TCYElement
+ tf = new TextFlow();
+ p = new ParagraphElement();
+ p.addChild(new TCYElement());
+ tf.addChild(p);
+ tf.flowComposer.addController(new ContainerController(new Sprite()));
+ tf.flowComposer.updateAllControllers();
+
+ // a more complex example
+ tf = new TextFlow();
+ p = new ParagraphElement();
+ var tcy:TCYElement = new TCYElement();
+ tcy.addChild(new InlineGraphicElement());
+ tcy.addChild(new SpanElement());
+ p.addChild(tcy);
+ tf.addChild(p);
+ tcy.removeChildAt(1);
+ tf.flowComposer.addController(new ContainerController(new Sprite()));
+ tf.flowComposer.updateAllControllers();
+
+ // several empty spans
+ tf = new TextFlow();
+ p = new ParagraphElement();
+ tf.addChild(p);
+ p.addChild(new SpanElement());
+ p.addChild(new SpanElement());
+ p.addChild(new SpanElement());
+ tf.flowComposer.addController(new ContainerController(new Sprite()));
+ tf.flowComposer.updateAllControllers();
+ }
+
+ [Test]
+ public function emptyElementCopyTests():void
+ {
+ var elemList:Array = GeneralFunctionsTest.childParentTable[0];
+ for (var idx:int = 1; idx < elemList.length; idx++)
+ {
+ var elem:FlowElement = new elemList[idx];
+ elem.shallowCopy();
+ elem.deepCopy();
+ }
+ }
+
+ [Test]
+ /**
+ * Tests fontMapping
+ */
+ public function fontMappingTest():void
+ {
+ var textFlow:TextFlow = SelManager.textFlow;
+ var container:DisplayObjectContainer = DisplayObjectContainer(textFlow.flowComposer.getControllerAt(0).container);
+
+ textFlow.fontFamily = "Arial";
+ textFlow.fontWeight = FontWeight.BOLD;
+ textFlow.flowComposer.updateAllControllers();
+
+ var arialBoldBits:BitmapData = new BitmapData(container.width, container.height);
+ arialBoldBits.draw(container as DisplayObjectContainer);
+ var arialBoldData:Bitmap = new Bitmap(arialBoldBits);
+
+ textFlow.fontFamily = "Arial Black";
+ textFlow.fontWeight = undefined;
+ textFlow.flowComposer.updateAllControllers();
+
+ var arialBlackBits:BitmapData = new BitmapData(container.width, container.height);
+ arialBlackBits.draw(container as DisplayObjectContainer);
+ var arialBlackData:Bitmap = new Bitmap(arialBlackBits);
+
+ GlobalSettings.fontMapperFunction = myFontMapper;
+ textFlow.invalidateAllFormats();
+
+ try
+ {
+ textFlow.flowComposer.updateAllControllers();
+ }
+ finally
+ {
+ GlobalSettings.fontMapperFunction = null;
+ textFlow.invalidateAllFormats();
+ }
+
+ var mappedBits:BitmapData = new BitmapData(container.width, container.height);
+ mappedBits.draw(container as DisplayObjectContainer);
+ var mappedData:Bitmap = new Bitmap(mappedBits);
+
+ assertTrue("font mapping failed", validateBitmap(mappedData, arialBoldData));
+
+ textFlow.flowComposer.updateAllControllers();
+
+ var mappingClearedBits:BitmapData = new BitmapData(container.width, container.height);
+ mappingClearedBits.draw(container as DisplayObjectContainer);
+ var mappingClearedData:Bitmap = new Bitmap(mappingClearedBits);
+
+ assertTrue("clearing font mapping failed", validateBitmap(mappingClearedData, arialBlackData));
+
+ }
+
+ [Test]
+ /**
+ * test the binary search algorithm which in findControllerIndexAtPosition - tricky bits wrt handling of zero length containers
+ */
+ public function testFindControllerIndexAtPosition():void
+ {
+ var s:Sprite = new Sprite(); // scratch
+ var controller:ContainerController; // scratch
+ var composer:StandardFlowComposer = new StandardFlowComposer();
+ // ideally shouldn't need TextFlow but because containercontrollers find their owning composer via the textflow its needed
+ var textFlow:TextFlow = new TextFlow();
+ textFlow.flowComposer = composer;
+ textFlow.mxmlChildren = [ "012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678" ];
+
+ controller = new ContainerController(s);
+ controller.verticalScrollPolicy = "off";
+ composer.addController(controller);
+ controller.setTextLength(100);
+ controller.verticalScrollPolicy = "off";
+
+ assertTrue("Bad result in findControllerIndexAtPosition 9", composer.findControllerIndexAtPosition(0) == 0);
+ assertTrue("Bad result in findControllerIndexAtPosition 10", composer.findControllerIndexAtPosition(100, true) == 0);
+ assertTrue("Bad result in findControllerIndexAtPosition 11", composer.findControllerIndexAtPosition(100, false) == -1);
+
+ for (var idx1:int = 0; idx1 < 4; idx1++)
+ {
+ for (var idx2:int = 0; idx2 < 4; idx2++)
+ {
+ var idx:int;
+
+ composer = new StandardFlowComposer();
+ textFlow = new TextFlow();
+ textFlow.flowComposer = composer;
+ textFlow.mxmlChildren = [ "012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678" ];
+
+ // add some empties
+ for (idx = 0; idx < idx1; idx++)
+ composer.addController(new ContainerController(s));
+ // add one of length one
+ controller = new ContainerController(s);
+ controller.verticalScrollPolicy = "off"; // scrolling confuses it
+ composer.addController(controller);
+ controller.setTextLength(100); // internal API
+ // add some empties
+ for (idx = 0; idx < idx2; idx++)
+ composer.addController(new ContainerController(s));
+ assertTrue("Bad result in findControllerIndexAtPosition 1", composer.findControllerIndexAtPosition(0) == 0);
+ assertTrue("Bad result in findControllerIndexAtPosition 2", composer.findControllerIndexAtPosition(0, true) == 0);
+ assertTrue("Bad result in findControllerIndexAtPosition 3", composer.findControllerIndexAtPosition(100, true) == idx1);
+ assertTrue("Bad result in findControllerIndexAtPosition 4", composer.findControllerIndexAtPosition(100, false) == -1);
+ // add one with some length
+ textFlow.mxmlChildren = [ "0123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678" ];
+ controller.setTextLength(100);
+ controller = new ContainerController(s);
+ controller.verticalScrollPolicy = "off"; // scrolling confuses it
+ composer.addController(controller);
+ controller.setTextLength(100); // internal API
+ assertTrue("Bad result in findControllerIndexAtPosition 5", composer.findControllerIndexAtPosition(100, true) == idx1);
+ assertTrue("Bad result in findControllerIndexAtPosition 6", composer.findControllerIndexAtPosition(100, false) == idx1 + 1);
+ assertTrue("Bad result in findControllerIndexAtPosition 7", composer.findControllerIndexAtPosition(200, true) == idx1 + idx2 + 1);
+ assertTrue("Bad result in findControllerIndexAtPosition 8", composer.findControllerIndexAtPosition(200, false) == -1);
+ }
+ }
+
+ }
+
+ [Test]
+ public function listItemInsertion():void
+ {
+ // some validations that ensure ListElement is correctly setup for list processing
+
+ // every ListStyleType must have an entry in ListElement.listSuffixes
+ var handler:EnumPropertyHandler = TextLayoutFormat.listStyleTypeProperty.findHandler(EnumPropertyHandler) as EnumPropertyHandler;
+ assertTrue("listItemInsertion: missing handler for ListStyleType", handler != null && handler.range != null);
+
+ var range:Object = handler.range;
+ var value:String;
+
+ var numberedListStyles:Object = { };
+ for (value in ListElement.algorithmicListStyles)
+ {
+ assertTrue("listItemInsertion: table entry duplicated", numberedListStyles[value] === undefined);
+ numberedListStyles[value] = ListElement.algorithmicListStyles[value];
+ }
+ for (value in ListElement.numericListStyles)
+ {
+ assertTrue("listItemInsertion: table entry duplicated", numberedListStyles[value] === undefined);
+ numberedListStyles[value] = ListElement.numericListStyles[value];
+ }
+ for (value in ListElement.alphabeticListStyles)
+ {
+ assertTrue("listItemInsertion: table entry duplicated", numberedListStyles[value] === undefined);
+ numberedListStyles[value] = ListElement.alphabeticListStyles[value];
+ }
+
+ for (value in range)
+ {
+ if (value != FormatValue.INHERIT)
+ {
+ // must be a numbered list or an unnumbered list but not both
+ assertTrue("listItemInsertion: listStyleType must be numbered or unnumbered but not both: " + value,
+ numberedListStyles[value] !== undefined && ListElement.constantListStyles[value] === undefined
+ || numberedListStyles[value] === undefined && ListElement.constantListStyles[value] !== undefined)
+ // numbered lists must have a suffix
+ if (ListElement.constantListStyles[value] === undefined)
+ assertTrue("listItemInsertion: missing suffix property: " + value, ListElement.listSuffixes[value] !== undefined);
+ }
+ }
+
+ // verify that all constantListStyles are in range
+ for (value in ListElement.constantListStyles)
+ assertTrue("listItemInsertion: invalid value in constantListStyles: " + value, range[value] !== undefined);
+ // verify that all numberedListStyles are in range
+ for (value in numberedListStyles)
+ assertTrue("listItemInsertion: invalid value in numberedListStyles: " + value, range[value] !== undefined);
+ // verify that all listSuffixes are in range
+ for (value in ListElement.listSuffixes)
+ assertTrue("listItemInsertion: invalid value in listSuffixes: " + value, range[value] !== undefined);
+
+ SelManager.selectRange(0, 0);
+
+ // remove all the children and put in a list
+ var textFlow:TextFlow = SelManager.textFlow;
+
+ textFlow.replaceChildren(0, textFlow.numChildren);
+
+ var list:ListElement = new ListElement();
+ list.listStyleType = ListStyleType.DECIMAL;
+
+ textFlow.addChild(list);
+ var item:ListItemElement = new ListItemElement();
+ list.addChild(item);
+
+ textFlow.flowComposer.updateAllControllers();
+
+ assertTrue("listItemInsertion: incorrect normalize", textFlow.findAbsoluteParagraph(0).parent == item);
+
+ // append two items and compose
+ list.addChild(new ListItemElement());
+ list.addChild(new ListItemElement());
+ textFlow.flowComposer.updateAllControllers();
+
+ // check the three textlines
+ checkListLines(textFlow, 3, "listItemInsertion1");
+
+ // now insert a brand new ListItem at the head and verify
+ list.replaceChildren(0, 0, new ListItemElement());
+ textFlow.flowComposer.updateAllControllers();
+
+ // check four textlines
+ checkListLines(textFlow, 4, "listItemInsertion2");
+
+ // remove a list item
+ list.removeChildAt(1);
+ textFlow.flowComposer.updateAllControllers();
+
+ // check three textLines
+ checkListLines(textFlow, 3, "listItemInsertion3");
+
+ // add another list in the first ListItemElement
+ item = list.getChildAt(0) as ListItemElement;
+ var newList:ListElement = new ListElement();
+ item.addChild(newList);
+ textFlow.flowComposer.updateAllControllers();
+
+ // assert the empty list is deleted
+ assertTrue("listItemInsertion: newList not normalized", newList.numChildren == 1);
+
+ }
+
+ [Test]
+ public function testFTETextField():void
+ {
+ // use the TextFlow's container
+ var fieldParent:Sprite = SelManager.textFlow.flowComposer.getControllerAt(0).container;
+ // remove the controller so the the textFlow isn't displayed in it
+ SelManager.textFlow.flowComposer.removeControllerAt(0);
+
+ var field:FTETextField = new FTETextField();
+ field.htmlText = "Hello world";
+ fieldParent.addChild(field);
+ }
+
+ [Test]
+ public function replaceChildrenTest():void
+ {
+ SelManager.selectRange(0, 0);
+
+ // remove all the children
+ var textFlow:TextFlow = SelManager.textFlow;
+ textFlow.replaceChildren(0, textFlow.numChildren);
+
+ var p:ParagraphElement = new ParagraphElement();
+ textFlow.addChild(p);
+
+ var link:LinkElement = new LinkElement();
+ link.href = "XXX";
+ p.addChild(link);
+ var span:SpanElement = new SpanElement();
+ span.text = "Hello, ";
+ span.fontSize = 24;
+ link.addChild(span);
+
+ var link2:LinkElement = new LinkElement();
+ link2.href = "YYY";
+ p.addChild(link2);
+
+ var span2:SpanElement = new SpanElement();
+ span2.text = "world ";
+ span2.fontSize = 24;
+ link2.addChild(span2);
+
+ textFlow.flowComposer.updateAllControllers();
+
+ link.replaceChildren(link2.numChildren, link2.numChildren, link2.mxmlChildren);
+ p.removeChild(link2);
+ textFlow.flowComposer.updateAllControllers();
+
+ assertTrue("replaceChildrenTest: extra line - look for extra terminator", textFlow.flowComposer.numLines == 1);
+ }
+
+ [Test]
+ public function resolveFontLookupTest():void
+ {
+ var textFlow:TextFlow = SelManager.textFlow;
+
+ textFlow.fontFamily = "Arial";
+ textFlow.fontWeight = FontWeight.BOLD;
+ textFlow.fontLookup = "device";
+ textFlow.flowComposer.updateAllControllers();
+
+ var swfContext:mySwfContext = new mySwfContext();
+ try
+ {
+ GlobalSettings.resolveFontLookupFunction = myFontLookup(swfContext, textFlow.format);
+ textFlow.flowComposer.updateAllControllers();
+ assertTrue("fontLookup not matched.", textFlow.fontLookup = swfContext.myFontlookup);
+ }
+ finally
+ {
+ GlobalSettings.resolveFontLookupFunction = null;
+ }
+ }
+
+ [Test]
+ public function bindableSpan():void
+ {
+ // Bindable span should not lose its formatting
+ var textFlow:TextFlow = new TextFlow();
+ var paragraph:ParagraphElement = new ParagraphElement();
+ var span1:SpanElement = new SpanElement();
+ var span2:SpanElement = new SpanElement();
+ var format:TextLayoutFormat = new TextLayoutFormat();
+ format.fontWeight = FontWeight.BOLD;
+ span2.format = format;
+ paragraph.mxmlChildren = [ span1, span2 ];
+ textFlow.mxmlChildren = [ paragraph ];
+ textFlow.flowComposer.addController(new ContainerController(new Sprite()));
+ textFlow.flowComposer.compose(); // force normalize
+ assertTrue("Spans should not be merged!", span2.parent == span1.parent && paragraph.numChildren == 2);
+ assertTrue("Formatting on second span should be preserved!", span2.fontWeight == FontWeight.BOLD);
+ }
+
+ [Test]
+ /**
+ * This test does not work in our current build environment, since playerEnablesSpicyFeatures will always be false.
+ * Once we have a method of compiling VellumUnit as a 10.2 swf, this test should be enabled.
+ */
+ public function softKeyboardFlagTest():void
+ {
+ if (Configuration.playerEnablesSpicyFeatures) // only run the rest of the test if we're in 10.2 or higher
+ {
+ // test 1 - add controller, then interaction manager
+ var sprite:Sprite = new Sprite();
+ var textFlow:TextFlow = new TextFlow();
+ textFlow.flowComposer.addController(new ContainerController(sprite));
+ textFlow.interactionManager = new EditManager();
+ assertTrue("needsSoftKeyboard should be true after adding EditManager", sprite["needsSoftKeyboard"] == true);
+ // test 2 - add another controller
+ var sprite1:Sprite = new Sprite();
+ textFlow.flowComposer.addController(new ContainerController(sprite1));
+ assertTrue("needsSoftKeyboard should be true for a second container", sprite1["needsSoftKeyboard"] == true);
+
+ // test 3 - add interaction manager, then controller
+ var sprite2:Sprite = new Sprite();
+ var textFlow2:TextFlow = new TextFlow();
+ textFlow2.interactionManager = new EditManager();
+ textFlow2.flowComposer.addController(new ContainerController(sprite2));
+ assertTrue("needsSoftKeyboard should be true after adding controller", sprite2["needsSoftKeyboard"] == true);
+ }
+ }
+
+
+ private function beginAPITest():void
+ {
+ beginTime = getTimer();
+ SelManager.selectRange(-1, -1);
+ }
+
+ private function endAPITest():void
+ {
+ SelManager.selectRange(0, 0);
+ SelManager.textFlow.flowComposer.updateAllControllers();
+ }
+
+ private function initTextFlowAAA():TextFlow
+ {
+ var textFlow:TextFlow = new TextFlow();
+ var p:ParagraphElement = new ParagraphElement();
+ var span:SpanElement = new SpanElement();
+ span.text = "aaa";
+ p.replaceChildren(0, 0, span);
+ textFlow.replaceChildren(0, 0, p);
+ return textFlow;
+ }
+
+ private function createParaIterationModel():TextFlow
+ {
+ // Creates 3 divs, each have 4 paras
+ const paraTotal:int = 4;
+ var paraCount:int;
+ const divTotal:int = 3;
+ var divCount:int;
+
+ var flow:TextFlow = new TextFlow();
+ for (var j:int = 0; j < divTotal; j++)
+ {
+ var div:DivElement = new DivElement();
+ for (var i:int = 0; i < paraTotal; i++)
+ {
+ var para:ParagraphElement = new ParagraphElement();
+ var span:SpanElement = new SpanElement();
+ span.text = paraCount.toString();
+ para.addChild(span);
+ div.addChild(para);
+ paraCount++;
+ }
+ flow.addChild(div);
+ }
+ return flow;
+ }
+
+ private function myFontLookup(context:mySwfContext, tlf:ITextLayoutFormat):Function
+ {
+ return myFontLookup;
+ }
+
+
+ private static function checkListLines(textFlow:TextFlow, numLines:int, prefix:String):void
+ {
+ for (var idx:int = 0; idx < numLines; idx++)
+ {
+ var tfl:TextFlowLine = textFlow.flowComposer.getLineAt(idx);
+ assertTrue(prefix + ": Missing TextFlowLine: " + idx, tfl != null);
+ var textLine:TextLine = tfl.getTextLine();
+ assertTrue(prefix + ": Missing TextLine: " + idx, textLine != null);
+ var numberLine:TextLine = textLine.getChildAt(0) as TextLine;
+ assertTrue(prefix + ": Missing NumberLine: " + idx, numberLine != null);
+ /* var numberString:String = numberLine.userData as String;
+ var expectedString:String = (idx+1).toString() + "."; // for numeric lists
+ assertTrue(prefix+": NumberLine missing userData: "+idx,numberString != null);
+ assertTrue(prefix+": Incorrect NumberLine userData: "+idx,numberLine.userData as String == expectedString);
+ assertTrue(prefix+": Incorrect NumberLine rawTextLength: "+idx,numberString.length+1 == numberLine.rawTextLength); */
+ }
+ }
+
+
+ private function validateBitmap(actual:Bitmap, expected:Bitmap):Boolean
+ {
+ actual.bitmapData.draw(expected, null, null, "difference");
+ var bounds:Rectangle = new Rectangle(0, 0, actual.width, actual.height);
+ var diffPixels:ByteArray = actual.bitmapData.getPixels(bounds);
+ diffPixels.position = 0;
+ while (diffPixels.bytesAvailable > 0)
+ {
+ if (diffPixels.readByte() > 0)
+ return false;
+ }
+
+ return true;
+ }
+
+ private function myFontMapper(fd:FontDescription):void
+ {
+ if (fd.fontName == "Arial Black")
+ {
+ fd.fontName = "Arial";
+ fd.fontWeight = FontWeight.BOLD;
+ }
+ }
+ }
}
import flash.text.engine.FontLookup;
+
import flashx.textLayout.compose.ISWFContext;
-import flashx.textLayout.elements.FlowElement;
import flashx.textLayout.elements.TextFlow;
-import flashx.textLayout.formats.TextLayoutFormat;
class mySwfContext implements ISWFContext
-{
- public var myFontlookup:String = FontLookup.EMBEDDED_CFF;
-
- public function callInContext(fn:Function, thisArg:Object, argsArray:Array, returns:Boolean=true):*
- {
- var tf:TextFlow = thisArg as TextFlow;
- tf.fontLookup = FontLookup.EMBEDDED_CFF;
- if (returns)
- return fn.apply(thisArg, argsArray);
- fn.apply(thisArg, argsArray);
- }
-
+{
+ public var myFontlookup:String = FontLookup.EMBEDDED_CFF;
+
+ public function callInContext(fn:Function, thisArg:Object, argsArray:Array, returns:Boolean = true):*
+ {
+ var tf:TextFlow = thisArg as TextFlow;
+ tf.fontLookup = FontLookup.EMBEDDED_CFF;
+ if (returns)
+ return fn.apply(thisArg, argsArray);
+ fn.apply(thisArg, argsArray);
+ }
+
}
[2/2] git commit: [flex-tlf] [refs/heads/FlexUnit4TestsTLF] - Add
FactoryImportTest.as and FlowModelTest.as
Posted by pi...@apache.org.
Add FactoryImportTest.as and FlowModelTest.as
Project: http://git-wip-us.apache.org/repos/asf/flex-tlf/repo
Commit: http://git-wip-us.apache.org/repos/asf/flex-tlf/commit/7961f332
Tree: http://git-wip-us.apache.org/repos/asf/flex-tlf/tree/7961f332
Diff: http://git-wip-us.apache.org/repos/asf/flex-tlf/diff/7961f332
Branch: refs/heads/FlexUnit4TestsTLF
Commit: 7961f3323e965e10bbff8947affddab8936c5f95
Parents: c105912
Author: piotrz <pi...@gmail.com>
Authored: Sun Oct 12 23:12:35 2014 +0200
Committer: piotrz <pi...@gmail.com>
Committed: Sun Oct 12 23:12:35 2014 +0200
----------------------------------------------------------------------
automation_tests/src/AllTestsSuite.as | 4 +
automation_tests/src/MinimalTestsSuite.as | 4 +-
.../src/UnitTest/Tests/FactoryImportTest.as | 250 +--
.../src/UnitTest/Tests/FloatTest.as | 84 -
.../src/UnitTest/Tests/FlowModelTest.as | 1920 +++++++++---------
5 files changed, 1101 insertions(+), 1161 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/flex-tlf/blob/7961f332/automation_tests/src/AllTestsSuite.as
----------------------------------------------------------------------
diff --git a/automation_tests/src/AllTestsSuite.as b/automation_tests/src/AllTestsSuite.as
index a13ac01..f6f8045 100644
--- a/automation_tests/src/AllTestsSuite.as
+++ b/automation_tests/src/AllTestsSuite.as
@@ -33,7 +33,9 @@ package
import UnitTest.Tests.CrossContainerTest;
import UnitTest.Tests.ElementOperationTest;
import UnitTest.Tests.EventOverrideTest;
+ import UnitTest.Tests.FactoryImportTest;
import UnitTest.Tests.FloatTest;
+ import UnitTest.Tests.FlowModelTest;
import UnitTest.Tests.OperationTest;
import UnitTest.Tests.ScrollingTest;
@@ -41,6 +43,7 @@ package
[RunWith("org.flexunit.runners.Suite")]
public dynamic class AllTestsSuite
{
+ public var factoryImportTest:FactoryImportTest;
public var accessibilityMethodsTest:AccessibilityMethodsTest;
public var allChartAttributeTest:AllCharAttributeTest;
public var allContAttirbuteTest:AllContAttributeTest;
@@ -58,6 +61,7 @@ package
public var crossContainerTest:CrossContainerTest;
public var elementOperationTest:ElementOperationTest;
public var eventOverrideTest:EventOverrideTest;
+ public var flowModelTest:FlowModelTest;
}
}
http://git-wip-us.apache.org/repos/asf/flex-tlf/blob/7961f332/automation_tests/src/MinimalTestsSuite.as
----------------------------------------------------------------------
diff --git a/automation_tests/src/MinimalTestsSuite.as b/automation_tests/src/MinimalTestsSuite.as
index 3122012..93ef569 100644
--- a/automation_tests/src/MinimalTestsSuite.as
+++ b/automation_tests/src/MinimalTestsSuite.as
@@ -19,13 +19,13 @@
package
{
- import UnitTest.Tests.AccessibilityMethodsTest;
+ import UnitTest.Tests.FactoryImportTest;
[Suite]
[RunWith("org.flexunit.runners.Suite")]
public dynamic class MinimalTestsSuite
{
- public var accessibilityMethodsTest:AccessibilityMethodsTest;
+ public var factoryImportTest:FactoryImportTest;
}
}
http://git-wip-us.apache.org/repos/asf/flex-tlf/blob/7961f332/automation_tests/src/UnitTest/Tests/FactoryImportTest.as
----------------------------------------------------------------------
diff --git a/automation_tests/src/UnitTest/Tests/FactoryImportTest.as b/automation_tests/src/UnitTest/Tests/FactoryImportTest.as
index 17e2220..b8bb3dc 100644
--- a/automation_tests/src/UnitTest/Tests/FactoryImportTest.as
+++ b/automation_tests/src/UnitTest/Tests/FactoryImportTest.as
@@ -18,132 +18,134 @@
////////////////////////////////////////////////////////////////////////////////
package UnitTest.Tests
{
- import UnitTest.ExtendedClasses.TestSuiteExtended;
- import UnitTest.ExtendedClasses.VellumTestCase;
- import UnitTest.Fixtures.FileRepository;
- import UnitTest.Fixtures.TestConfig;
-
- import flash.display.*;
- import flash.geom.Rectangle;
- import flash.text.engine.TextLine;
-
- import flashx.textLayout.conversion.ITextImporter;
- import flashx.textLayout.conversion.TextConverter;
- import flashx.textLayout.elements.FlowLeafElement;
- import flashx.textLayout.elements.InlineGraphicElement;
- import flashx.textLayout.elements.TextFlow;
- import flashx.textLayout.factory.TextFlowTextLineFactory;
-
- import mx.containers.Canvas;
+ import UnitTest.ExtendedClasses.VellumTestCase;
+ import UnitTest.Fixtures.FileRepository;
+ import UnitTest.Fixtures.TestConfig;
- import org.flexunit.asserts.fail;
+ import flash.display.*;
+ import flash.geom.Rectangle;
+ import flash.text.engine.TextLine;
+
+ import flashx.textLayout.conversion.ITextImporter;
+ import flashx.textLayout.conversion.TextConverter;
+ import flashx.textLayout.elements.FlowLeafElement;
+ import flashx.textLayout.elements.InlineGraphicElement;
+ import flashx.textLayout.elements.TextFlow;
+ import flashx.textLayout.factory.TextFlowTextLineFactory;
+ import mx.containers.Canvas;
+
+ import org.flexunit.asserts.fail;
public class FactoryImportTest extends VellumTestCase
- {
- private var ItemsToRemove:Array;
- private var TestCanvas:Canvas = null;
- private var fileForFactory:String;
- private var flowFromXML:TextFlow;
-
- public function FactoryImportTest(fileToImport:String, testID:String, testConfig:TestConfig, testCaseXML:XML=null)
- {
- super ("doThis", testID, testConfig, testCaseXML);
- containerType = "custom";
- fileForFactory = fileToImport;
-
- // Note: These must correspond to a Watson product area (case-sensitive)
- metaData.productArea = "Import/Export";
- }
-
- public function doThis():void
- {
- var xmlRoot:XML = FileRepository.getFileAsXML(baseURL,"../../test/testFiles/markup/tlf/" + fileForFactory);
- if (!xmlRoot)
- {
- fail("File not loaded -- timeout?");
- return;
- }
- var parser:ITextImporter = testDataImportParser;
- flowFromXML = parser.importToFlow(xmlRoot);
- processInlines(flowFromXML);
- buildVellumFactory();
- //TestCanvas.rawChildren.addChild(_rslt);
- }
-
- public static function suiteFromXML(testListXML:XML, testConfig:TestConfig, ts:TestSuiteExtended):void
- {
- var testCaseClass:Class = FactoryImportTest;
- VellumTestCase.suiteFromXML(testCaseClass, testListXML, testConfig, ts);
- }
-
- override public function setUpTest() : void
- {
- cleanUpTestApp();
- ItemsToRemove = [];
- TestDisplayObject = testApp.getDisplayObject();
- if (TestDisplayObject)
- {
- TestCanvas = Canvas(TestDisplayObject);
- }
- else
- {
- fail ("Did not get a blank canvas to work with");
- }
- }
-
- private static function getExtension(fileName:String):String
- {
- var dotPos:int = fileName.lastIndexOf(".");
- if (dotPos >= 0)
- return fileName.substring(dotPos + 1);
- return fileName;
- }
-
- protected function get testDataImportParser():ITextImporter
- {
- var extension:String = getExtension(fileForFactory);
- if (extension == "xml")
- extension = TextConverter.TEXT_LAYOUT_FORMAT;
- else if (extension == "txt")
- extension = TextConverter.PLAIN_TEXT_FORMAT;
- return TextConverter.getImporter(extension);
- }
-
- private function processInlines(textFlow:TextFlow):void
- {
- for (var leaf:FlowLeafElement = textFlow.getFirstLeaf(); leaf; leaf = leaf.getNextLeaf())
- {
- if (leaf is InlineGraphicElement /* && InlineGraphicElement(leaf).source == null */)
- {
- var ilg:InlineGraphicElement = InlineGraphicElement(leaf);
-
- // Create a filler inline, simple filled rect
- var displayObject:Sprite = new Sprite();
- var g:Graphics = displayObject.graphics;
- g.beginFill(0xFF0000);
- g.drawRect(0, 0, Number(ilg.width), Number(ilg.height));
- g.endFill();
- ilg.source = displayObject;
- }
- }
- }
-
- public function callback(dispObj:DisplayObject):void
- {
- TestCanvas.rawChildren.addChild(dispObj);
-
- if(dispObj is TextLine)
- {
- ItemsToRemove.push (dispObj as TextLine);
- }
- }
- /** use the vellum factory via the callback */
- public function buildVellumFactory():void //DisplayObject
- {
- var factory:TextFlowTextLineFactory = new TextFlowTextLineFactory();
- factory.compositionBounds = new Rectangle(0, 0, TestCanvas.width, TestCanvas.height);
- factory.createTextLines(callback,flowFromXML);
- }
- }
+ {
+ private var ItemsToRemove:Array;
+ private var TestCanvas:Canvas = null;
+ private var fileForFactory:String;
+ private var flowFromXML:TextFlow;
+
+ public function FactoryImportTest()
+ {
+ super("", "EventOverrideTest", TestConfig.getInstance());
+
+ containerType = "custom";
+ fileForFactory = "simple.xml";
+
+ metaData = {};
+ // Note: These must correspond to a Watson product area (case-sensitive)
+ metaData.productArea = "Import/Export";
+ }
+
+ [Before]
+ override public function setUpTest():void
+ {
+ cleanUpTestApp();
+ ItemsToRemove = [];
+ TestDisplayObject = testApp.getDisplayObject();
+ if (TestDisplayObject)
+ {
+ TestCanvas = Canvas(TestDisplayObject);
+ }
+ else
+ {
+ fail("Did not get a blank canvas to work with");
+ }
+ }
+
+ [After]
+ override public function tearDownTest():void
+ {
+ super.tearDownTest();
+ }
+
+ [Test]
+ public function importTest():void
+ {
+ var xmlRoot:XML = FileRepository.getFileAsXML(baseURL, "../../test/testFiles/markup/tlf/" + fileForFactory);
+ if (!xmlRoot)
+ {
+ fail("File not loaded -- timeout?");
+ return;
+ }
+ var parser:ITextImporter = testDataImportParser;
+ flowFromXML = parser.importToFlow(xmlRoot);
+ processInlines(flowFromXML);
+ buildVellumFactory();
+ }
+
+ private static function getExtension(fileName:String):String
+ {
+ var dotPos:int = fileName.lastIndexOf(".");
+ if (dotPos >= 0)
+ return fileName.substring(dotPos + 1);
+ return fileName;
+ }
+
+ protected function get testDataImportParser():ITextImporter
+ {
+ var extension:String = getExtension(fileForFactory);
+ if (extension == "xml")
+ extension = TextConverter.TEXT_LAYOUT_FORMAT;
+ else if (extension == "txt")
+ extension = TextConverter.PLAIN_TEXT_FORMAT;
+ return TextConverter.getImporter(extension);
+ }
+
+ private function processInlines(textFlow:TextFlow):void
+ {
+ for (var leaf:FlowLeafElement = textFlow.getFirstLeaf(); leaf; leaf = leaf.getNextLeaf())
+ {
+ if (leaf is InlineGraphicElement /* && InlineGraphicElement(leaf).source == null */)
+ {
+ var ilg:InlineGraphicElement = InlineGraphicElement(leaf);
+
+ // Create a filler inline, simple filled rect
+ var displayObject:Sprite = new Sprite();
+ var g:Graphics = displayObject.graphics;
+ g.beginFill(0xFF0000);
+ g.drawRect(0, 0, Number(ilg.width), Number(ilg.height));
+ g.endFill();
+ ilg.source = displayObject;
+ }
+ }
+ }
+
+ private function callback(dispObj:DisplayObject):void
+ {
+ TestCanvas.rawChildren.addChild(dispObj);
+
+ if (dispObj is TextLine)
+ {
+ ItemsToRemove.push(dispObj as TextLine);
+ }
+ }
+
+ /** use the vellum factory via the callback */
+ private function buildVellumFactory():void //DisplayObject
+ {
+ var factory:TextFlowTextLineFactory = new TextFlowTextLineFactory();
+ factory.compositionBounds = new Rectangle(0, 0, TestCanvas.width, TestCanvas.height);
+ factory.createTextLines(callback, flowFromXML);
+ }
+ }
}
http://git-wip-us.apache.org/repos/asf/flex-tlf/blob/7961f332/automation_tests/src/UnitTest/Tests/FloatTest.as
----------------------------------------------------------------------
diff --git a/automation_tests/src/UnitTest/Tests/FloatTest.as b/automation_tests/src/UnitTest/Tests/FloatTest.as
index da7a19a..2f105a6 100644
--- a/automation_tests/src/UnitTest/Tests/FloatTest.as
+++ b/automation_tests/src/UnitTest/Tests/FloatTest.as
@@ -104,90 +104,6 @@ package UnitTest.Tests
_floatColor = 0xFF0000;
}
- /*
- public static function suite(testConfig:TestConfig, ts:TestSuiteExtended):void
- {
- addTestCase(ts, testConfig, "atFlowStart");
- addTestCase(ts, testConfig, "atFlowStartSpaceBefore");
- addTestCase(ts, testConfig, "atParagraphStart");
- addTestCase(ts, testConfig, "atParagraphStartSpaceBefore");
- addTestCase(ts, testConfig, "atParagraphEnd");
- addTestCase(ts, testConfig, "atLineStart");
- addTestCase(ts, testConfig, "atLineMiddle");
- addTestCase(ts, testConfig, "atLineEnd");
- addTestCase(ts, testConfig, "stackedFloats");
- addTestCase(ts, testConfig, "onTwoSidesSameLine");
- addTestCase(ts, testConfig, "onTwoSidesSuccessiveLines");
- ts.addTestDescriptor (new TestDescriptor (FloatTest,"fillsColumn", testConfig, null) );
- ts.addTestDescriptor (new TestDescriptor (FloatTest,"noEmergencyBreakByFloat", testConfig, null) );
- ts.addTestDescriptor (new TestDescriptor (FloatTest,"fillsColumnRecursion", testConfig, null) );
- ts.addTestDescriptor (new TestDescriptor (FloatTest,"widerThanColumn", testConfig, null) );
- ts.addTestDescriptor (new TestDescriptor (FloatTest,"widerThanColumnScroll", testConfig, null) );
- ts.addTestDescriptor (new TestDescriptor (FloatTest,"contentHeightCheck", testConfig, null) );
- ts.addTestDescriptor (new TestDescriptor (FloatTest,"noFloatsWithMeasureOrExplicit", testConfig, null) );
- ts.addTestDescriptor (new TestDescriptor (FloatTest,"floatOnly", testConfig, null) );
- ts.addTestDescriptor (new TestDescriptor (FloatTest,"noVJ", testConfig, null) );
- ts.addTestDescriptor (new TestDescriptor (FloatTest,"verticalAlignMiddleFloatAtEnd", testConfig, null) );
- ts.addTestDescriptor (new TestDescriptor (FloatTest,"verticalAlignMiddleTextAtEnd", testConfig, null) );
- ts.addTestDescriptor (new TestDescriptor (FloatTest,"verticalAlignBottomFloatAtEnd", testConfig, null) );
- ts.addTestDescriptor (new TestDescriptor (FloatTest,"verticalAlignBottomTextAtEnd", testConfig, null) );
- ts.addTestDescriptor (new TestDescriptor (FloatTest,"verticalAlignBottomFloat2636122", testConfig, null) );
- ts.addTestDescriptor (new TestDescriptor (FloatTest,"textAlignRightAtStart", testConfig, null) );
- ts.addTestDescriptor (new TestDescriptor (FloatTest,"textAlignRightInMiddle", testConfig, null) );
- ts.addTestDescriptor (new TestDescriptor (FloatTest,"leftIndent", testConfig, null) );
- ts.addTestDescriptor (new TestDescriptor (FloatTest,"rightIndent", testConfig, null) );
- ts.addTestDescriptor (new TestDescriptor (FloatTest,"leftBigIndent", testConfig, null) );
- ts.addTestDescriptor (new TestDescriptor (FloatTest,"rightBigIndent", testConfig, null) );
- ts.addTestDescriptor (new TestDescriptor (FloatTest,"clearOneAll", testConfig, null) );
- ts.addTestDescriptor (new TestDescriptor (FloatTest,"clearTwoAll", testConfig, null) );
- ts.addTestDescriptor (new TestDescriptor (FloatTest,"paddingAndMargins", testConfig, null) );
- ts.addTestDescriptor (new TestDescriptor (FloatTest,"negativePaddingAndMargins", testConfig, null) );
- ts.addTestDescriptor (new TestDescriptor (FloatTest,"rightIndentWithTab", testConfig, null) );
- ts.addTestDescriptor (new TestDescriptor (FloatTest,"leftIndentWithTab", testConfig, null) );
- ts.addTestDescriptor (new TestDescriptor (FloatTest,"hoistFailure", testConfig, null) );
- ts.addTestDescriptor (new TestDescriptor (FloatTest,"clearNoPrecedingFloatAll", testConfig, null) );
- ts.addTestDescriptor (new TestDescriptor (FloatTest,"stackedLeftFloats", testConfig, null) );
- ts.addTestDescriptor (new TestDescriptor (FloatTest,"stackedRightFloats", testConfig, null) );
- ts.addTestDescriptor (new TestDescriptor (FloatTest,"smallFloatBigText", testConfig, null) );
- ts.addTestDescriptor (new TestDescriptor (FloatTest,"lineHeightIgnoredOnFloatingImages", testConfig, null) );
- ts.addTestDescriptor (new TestDescriptor (FloatTest,"convertFloatToInline", testConfig, null) );
- ts.addTestDescriptor (new TestDescriptor (FloatTest,"cursorByAnchor", testConfig, null) );
- ts.addTestDescriptor (new TestDescriptor (FloatTest,"insertTextBeforeFloat", testConfig, null) );
- ts.addTestDescriptor (new TestDescriptor (FloatTest,"atControllerEnd", testConfig, null) );
- ts.addTestDescriptor (new TestDescriptor (FloatTest,"resizeControllerWithFloats", testConfig, null) );
- ts.addTestDescriptor (new TestDescriptor (FloatTest,"textIndentAfterFloat", testConfig, null) );
- ts.addTestDescriptor (new TestDescriptor (FloatTest,"composeAcrossControllers", testConfig, null) );
- ts.addTestDescriptor (new TestDescriptor (FloatTest,"deleteAtStart", testConfig, null) );
- ts.addTestDescriptor (new TestDescriptor (FloatTest,"measureWidth", testConfig, null) );
- ts.addTestDescriptor (new TestDescriptor (FloatTest,"inlineWideAndFloat", testConfig, null) );
- ts.addTestDescriptor (new TestDescriptor (FloatTest,"narrowColumnFloat", testConfig, null) );
- ts.addTestDescriptor (new TestDescriptor (FloatTest,"infiniteLoop2769562", testConfig, null) );
- ts.addTestDescriptor (new TestDescriptor (FloatTest, "verticalAlignInline", testConfig, null) );
- ts.addTestDescriptor (new TestDescriptor (FloatTest, "pasteManyFloatsWithLoading", testConfig, null) );
- ts.addTestDescriptor (new TestDescriptor (FloatTest,"contentBoundsWithFactoryComposition", testConfig, null) );
- // We only need one version of these tests
- if (testConfig.writingDirection[0] == BlockProgression.TB && testConfig.writingDirection[1] == Direction.LTR)
- {
- ts.addTestDescriptor (new TestDescriptor (FloatTest,"inlineAndFloat", testConfig, null) );
- ts.addTestDescriptor (new TestDescriptor (FloatTest,"htmlImportTest", testConfig, null) );
- ts.addTestDescriptor (new TestDescriptor (FloatTest,"overFlowAtStart", testConfig, null) );
- ts.addTestDescriptor (new TestDescriptor (FloatTest,"caretOnEmptyInlineGraphic", testConfig, null) );
- ts.addTestDescriptor (new TestDescriptor (FloatTest,"restartComposeFromStart", testConfig, null) );
- ts.addTestDescriptor (new TestDescriptor (FloatTest,"convertInlineToFloat", testConfig, null) );
-
- }
- }
-
- private static function addTestCase(ts:TestSuiteExtended, testConfig:TestConfig, methodName:String):void
- {
- //ts.addTestDescriptor (new TestDescriptor (MeasurementGridTest,methodName, testConfig, creationType, measureType, lineBreak) );
- var testXML:XML = <TestCase>
- <TestData name="methodName">{methodName}</TestData>
- <TestData name="id">{methodName}</TestData>
- </TestCase>;
-
- ts.addTestDescriptor (new TestDescriptor (FloatTest,"callTestMethod", testConfig, testXML) );
- } */
[BeforeClass]
public static function setUpClass():void
{