use of com.google.api.ads.adwords.axis.v201809.cm.ProductDimension in project googleads-java-lib by googleads.
the class ProductDimensionsTest method testCreateMethodExistsForEveryDimensionSubclass.
/**
* Test that verifies that {@link ProductDimensions} has a {@code createX} method for every
* subclass {@code X} of {@link ProductDimension}.
*/
@SuppressWarnings("unchecked")
@Test
public void testCreateMethodExistsForEveryDimensionSubclass() throws Exception {
String basePackageNameForVersion = ProductDimension.class.getPackage().getName().substring(0, ProductDimension.class.getPackage().getName().length() - ".cm".length());
ClassPath classPath = ClassPath.from(ProductDimension.class.getClassLoader());
Set<?> dimensionSubclasses = classPath.getTopLevelClassesRecursive(basePackageNameForVersion).stream().map(ClassInfo::load).filter(classInfoClass -> ProductDimension.class.isAssignableFrom(classInfoClass) && ProductDimension.class != classInfoClass).collect(Collectors.toSet());
Map<Class<? extends ProductDimension>, Method> factoryMethodsMap = getAllProductDimensionFactoryMethods();
dimensionSubclasses.stream().filter(dimensionSubclass -> !DIMENSION_TYPES_TO_IGNORE.contains(dimensionSubclass)).forEach(dimensionSubclass -> assertThat("No factory method exists for subclass " + dimensionSubclass + " of ProductDimension", (Class<? extends ProductDimension>) dimensionSubclass, Matchers.isIn(factoryMethodsMap.keySet())));
}
use of com.google.api.ads.adwords.axis.v201809.cm.ProductDimension in project googleads-java-lib by googleads.
the class ProductPartitionNodeTest method testDimensionToString.
/**
* Test to confirm that {@link ProductPartitionNode#toString(ProductDimension)} handles each
* subclass of {@link ProductDimension}. This will help ensure that
* {@link ProductPartitionNode#toString(ProductDimension)} is kept up to date with changes in
* {@link ProductDimensions}.
*/
@Test
public void testDimensionToString() throws Exception {
// Use reflection to determine which subclasses of ProductDimension have a factory
// method in ProductDimensions.
Set<Class<? extends ProductDimension>> dimensionSubclasses = ProductDimensionsTest.getAllProductDimensionFactoryMethods().keySet();
// Create a sample instance for each subclass of ProductDimension.
Map<Class<? extends ProductDimension>, ProductDimension> dimensionsByType = Maps.newHashMap();
dimensionsByType.put(ProductBrand.class, ProductDimensions.createBrand("testBrand"));
dimensionsByType.put(ProductBiddingCategory.class, ProductDimensions.createBiddingCategory(ProductDimensionType.BIDDING_CATEGORY_L1, 123L));
dimensionsByType.put(ProductCanonicalCondition.class, ProductDimensions.createCanonicalCondition(ProductCanonicalConditionCondition.NEW));
dimensionsByType.put(ProductChannel.class, ProductDimensions.createChannel(ShoppingProductChannel.LOCAL));
dimensionsByType.put(ProductChannelExclusivity.class, ProductDimensions.createChannelExclusivity(ShoppingProductChannelExclusivity.SINGLE_CHANNEL));
dimensionsByType.put(ProductCustomAttribute.class, ProductDimensions.createCustomAttribute(ProductDimensionType.CUSTOM_ATTRIBUTE_2, "testAttribute"));
dimensionsByType.put(ProductOfferId.class, ProductDimensions.createOfferId("testOfferId"));
dimensionsByType.put(ProductType.class, ProductDimensions.createType(ProductDimensionType.PRODUCT_TYPE_L3, "testType"));
// sample instance.
for (Class<? extends ProductDimension> dimensionSubclass : dimensionSubclasses) {
ProductDimension sampleDimension = dimensionsByType.get(dimensionSubclass);
assertNotNull("No sample dimension found for ProductDimension subclass " + dimensionSubclass + ". Add a sample instance of this type to the dimensionsByType map in this test.", sampleDimension);
String dimensionToString = ProductPartitionNode.toString(sampleDimension);
assertThat("ProductPartitionNode.toString does not appear to recognize any attributes of " + dimensionSubclass, dimensionToString, Matchers.not(Matchers.containsString("[]")));
assertThat("ProductPartitionNode.toString failed to interpret the attributes of a " + dimensionSubclass, dimensionToString, Matchers.not(Matchers.containsString("UNKNOWN")));
}
}
use of com.google.api.ads.adwords.axis.v201809.cm.ProductDimension in project googleads-java-lib by googleads.
the class ProductPartitionTreeImpl method addMutateOperations.
/**
* Adds to the operations list all operations required to mutate {@code originalNode} to the state
* of {@code newNode}.
*
* <p>The returned set of child product dimensions will only <em>potentially</em> be non-empty if
* both {@code originalNode != null} and {@code newNode != null}.
*
* @param originalNode may be null
* @param newNode may be null
* @param ops the operations list to add to
*
* @return the set of child product dimensions that require further processing
*/
private Set<ProductDimension> addMutateOperations(@Nullable ProductPartitionNode originalNode, @Nullable ProductPartitionNode newNode, List<OperationPair> ops) {
Set<ProductDimension> childDimensionsToProcess = Sets.newTreeSet(dimensionComparator);
NodeDifference nodeDifference = ProductPartitionNodeDiffer.diff(originalNode, newNode, dimensionComparator);
boolean isProcessChildren;
switch(nodeDifference) {
case NEW_NODE:
ops.addAll(createAddOperations(newNode));
// No need to further process children. The ADD operations above will include operations
// for all children of newNode.
isProcessChildren = false;
break;
case REMOVED_NODE:
ops.add(createRemoveOperation(originalNode));
// No need to further process children. The REMOVE operation above will perform a
// cascading delete of all children of newNode.
isProcessChildren = false;
break;
case PARTITION_TYPE_CHANGE:
case EXCLUDED_UNIT_CHANGE:
ops.add(createRemoveOperation(originalNode));
ops.addAll(createAddOperations(newNode));
// No need to further process children. The ADD operations above will include operations
// for all children of newNode.
isProcessChildren = false;
break;
case BIDDABLE_UNIT_CHANGE:
// Ensure that the new node has the proper ID (this may have been lost if the node
// was removed and then re-added).
newNode = newNode.setProductPartitionId(originalNode.getProductPartitionId());
ops.add(createSetBidOperation(newNode));
// Process the children of newNode. The SET operation above will only handle changes
// made to newNode, not its children.
isProcessChildren = true;
break;
case NONE:
// Ensure that the new node has the proper ID (this may have been lost if the node
// was removed and then re-added).
newNode = newNode.setProductPartitionId(originalNode.getProductPartitionId());
// This node does not have changes, but its children may.
isProcessChildren = true;
break;
default:
throw new IllegalStateException("Unrecognized difference: " + nodeDifference);
}
if (isProcessChildren) {
for (ProductPartitionNode childNode : Iterables.concat(originalNode.getChildren(), newNode.getChildren())) {
childDimensionsToProcess.add(childNode.getDimension());
}
}
return childDimensionsToProcess;
}
use of com.google.api.ads.adwords.axis.v201809.cm.ProductDimension in project googleads-java-lib by googleads.
the class ProductPartitionTreeImpl method addMutateOperationsByParent.
/**
* Adds to the operations list all operations required to mutate the children of
* {@code originalParentNode} to {@code newParentNode}.
*
* @param originalParentNode required - must not be null
* @param newParentNode required - must not be null
* @param childDimensionsToProcess the child dimensions to process
* @param ops the operations list to add to
*/
private void addMutateOperationsByParent(ProductPartitionNode originalParentNode, ProductPartitionNode newParentNode, Set<ProductDimension> childDimensionsToProcess, List<OperationPair> ops) {
for (ProductDimension dimensionToProcess : childDimensionsToProcess) {
ProductPartitionNode originalChild = originalParentNode.hasChild(dimensionToProcess) ? originalParentNode.getChild(dimensionToProcess) : null;
ProductPartitionNode newChild = newParentNode.hasChild(dimensionToProcess) ? newParentNode.getChild(dimensionToProcess) : null;
Set<ProductDimension> grandchildDimensionsToProcess = addMutateOperations(originalChild, newChild, ops);
if (!grandchildDimensionsToProcess.isEmpty()) {
// Logic check - the only condition where further processing of children is required
// is when the parent exists in both trees. If the parent is null in one tree but
// not the other, then the node for dimensionToProcess was either:
// 1) removed from the original OR
// 2) added to the new tree
// In both cases, the call to addMutateOperations above will have already added all of the
// necessary operations to handle the node and all of its children.
Preconditions.checkState(originalChild != null, "Original child should not be null if there are children to process");
Preconditions.checkState(newChild != null, "New child should not be null if there are children to process");
addMutateOperationsByParent(originalChild, newChild, grandchildDimensionsToProcess, ops);
}
}
}
use of com.google.api.ads.adwords.axis.v201809.cm.ProductDimension in project googleads-java-lib by googleads.
the class BaseProductDimensionComparatorTest method testIdentityComparison.
@Test
public void testIdentityComparison() {
ProductDimension dimension = createOtherProductDimension();
int result = comparator.compare(dimension, dimension);
assertEquals("Comparing a dimension to itself should return 0", 0, result);
}
Aggregations