defineSuite([ 'DataSources/Entity', 'Core/Cartesian3', 'Core/JulianDate', 'Core/Matrix3', 'Core/Matrix4', 'Core/Quaternion', 'Core/TimeInterval', 'Core/TimeIntervalCollection', 'Core/Transforms', 'DataSources/BillboardGraphics', 'DataSources/BoxGraphics', 'DataSources/ConstantPositionProperty', 'DataSources/ConstantProperty', 'DataSources/CorridorGraphics', 'DataSources/CylinderGraphics', 'DataSources/EllipseGraphics', 'DataSources/EllipsoidGraphics', 'DataSources/LabelGraphics', 'DataSources/ModelGraphics', 'DataSources/PathGraphics', 'DataSources/PlaneGraphics', 'DataSources/PointGraphics', 'DataSources/PolygonGraphics', 'DataSources/PolylineGraphics', 'DataSources/PolylineVolumeGraphics', 'DataSources/RectangleGraphics', 'DataSources/WallGraphics' ], function( Entity, Cartesian3, JulianDate, Matrix3, Matrix4, Quaternion, TimeInterval, TimeIntervalCollection, Transforms, BillboardGraphics, BoxGraphics, ConstantPositionProperty, ConstantProperty, CorridorGraphics, CylinderGraphics, EllipseGraphics, EllipsoidGraphics, LabelGraphics, ModelGraphics, PathGraphics, PlaneGraphics, PointGraphics, PolygonGraphics, PolylineGraphics, PolylineVolumeGraphics, RectangleGraphics, WallGraphics) { 'use strict'; it('constructor sets expected properties.', function() { var entity = new Entity(); expect(entity.id).toBeDefined(); expect(entity.name).toBeUndefined(); expect(entity.billboard).toBeUndefined(); expect(entity.box).toBeUndefined(); expect(entity.corridor).toBeUndefined(); expect(entity.cylinder).toBeUndefined(); expect(entity.description).toBeUndefined(); expect(entity.ellipse).toBeUndefined(); expect(entity.ellipsoid).toBeUndefined(); expect(entity.label).toBeUndefined(); expect(entity.model).toBeUndefined(); expect(entity.orientation).toBeUndefined(); expect(entity.path).toBeUndefined(); expect(entity.plane).toBeUndefined(); expect(entity.point).toBeUndefined(); expect(entity.polygon).toBeUndefined(); expect(entity.polyline).toBeUndefined(); expect(entity.polylineVolume).toBeUndefined(); expect(entity.position).toBeUndefined(); expect(entity.rectangle).toBeUndefined(); expect(entity.viewFrom).toBeUndefined(); expect(entity.wall).toBeUndefined(); expect(entity.entityCollection).toBeUndefined(); var options = { id : 'someId', name : 'bob', show : false, availability : new TimeIntervalCollection(), parent : new Entity(), customProperty : {}, billboard : {}, box : {}, corridor : {}, cylinder : {}, description : 'description', ellipse : {}, ellipsoid : {}, label : {}, model : {}, orientation : new Quaternion(1, 2, 3, 4), path : {}, plane : {}, point : {}, polygon : {}, polyline : {}, polylineVolume : {}, position : new Cartesian3(5, 6, 7), rectangle : {}, viewFrom : new Cartesian3(8, 9, 10), wall : {} }; entity = new Entity(options); expect(entity.id).toEqual(options.id); expect(entity.name).toEqual(options.name); expect(entity.show).toBe(options.show); expect(entity.availability).toBe(options.availability); expect(entity.parent).toBe(options.parent); expect(entity.customProperty).toBe(options.customProperty); expect(entity.billboard).toBeInstanceOf(BillboardGraphics); expect(entity.box).toBeInstanceOf(BoxGraphics); expect(entity.corridor).toBeInstanceOf(CorridorGraphics); expect(entity.cylinder).toBeInstanceOf(CylinderGraphics); expect(entity.description).toBeInstanceOf(ConstantProperty); expect(entity.ellipse).toBeInstanceOf(EllipseGraphics); expect(entity.ellipsoid).toBeInstanceOf(EllipsoidGraphics); expect(entity.label).toBeInstanceOf(LabelGraphics); expect(entity.model).toBeInstanceOf(ModelGraphics); expect(entity.orientation).toBeInstanceOf(ConstantProperty); expect(entity.path).toBeInstanceOf(PathGraphics); expect(entity.plane).toBeInstanceOf(PlaneGraphics); expect(entity.point).toBeInstanceOf(PointGraphics); expect(entity.polygon).toBeInstanceOf(PolygonGraphics); expect(entity.polyline).toBeInstanceOf(PolylineGraphics); expect(entity.polylineVolume).toBeInstanceOf(PolylineVolumeGraphics); expect(entity.position).toBeInstanceOf(ConstantPositionProperty); expect(entity.rectangle).toBeInstanceOf(RectangleGraphics); expect(entity.viewFrom).toBeInstanceOf(ConstantProperty); expect(entity.wall).toBeInstanceOf(WallGraphics); expect(entity.entityCollection).toBeUndefined(); }); it('isAvailable is always true if no availability defined.', function() { var entity = new Entity(); expect(entity.isAvailable(JulianDate.now())).toEqual(true); }); it('isAvailable throw if no time specified.', function() { var entity = new Entity(); expect(function() { entity.isAvailable(); }).toThrowDeveloperError(); }); it('constructor creates a unique id if one is not provided.', function() { var object = new Entity(); var object2 = new Entity(); expect(object.id).toBeDefined(); expect(object.id).not.toEqual(object2.id); }); it('isAvailable works.', function() { var entity = new Entity(); var interval = TimeInterval.fromIso8601({ iso8601 : '2000-01-01/2001-01-01' }); var intervals = new TimeIntervalCollection(); intervals.addInterval(interval); entity.availability = intervals; expect(entity.isAvailable(JulianDate.addSeconds(interval.start, -1, new JulianDate()))).toEqual(false); expect(entity.isAvailable(interval.start)).toEqual(true); expect(entity.isAvailable(interval.stop)).toEqual(true); expect(entity.isAvailable(JulianDate.addSeconds(interval.stop, 1, new JulianDate()))).toEqual(false); }); it('definitionChanged works for all properties', function() { var entity = new Entity(); var propertyNames = entity.propertyNames; var propertyNamesLength = propertyNames.length; var listener = jasmine.createSpy('listener'); entity.definitionChanged.addEventListener(listener); var i; var name; var newValue; var oldValue; //We loop through twice to ensure that oldValue is properly passed in. for (var x = 0; x < 2; x++) { for (i = 0; i < propertyNamesLength; i++) { name = propertyNames[i]; newValue = new ConstantProperty(1); oldValue = entity[propertyNames[i]]; entity[name] = newValue; expect(listener).toHaveBeenCalledWith(entity, name, newValue, oldValue); } } }); it('merge always overwrites availability', function() { var entity = new Entity(); var interval = TimeInterval.fromIso8601({ iso8601 : '2000-01-01/2001-01-01' }); entity.availability = interval; var entity2 = new Entity(); var interval2 = TimeInterval.fromIso8601({ iso8601 : '2000-01-01/2001-01-01' }); entity2.availability = interval2; entity.merge(entity2); expect(entity.availability).toBe(interval2); }); it('merge works with custom properties.', function() { var propertyName = 'customProperty'; var value = 'fizzbuzz'; var source = new Entity({ id : 'source' }); source.addProperty(propertyName); source[propertyName] = value; var target = new Entity({ id : 'target' }); //Merging should actually call addProperty for the customProperty. spyOn(target, 'addProperty').and.callThrough(); target.merge(source); expect(target.addProperty).toHaveBeenCalledWith(propertyName); expect(target[propertyName]).toEqual(source[propertyName]); }); it('merge throws with undefined source', function() { var entity = new Entity(); expect(function() { entity.merge(undefined); }).toThrowDeveloperError(); }); it('computeModelMatrix throws if no time specified.', function() { var entity = new Entity(); expect(function() { entity.computeModelMatrix(); }).toThrowDeveloperError(); }); it('computeModelMatrix returns undefined when position is undefined.', function() { var entity = new Entity(); entity.orientation = new ConstantProperty(Quaternion.IDENTITY); expect(entity.computeModelMatrix(new JulianDate())).toBeUndefined(); }); it('computeModelMatrix returns correct value.', function() { var entity = new Entity(); var position = new Cartesian3(123456, 654321, 123456); var orientation = new Quaternion(1, 2, 3, 4); Quaternion.normalize(orientation, orientation); entity.position = new ConstantProperty(position); entity.orientation = new ConstantProperty(orientation); var modelMatrix = entity.computeModelMatrix(new JulianDate()); var expected = Matrix4.fromRotationTranslation(Matrix3.fromQuaternion(orientation), position); expect(modelMatrix).toEqual(expected); }); it('computeModelMatrix returns ENU when quaternion is undefined.', function() { var entity = new Entity(); var position = new Cartesian3(123456, 654321, 123456); entity.position = new ConstantProperty(position); var modelMatrix = entity.computeModelMatrix(new JulianDate()); var expected = Transforms.eastNorthUpToFixedFrame(position); expect(modelMatrix).toEqual(expected); }); it('computeModelMatrix works with result parameter.', function() { var entity = new Entity(); var position = new Cartesian3(123456, 654321, 123456); entity.position = new ConstantProperty(position); var result = new Matrix4(); var modelMatrix = entity.computeModelMatrix(new JulianDate(), result); var expected = Transforms.eastNorthUpToFixedFrame(position); expect(modelMatrix).toBe(result); expect(modelMatrix).toEqual(expected); }); it('can add and remove custom properties.', function() { var entity = new Entity(); expect(entity.hasOwnProperty('bob')).toBe(false); expect(entity.propertyNames).not.toContain('bob'); entity.addProperty('bob'); expect(entity.hasOwnProperty('bob')).toBe(true); expect(entity.propertyNames).toContain('bob'); entity.removeProperty('bob'); expect(entity.hasOwnProperty('bob')).toBe(false); expect(entity.propertyNames).not.toContain('bob'); }); it('can re-add removed properties', function() { var entity = new Entity(); entity.addProperty('bob'); entity.removeProperty('bob'); entity.addProperty('bob'); expect(entity.hasOwnProperty('bob')).toBe(true); expect(entity.propertyNames).toContain('bob'); }); it('addProperty throws with no property specified.', function() { var entity = new Entity(); expect(function() { entity.addProperty(undefined); }).toThrowDeveloperError(); }); it('addProperty throws with no property specified.', function() { var entity = new Entity(); expect(function() { entity.addProperty(undefined); }).toThrowDeveloperError(); }); it('removeProperty throws with no property specified.', function() { var entity = new Entity(); expect(function() { entity.removeProperty(undefined); }).toThrowDeveloperError(); }); it('addProperty throws when adding an existing property.', function() { var entity = new Entity(); entity.addProperty('bob'); expect(function() { entity.addProperty('bob'); }).toThrowDeveloperError(); }); it('removeProperty throws when non-existent property.', function() { var entity = new Entity(); expect(function() { entity.removeProperty('bob'); }).toThrowDeveloperError(); }); it('addProperty throws with defined reserved property name.', function() { var entity = new Entity(); expect(function() { entity.addProperty('merge'); }).toThrowDeveloperError(); }); it('removeProperty throws with defined reserved property name.', function() { var entity = new Entity(); expect(function() { entity.removeProperty('merge'); }).toThrowDeveloperError(); }); it('addProperty throws with undefined reserved property name.', function() { var entity = new Entity(); expect(entity.name).toBeUndefined(); expect(function() { entity.addProperty('name'); }).toThrowDeveloperError(); }); it('removeProperty throws with undefined reserved property name.', function() { var entity = new Entity(); expect(entity.name).toBeUndefined(); expect(function() { entity.removeProperty('name'); }).toThrowDeveloperError(); }); it('isShowing works without parent.', function() { var entity = new Entity({ show : false }); expect(entity.isShowing).toBe(false); var listener = jasmine.createSpy('listener'); entity.definitionChanged.addEventListener(listener); entity.show = true; expect(listener.calls.count()).toBe(2); expect(listener.calls.argsFor(0)).toEqual([entity, 'isShowing', true, false]); expect(listener.calls.argsFor(1)).toEqual([entity, 'show', true, false]); expect(entity.isShowing).toBe(true); listener.calls.reset(); entity.show = false; expect(listener.calls.count()).toBe(2); expect(listener.calls.argsFor(0)).toEqual([entity, 'isShowing', false, true]); expect(listener.calls.argsFor(1)).toEqual([entity, 'show', false, true]); expect(entity.isShowing).toBe(false); }); function ancestorShowTest(entity, ancestor) { var listener = jasmine.createSpy('listener'); entity.definitionChanged.addEventListener(listener); ancestor.show = false; //Setting ancestor show to false causes entity to raise //its own isShowing event, but not the show event. expect(listener.calls.count()).toBe(1); expect(listener.calls.argsFor(0)).toEqual([entity, 'isShowing', false, true]); expect(entity.show).toBe(true); expect(entity.isShowing).toBe(false); listener.calls.reset(); //Since isShowing is already false, setting show to false causes the show event //but not the isShowing event to be raised entity.show = false; expect(entity.show).toBe(false); expect(listener.calls.count()).toBe(1); expect(listener.calls.argsFor(0)).toEqual([entity, 'show', false, true]); listener.calls.reset(); //Setting ancestor show to true does not trigger the entity.isShowing event //because entity.show is false; ancestor.show = true; expect(entity.show).toBe(false); expect(entity.isShowing).toBe(false); expect(listener.calls.count()).toBe(0); listener.calls.reset(); //Setting entity.show to try now causes both events to be raised //because the ancestor is also showing. entity.show = true; expect(listener.calls.count()).toBe(2); expect(listener.calls.argsFor(0)).toEqual([entity, 'isShowing', true, false]); expect(listener.calls.argsFor(1)).toEqual([entity, 'show', true, false]); expect(entity.show).toBe(true); expect(entity.isShowing).toBe(true); } it('isShowing works with parent.', function() { var parent = new Entity(); var entity = new Entity(); entity.parent = parent; ancestorShowTest(entity, parent); }); it('isShowing works with grandparent.', function() { var grandparent = new Entity(); var parent = new Entity(); parent.parent = grandparent; var entity = new Entity(); entity.parent = parent; ancestorShowTest(entity, grandparent); }); it('isShowing works when replacing parent.', function() { var entity = new Entity(); entity.parent = new Entity(); var listener = jasmine.createSpy('listener'); entity.definitionChanged.addEventListener(listener); entity.parent = new Entity({ show : false }); expect(listener.calls.count()).toBe(2); expect(listener.calls.argsFor(0)).toEqual([entity, 'isShowing', false, true]); expect(entity.show).toBe(true); expect(entity.isShowing).toBe(false); }); it('isShowing works when removing parent.', function() { var entity = new Entity(); entity.parent = new Entity({ show : false }); expect(entity.isShowing).toBe(false); var listener = jasmine.createSpy('listener'); entity.definitionChanged.addEventListener(listener); entity.parent = undefined; expect(listener.calls.count()).toBe(2); expect(listener.calls.argsFor(0)).toEqual([entity, 'isShowing', true, false]); expect(entity.isShowing).toBe(true); }); });