All Downloads are FREE. Search and download functionalities are using the official Maven repository.

net.javacrumbs.smock.common.EnhancedDiff Maven / Gradle / Ivy

The newest version!
/*
 * Copyright 2009-2010 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package net.javacrumbs.smock.common;

import java.io.IOException;

import org.custommonkey.xmlunit.Diff;
import org.custommonkey.xmlunit.Difference;
import org.w3c.dom.Attr;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.xml.sax.SAXException;

/**
 * Diff that ignores "${IGNORE}" placeholder and is able to correctly compare namespace prefixes in the attribute values.
 * @author Lukas Krecan
 *
 */
public final class EnhancedDiff extends Diff {
	public EnhancedDiff(Document controlDoc, Document testDoc) {
		super(controlDoc, testDoc);
	}

	EnhancedDiff(String control, String test) throws SAXException, IOException {
		super(control, test);
	}

	public int differenceFound(Difference difference) {
		//ignore dissimilarities
		if (difference.isRecoverable())
		{
			return RETURN_ACCEPT_DIFFERENCE;
		}
		if ("${IGNORE}".equals(difference.getControlNodeDetail().getValue())) {
			return RETURN_IGNORE_DIFFERENCE_NODES_SIMILAR;
		} 
		else if (isDifferenceOnlyInAttributeValuePrefix(difference)) 
		{
			return RETURN_IGNORE_DIFFERENCE_NODES_SIMILAR;
		}
		else
		{
			return super.differenceFound(difference);
		}

	}

	/**
	 * Returns true iff difference is only in attribute value namespace prefix but the corresponding namespace is same.  
	 * @param difference
	 * @return
	 */
	protected final boolean isDifferenceOnlyInAttributeValuePrefix(Difference difference) {
		Node testNode = difference.getTestNodeDetail().getNode();
		if (testNode==null)
		{
			return false;
		}
		String testNodeValue = testNode.getNodeValue();
		
		Node controlNode = difference.getControlNodeDetail().getNode();
		String controlNodeValue = controlNode.getNodeValue();
		
		if (isAttr(testNode) && isAttr(controlNode) && (hasNsPrefix(testNodeValue) || hasNsPrefix(controlNodeValue)))
		{
			String testValueNsResolved = resolveNamespaces(testNode, testNodeValue);
			String controlValueNsResolved = resolveNamespaces(controlNode, controlNodeValue);
			
			return testValueNsResolved.equals(controlValueNsResolved);
			
		}
		return false;
	}

	/**
	 * Replaces namespace prefixes with their URLs.
	 * @param node
	 * @param value
	 * @return
	 */
	private String resolveNamespaces(Node node, String value) {
		int prefixLength = value.indexOf(':');
		if (prefixLength>=0)
		{
			String prefix = value.substring(0, prefixLength);
			String nsUri = node.lookupNamespaceURI(prefix);
			if (nsUri==null)//prefix not resolved, let's use prefix instead
			{
				nsUri = prefix;
			}
			return nsUri+value.substring(prefixLength);
		}
		else
		{
			String nsUri = node.lookupNamespaceURI(null);
			return nsUri+":"+value;
		}
	}

	private boolean hasNsPrefix(String testNodeValue) {
		return testNodeValue.contains(":");
	}

	private boolean isAttr(Node testNode) {
		return testNode instanceof Attr;
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy