private void exercise()

in testing/unittestsupport/applib/src/main/java/org/apache/causeway/testing/unittestsupport/applib/dom/pojo/PojoTester.java [541:621]


	private void exercise(final Object bean, String property,
			final Map<String, Method> methods, Method setterMethod,
			final Class<?> parameterType, List<Method> earlierGetters)
			throws AssertionFailedError, TestException {

		final var setterName = setterMethod.getName();
		var factory = dataByType.get(parameterType);
		if (factory == null) {
			// automatically populate for enums
			if (Enum.class.isAssignableFrom(parameterType)) {
				final var testData = parameterType.getEnumConstants();
				factory = new DatumFactoryImpl<>(Object.class) {
					private int index = testData.length - 1;

					@Override
					public Object getNext() {
						index = (index + 1) % testData.length;
						return testData[index];
					}
				};
				dataByType.put(parameterType, factory);
			} else {
				throw new TestException(String.format(
						"No test data is available for %s( %s ).",
						setterName, parameterType.getName()));
			}
		}

		checkMethodVisibility(property, setterName, setterMethod);

		String getterName;
		if (parameterType == boolean.class) {
			getterName = getAccessor("is", property);
			if (property.startsWith("Is") && !methods.containsKey(getterName)) {
				getterName = getAccessor("is", property.substring(2));
			}
		} else {
			getterName = getAccessor("get", property);
		}

		try {
			final var getterMethod = bean.getClass().getMethod(getterName);
			if (getterMethod.getReturnType().equals(void.class)) {
				throw new TestException(String.format("%s(...) is void return.", getterName));
			}
			checkMethodVisibility(property, getterName, getterMethod);

			List<Object> earlierGetterOriginalValues = _Lists.newArrayList();
	        for (var earlierGetter : earlierGetters) {
                final var earlierValue = earlierGetter.invoke(bean);
                earlierGetterOriginalValues.add(earlierValue);
            }

			Object value;
			for (var i = 0; i < 3; i++) {
				value = factory.getNext();
				invokeSetterAndGetter(bean, property, setterMethod,
						getterMethod, value);

				// check hasn't changed value of any of the earlier getters
				var j=0;
	            for (var earlierGetter : earlierGetters) {
	                final var earlierGetterCurrentValue = earlierGetter.invoke(bean);
	                final var earlierGetterOriginalValue = earlierGetterOriginalValues.get(j++);
                    if(!Objects.equals(earlierGetterOriginalValue, earlierGetterCurrentValue)) {
	                    throw new TestException(String.format(
	                    		"%s interferes with %s",
								setterName, earlierGetter.getName()));
	                }
	            }
			}

			// finally store this getter to be tested against the next property
			earlierGetters.add(getterMethod);

		} catch (Exception e) {
            final var error = new TestException(String.format("%s: %s", property, e.getMessage()));
            error.initCause(e);
            throw error;
		}
	}