function assertAllSettersForClass(oClass, assert, oClassConstraints) {
		var oMetadata = oClass.getMetadata(),
			sClassName = oMetadata.getName(),
			oControl;

		// Abstract classes should not be tested on their own
		if (oMetadata.isAbstract()) {
			assert.ok(true, "Abstract class '" + sClassName + "' skipped");
			return;
		}

		var aExcludedSettings = oClassConstraints && Array.isArray(oClassConstraints.exclude) ? oClassConstraints.exclude : [];

		var bForceTest4AllMethods = hasUntestedAbstractBaseClass(oClass, assert);

		try {
			oControl = new oClass();
		} catch (e) {
			assert.ok(false, "Failed to instantiate a '" + sClassName + "' with default settings: " + (e.message || e));
			return;
		}


		var pChain = Promise.resolve();
		var iOwnSettings = 0;

		function hasOwnMethod(obj, name) {
			return Object.prototype.hasOwnProperty.call(obj, name)
				|| Object.prototype.hasOwnProperty.call(oClass.prototype, name)
				|| bForceTest4AllMethods;
		}

		function checkOwnMethod(sMethodName, args, sArgs) {
			if ( hasOwnMethod(oControl, sMethodName) ) {
				iOwnSettings++;
				try {
					assert.ok(
						oControl[sMethodName].apply(oControl, args) === oControl,
						sMethodName + "(" + sArgs + ")" + " should always return <this>");
				} catch (e) {
					// we can't distinguish between expected and unexpected errors here, so we log only
					assert.ok(true,
						sMethodName + "(" + sArgs + ")" + " shouldn't throw an exception");
				}
			}
		}

		each(oMetadata.getAllProperties(), function(sPropertyName, oProperty) {

			if ( aExcludedSettings.indexOf(sPropertyName) >= 0 ) {
				assert.ok(true, "ignore property '" + sPropertyName + "'");
				return;
			}

			if ( hasOwnMethod(oControl, oProperty._sMutator) ) {

				iOwnSettings++;

				// Get the value of the property
				var oValue = oProperty.get(oControl);

				// Assert
				try {
					assert.ok(
						oControl === oProperty.set(oControl, oValue),
						oProperty._sMutator + "(...) should always return <this>");
				} catch (e) {
					// If the setter fails we have a special scenario where date may be required
					// but as there is no type "date" in our metadata API we need to identify it here
					// and provide a JavaScript Date so we can test the setter
					var sName = oProperty.name;
					var bDateInName = sName.indexOf("Date", sName.length - 4) !== -1 || sName.substring(0, 4) === "date";
					if ((sName === "date" || bDateInName) && oProperty.type === "object") {
						assert.ok(
							oControl === oProperty.set(oControl, new Date()),
							oProperty._sMutator + "({js date}) should always return <this>");
					} else {
						// If the setter fails for some reason called with the value from get collected before that
						// we need to fail with a meaningful error.
						assert.ok(false,
							oProperty._sMutator + "(" + oValue + ") fails when called " +
							"with value received from get with exception: " + e);
					}
				}
			}
		});

		each(oMetadata.getAllAggregations(), function(sAggregationName, oAggregation) {

			if ( aExcludedSettings.indexOf(sAggregationName) >= 0 ) {
				assert.ok(true, "ignore aggregation '" + sAggregationName + "'");
				return;
			}

			pChain = pChain.then(function() {
				return createAggregatedElement(oAggregation.type);
			}).then(function(oElement) {
				checkOwnMethod(oAggregation._sMutator, [null], "null");
				if ( oElement ) {
					checkOwnMethod(oAggregation._sMutator, [oElement], "elem");
				}
				if ( oAggregation.multiple ) {
					checkOwnMethod(oAggregation._sInsertMutator, [null], "null");
					if ( oElement ) {
						checkOwnMethod(oAggregation._sInsertMutator, [oElement], "elem");
					}
				}
				checkOwnMethod(oAggregation._sDestructor, [], "");
				if ( oElement && !oElement.bIsDestroyed ) {
					try {
						oElement.destroy();
					} catch (e) {
						// ignore
					}
				}
			});

		});

		each(oMetadata.getAllAssociations(), function(sAssociationName, oAssociation) {
			if ( aExcludedSettings.indexOf(sAssociationName) >= 0 ) {
				assert.ok(true, "ignore aggregation '" + sAssociationName + "'");
				return;
			}
			checkOwnMethod(oAssociation._sMutator, [null], "null");
			checkOwnMethod(oAssociation._sMutator, ["dummy"], "ref");
		});

		each(oMetadata.getAllEvents(), function(sEventName, oEvent) {
			if ( aExcludedSettings.indexOf(sEventName) >= 0 ) {
				assert.ok(true, "ignore aggregation '" + sEventName + "'");
				return;
			}
			checkOwnMethod(oEvent._sMutator, [noop], "listener");
			checkOwnMethod(oEvent._sDetachMutator, [noop], "listener");
		});

		pChain = pChain.then(function() {
			try {
				oControl.destroy();
			} catch (e) {
				// ignore errors during destroy if control is known to have issues there
				assert.ok(oClassConstraints && oClassConstraints.failsOnDestroy,
					"failed to destroy '" + oControl + "'" + (oClassConstraints && oClassConstraints.failsOnDestroy ? " (ignored)" : ""));
			}
			if (iOwnSettings === 0 ) {
				assert.ok(true, "no own settings");
			}
		});

		return pChain;
	}
/**
	 * Creates assertions for all setters of the given class.
	 *
	 * To avoid redundant checks of inherited base class methods in subclasses, only methods are tested
	 * that either have been attached to the instance itself or directly to the prototype of the instance.
	 * This ensures that when a subclass overrides a method locally, the local method also will be tested.
	 *
	 * Abstract base classes are skipped as they often can't be instantiated. To test their 'own' methods, too,
	 * such abstract classes are remembered and the first non-abstract subclass will test all its methods
	 * including the inherited ones, not only its own methods.
	 *
	 * @param {string} sClassName class to be tested
	 * @param {function} fnAssert QUnit assert
	 */
Creates assertions for all setters of the given class.
To avoid redundant checks of inherited base class methods in subclasses, only methods are tested
that either have been attached to the instance itself or directly to the prototype of the instance.
This ensures that when a subclass overrides a method locally, the local method also will be tested.

Abstract base classes are skipped as they often can't be instantiated. To test their 'own' methods, too,
such abstract classes are remembered and the first non-abstract subclass will test all its methods
including the inherited ones, not only its own methods.

@param {string} sClassName class to be tested
@param {function} fnAssert QUnit assert
Creates assertions for all setters of the given class . To avoid redundant checks of inherited base class methods in subclasses only methods are tested that either have been attached to the instance itself or directly to the prototype of the instance . This ensures that when a subclass overrides a method locally the local method also will be tested . Abstract base classes are skipped as they often can ' t be instantiated . To test their ' own ' methods too such abstract classes are remembered and the first non - abstract subclass will test all its methods including the inherited ones not only its own methods . @param { string } sClassName class to be tested @param { function } fnAssert QUnit assert
function assertAllSettersForClass(oClass, assert, oClassConstraints) {
		var oMetadata = oClass.getMetadata(),
			sClassName = oMetadata.getName(),
			oControl;
		if (oMetadata.isAbstract()) {
			assert.ok(true, "Abstract class '" + sClassName + "' skipped");
			return;
		}
		var aExcludedSettings = oClassConstraints && Array.isArray(oClassConstraints.exclude) ? oClassConstraints.exclude : [];
		var bForceTest4AllMethods = hasUntestedAbstractBaseClass(oClass, assert);
		try {
			oControl = new oClass();
		} catch (e) {
			assert.ok(false, "Failed to instantiate a '" + sClassName + "' with default settings: " + (e.message || e));
			return;
		}
		var pChain = Promise.resolve();
		var iOwnSettings = 0;
		function hasOwnMethod(obj, name) {
			return Object.prototype.hasOwnProperty.call(obj, name)
				|| Object.prototype.hasOwnProperty.call(oClass.prototype, name)
				|| bForceTest4AllMethods;
		}
		function checkOwnMethod(sMethodName, args, sArgs) {
			if ( hasOwnMethod(oControl, sMethodName) ) {
				iOwnSettings++;
				try {
					assert.ok(
						oControl[sMethodName].apply(oControl, args) === oControl,
						sMethodName + "(" + sArgs + ")" + " should always return <this>");
				} catch (e) {
					assert.ok(true,
						sMethodName + "(" + sArgs + ")" + " shouldn't throw an exception");
				}
			}
		}
		each(oMetadata.getAllProperties(), function(sPropertyName, oProperty) {
			if ( aExcludedSettings.indexOf(sPropertyName) >= 0 ) {
				assert.ok(true, "ignore property '" + sPropertyName + "'");
				return;
			}
			if ( hasOwnMethod(oControl, oProperty._sMutator) ) {
				iOwnSettings++;
				var oValue = oProperty.get(oControl);
				try {
					assert.ok(
						oControl === oProperty.set(oControl, oValue),
						oProperty._sMutator + "(...) should always return <this>");
				} catch (e) {
					var sName = oProperty.name;
					var bDateInName = sName.indexOf("Date", sName.length - 4) !== -1 || sName.substring(0, 4) === "date";
					if ((sName === "date" || bDateInName) && oProperty.type === "object") {
						assert.ok(
							oControl === oProperty.set(oControl, new Date()),
							oProperty._sMutator + "({js date}) should always return <this>");
					} else {
						assert.ok(false,
							oProperty._sMutator + "(" + oValue + ") fails when called " +
							"with value received from get with exception: " + e);
					}
				}
			}
		});
		each(oMetadata.getAllAggregations(), function(sAggregationName, oAggregation) {
			if ( aExcludedSettings.indexOf(sAggregationName) >= 0 ) {
				assert.ok(true, "ignore aggregation '" + sAggregationName + "'");
				return;
			}
			pChain = pChain.then(function() {
				return createAggregatedElement(oAggregation.type);
			}).then(function(oElement) {
				checkOwnMethod(oAggregation._sMutator, [null], "null");
				if ( oElement ) {
					checkOwnMethod(oAggregation._sMutator, [oElement], "elem");
				}
				if ( oAggregation.multiple ) {
					checkOwnMethod(oAggregation._sInsertMutator, [null], "null");
					if ( oElement ) {
						checkOwnMethod(oAggregation._sInsertMutator, [oElement], "elem");
					}
				}
				checkOwnMethod(oAggregation._sDestructor, [], "");
				if ( oElement && !oElement.bIsDestroyed ) {
					try {
						oElement.destroy();
					} catch (e) {
					}
				}
			});
		});
		each(oMetadata.getAllAssociations(), function(sAssociationName, oAssociation) {
			if ( aExcludedSettings.indexOf(sAssociationName) >= 0 ) {
				assert.ok(true, "ignore aggregation '" + sAssociationName + "'");
				return;
			}
			checkOwnMethod(oAssociation._sMutator, [null], "null");
			checkOwnMethod(oAssociation._sMutator, ["dummy"], "ref");
		});
		each(oMetadata.getAllEvents(), function(sEventName, oEvent) {
			if ( aExcludedSettings.indexOf(sEventName) >= 0 ) {
				assert.ok(true, "ignore aggregation '" + sEventName + "'");
				return;
			}
			checkOwnMethod(oEvent._sMutator, [noop], "listener");
			checkOwnMethod(oEvent._sDetachMutator, [noop], "listener");
		});
		pChain = pChain.then(function() {
			try {
				oControl.destroy();
			} catch (e) {
				 errors during destroy if control is known to have issues there
				assert.ok(oClassConstraints && oClassConstraints.failsOnDestroy,
					"failed to destroy '" + oControl + "'" + (oClassConstraints && oClassConstraints.failsOnDestroy ? " (ignored)" : ""));
			}
			if (iOwnSettings === 0 ) {
				assert.ok(true, "no own settings");
			}
		});
		return pChain;
	}
function assertAllSettersForClass ( oClass , assert , oClassConstraints ) { var oMetadata = oClass . getMetadata ( ) , sClassName = oMetadata . getName ( ) , oControl ; if ( oMetadata . isAbstract ( ) ) { assert . ok ( true , "Abstract class '" + sClassName + "' skipped" ) ; return ; } var aExcludedSettings = oClassConstraints && Array . isArray ( oClassConstraints . exclude ) ? oClassConstraints . exclude : [ ] ; var bForceTest4AllMethods = hasUntestedAbstractBaseClass ( oClass , assert ) ; try { oControl = new oClass ( ) ; } catch ( e ) { assert . ok ( false , "Failed to instantiate a '" + sClassName + "' with default settings: " + ( e . message || e ) ) ; return ; } var pChain = Promise . resolve ( ) ; var iOwnSettings = 0 ; function hasOwnMethod ( obj , name ) { return Object . prototype . hasOwnProperty . call ( obj , name ) || Object . prototype . hasOwnProperty . call ( oClass . prototype , name ) || bForceTest4AllMethods ; } function checkOwnMethod ( sMethodName , args , sArgs ) { if ( hasOwnMethod ( oControl , sMethodName ) ) { iOwnSettings ++ ; try { assert . ok ( oControl [ sMethodName ] . apply ( oControl , args ) === oControl , sMethodName + "(" + sArgs + ")" + " should always return <this>" ) ; } catch ( e ) { assert . ok ( true , sMethodName + "(" + sArgs + ")" + " shouldn't throw an exception" ) ; } } } each ( oMetadata . getAllProperties ( ) , function ( sPropertyName , oProperty ) { if ( aExcludedSettings . indexOf ( sPropertyName ) >= 0 ) { assert . ok ( true , "ignore property '" + sPropertyName + "'" ) ; return ; } if ( hasOwnMethod ( oControl , oProperty . _sMutator ) ) { iOwnSettings ++ ; var oValue = oProperty . get ( oControl ) ; try { assert . ok ( oControl === oProperty . set ( oControl , oValue ) , oProperty . _sMutator + "(...) should always return <this>" ) ; } catch ( e ) { var sName = oProperty . name ; var bDateInName = sName . indexOf ( "Date" , sName . length - 4 ) !== - 1 || sName . substring ( 0 , 4 ) === "date" ; if ( ( sName === "date" || bDateInName ) && oProperty . type === "object" ) { assert . ok ( oControl === oProperty . set ( oControl , new Date ( ) ) , oProperty . _sMutator + "({js date}) should always return <this>" ) ; } else { assert . ok ( false , oProperty . _sMutator + "(" + oValue + ") fails when called " + "with value received from get with exception: " + e ) ; } } } } ) ; each ( oMetadata . getAllAggregations ( ) , function ( sAggregationName , oAggregation ) { if ( aExcludedSettings . indexOf ( sAggregationName ) >= 0 ) { assert . ok ( true , "ignore aggregation '" + sAggregationName + "'" ) ; return ; } pChain = pChain . then ( function ( ) { return createAggregatedElement ( oAggregation . type ) ; } ) . then ( function ( oElement ) { checkOwnMethod ( oAggregation . _sMutator , [ null ] , "null" ) ; if ( oElement ) { checkOwnMethod ( oAggregation . _sMutator , [ oElement ] , "elem" ) ; } if ( oAggregation . multiple ) { checkOwnMethod ( oAggregation . _sInsertMutator , [ null ] , "null" ) ; if ( oElement ) { checkOwnMethod ( oAggregation . _sInsertMutator , [ oElement ] , "elem" ) ; } } checkOwnMethod ( oAggregation . _sDestructor , [ ] , "" ) ; if ( oElement && ! oElement . bIsDestroyed ) { try { oElement . destroy ( ) ; } catch ( e ) { } } } ) ; } ) ; each ( oMetadata . getAllAssociations ( ) , function ( sAssociationName , oAssociation ) { if ( aExcludedSettings . indexOf ( sAssociationName ) >= 0 ) { assert . ok ( true , "ignore aggregation '" + sAssociationName + "'" ) ; return ; } checkOwnMethod ( oAssociation . _sMutator , [ null ] , "null" ) ; checkOwnMethod ( oAssociation . _sMutator , [ "dummy" ] , "ref" ) ; } ) ; each ( oMetadata . getAllEvents ( ) , function ( sEventName , oEvent ) { if ( aExcludedSettings . indexOf ( sEventName ) >= 0 ) { assert . ok ( true , "ignore aggregation '" + sEventName + "'" ) ; return ; } checkOwnMethod ( oEvent . _sMutator , [ noop ] , "listener" ) ; checkOwnMethod ( oEvent . _sDetachMutator , [ noop ] , "listener" ) ; } ) ; pChain = pChain . then ( function ( ) { try { oControl . destroy ( ) ; } catch ( e ) { assert . ok ( oClassConstraints && oClassConstraints . failsOnDestroy , "failed to destroy '" + oControl + "'" + ( oClassConstraints && oClassConstraints . failsOnDestroy ? " (ignored)" : "" ) ) ; } if ( iOwnSettings === 0 ) { assert . ok ( true , "no own settings" ) ; } } ) ; return pChain ; }
Creates assertions for all setters of the given class.
Creates assertions for all setters of the given class .
// Abstract classes should not be tested on their own // we can't distinguish between expected and unexpected errors here, so we log only // Get the value of the property // Assert // If the setter fails we have a special scenario where date may be required // but as there is no type "date" in our metadata API we need to identify it here // and provide a JavaScript Date so we can test the setter // If the setter fails for some reason called with the value from get collected before that // we need to fail with a meaningful error. // ignore // ignore errors during destroy if control is known to have issues there