This is an automated email from the ASF dual-hosted git repository.

coheigea pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/ws-neethi.git


The following commit(s) were added to refs/heads/master by this push:
     new 49a5368  Adding some unit tests
49a5368 is described below

commit 49a53687d7ad858297c32aaf40459b455ac7a324
Author: Colm O hEigeartaigh <[email protected]>
AuthorDate: Tue Apr 21 10:29:32 2026 +0100

    Adding some unit tests
---
 .../java/org/apache/neethi/PolicyModelTest.java    | 448 +++++++++++++++++++++
 .../org/apache/neethi/PolicyRegistryImplTest.java  | 164 ++++++++
 .../neethi/builders/PrimitiveAssertionTest.java    | 342 ++++++++++++++++
 .../apache/neethi/util/PolicyComparatorTest.java   | 172 +++++++-
 4 files changed, 1123 insertions(+), 3 deletions(-)

diff --git a/src/test/java/org/apache/neethi/PolicyModelTest.java 
b/src/test/java/org/apache/neethi/PolicyModelTest.java
new file mode 100644
index 0000000..568cfda
--- /dev/null
+++ b/src/test/java/org/apache/neethi/PolicyModelTest.java
@@ -0,0 +1,448 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 org.apache.neethi;
+
+import java.util.List;
+
+import javax.xml.namespace.QName;
+
+import org.apache.neethi.builders.PrimitiveAssertion;
+
+import org.junit.Test;
+
+/**
+ * Unit tests for {@link All}, {@link ExactlyOne}, {@link Policy},
+ * and the shared behaviour in {@link AbstractPolicyOperator}.
+ */
+public class PolicyModelTest extends PolicyTestCase {
+
+    private static final QName FOO = new QName("http://example.com";, "Foo");
+    private static final QName BAR = new QName("http://example.com";, "Bar");
+
+    // =========================================================
+    // All
+    // =========================================================
+
+    @Test
+    public void testAll_getType() {
+        assertEquals(Constants.TYPE_ALL, new All().getType());
+    }
+
+    @Test
+    public void testAll_newIsEmpty() {
+        assertTrue(new All().isEmpty());
+    }
+
+    @Test
+    public void testAll_addComponent_notEmpty() {
+        All all = new All();
+        all.addPolicyComponent(new PrimitiveAssertion(FOO));
+        assertFalse(all.isEmpty());
+    }
+
+    @Test
+    public void testAll_addAssertion_appearsInAssertions() {
+        All all = new All();
+        PrimitiveAssertion a = new PrimitiveAssertion(FOO);
+        all.addAssertion(a);
+
+        List<PolicyComponent> assertions = all.getAssertions();
+        assertEquals(1, assertions.size());
+        assertSame(a, assertions.get(0));
+    }
+
+    @Test
+    public void testAll_getPolicyComponents_returnsSameList() {
+        All all = new All();
+        PrimitiveAssertion a = new PrimitiveAssertion(FOO);
+        all.addPolicyComponent(a);
+
+        assertEquals(1, all.getPolicyComponents().size());
+        assertSame(a, all.getPolicyComponents().get(0));
+    }
+
+    @Test
+    public void testAll_addMultipleComponents() {
+        All all = new All();
+        all.addPolicyComponent(new PrimitiveAssertion(FOO));
+        all.addPolicyComponent(new PrimitiveAssertion(BAR));
+
+        assertEquals(2, all.getPolicyComponents().size());
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void testAll_addNullComponent_throwsIllegalArgument() {
+        new All().addPolicyComponent(null);
+    }
+
+    @Test
+    public void testAll_getFirstPolicyComponent_emptyReturnsNull() {
+        assertNull(new All().getFirstPolicyComponent());
+    }
+
+    @Test
+    public void testAll_getFirstPolicyComponent_returnsFirst() {
+        All all = new All();
+        PrimitiveAssertion first = new PrimitiveAssertion(FOO);
+        PrimitiveAssertion second = new PrimitiveAssertion(BAR);
+        all.addPolicyComponent(first);
+        all.addPolicyComponent(second);
+
+        assertSame(first, all.getFirstPolicyComponent());
+    }
+
+    @Test
+    public void testAll_addPolicyComponents_addsAll() {
+        All source = new All();
+        source.addPolicyComponent(new PrimitiveAssertion(FOO));
+        source.addPolicyComponent(new PrimitiveAssertion(BAR));
+
+        All dest = new All();
+        dest.addPolicyComponents(source.getPolicyComponents());
+
+        assertEquals(2, dest.getPolicyComponents().size());
+    }
+
+    @Test
+    public void testAll_equal_sameContent() {
+        All a1 = new All();
+        a1.addPolicyComponent(new PrimitiveAssertion(FOO));
+        All a2 = new All();
+        a2.addPolicyComponent(new PrimitiveAssertion(FOO));
+
+        assertTrue(a1.equal(a2));
+    }
+
+    @Test
+    public void testAll_equal_differentContent() {
+        All a1 = new All();
+        a1.addPolicyComponent(new PrimitiveAssertion(FOO));
+        All a2 = new All();
+        a2.addPolicyComponent(new PrimitiveAssertion(BAR));
+
+        assertFalse(a1.equal(a2));
+    }
+
+    @Test
+    public void testAll_constructorWithParent_addsItselfToParent() {
+        ExactlyOne parent = new ExactlyOne();
+        All child = new All(parent);
+
+        assertEquals(1, parent.getPolicyComponents().size());
+        assertSame(child, parent.getPolicyComponents().get(0));
+    }
+
+    // =========================================================
+    // ExactlyOne
+    // =========================================================
+
+    @Test
+    public void testExactlyOne_getType() {
+        assertEquals(Constants.TYPE_EXACTLYONE, new ExactlyOne().getType());
+    }
+
+    @Test
+    public void testExactlyOne_newIsEmpty() {
+        assertTrue(new ExactlyOne().isEmpty());
+    }
+
+    @Test
+    public void testExactlyOne_addComponent_notEmpty() {
+        ExactlyOne eo = new ExactlyOne();
+        eo.addPolicyComponent(new All());
+        assertFalse(eo.isEmpty());
+    }
+
+    @Test(expected = IllegalArgumentException.class)
+    public void testExactlyOne_addNullComponent_throwsIllegalArgument() {
+        new ExactlyOne().addPolicyComponent(null);
+    }
+
+    @Test
+    public void testExactlyOne_constructorWithParent_addsItselfToParent() {
+        Policy parent = new Policy();
+        ExactlyOne child = new ExactlyOne(parent);
+
+        assertEquals(1, parent.getPolicyComponents().size());
+        assertSame(child, parent.getPolicyComponents().get(0));
+    }
+
+    // =========================================================
+    // Policy
+    // =========================================================
+
+    @Test
+    public void testPolicy_getType() {
+        assertEquals(Constants.TYPE_POLICY, new Policy().getType());
+    }
+
+    @Test
+    public void testPolicy_defaultConstructor_noNameNoId() {
+        Policy p = new Policy();
+        assertNull(p.getName());
+        assertNull(p.getId());
+        assertNull(p.getNamespace());
+    }
+
+    @Test
+    public void testPolicy_setGetName() {
+        Policy p = new Policy();
+        p.setName("MyPolicy");
+        assertEquals("MyPolicy", p.getName());
+    }
+
+    @Test
+    public void testPolicy_setGetId() {
+        Policy p = new Policy();
+        p.setId("policy-id-1");
+        assertEquals("policy-id-1", p.getId());
+    }
+
+    @Test
+    public void testPolicy_getNamespace() {
+        Policy p = new Policy(null, "http://my.ns";);
+        assertEquals("http://my.ns";, p.getNamespace());
+    }
+
+    @Test
+    public void testPolicy_addAndGetAttribute() {
+        Policy p = new Policy();
+        QName key = new QName("http://example.com";, "customAttr");
+        p.addAttribute(key, "attrValue");
+
+        assertEquals("attrValue", p.getAttribute(key));
+    }
+
+    @Test
+    public void testPolicy_getAttribute_absentKeyReturnsNull() {
+        Policy p = new Policy();
+        assertNull(p.getAttribute(new QName("http://example.com";, "missing")));
+    }
+
+    @Test
+    public void testPolicy_getAttributes_containsAll() {
+        Policy p = new Policy();
+        QName k1 = new QName("", "k1");
+        QName k2 = new QName("", "k2");
+        p.addAttribute(k1, "v1");
+        p.addAttribute(k2, "v2");
+
+        assertEquals("v1", p.getAttributes().get(k1));
+        assertEquals("v2", p.getAttributes().get(k2));
+    }
+
+    @Test
+    public void testPolicy_registryRoundtrip() {
+        PolicyRegistryImpl reg = new PolicyRegistryImpl();
+        Policy p = new Policy(reg);
+        assertSame(reg, p.getPolicyRegistry());
+    }
+
+    @Test
+    public void testPolicy_setPolicyRegistry() {
+        Policy p = new Policy();
+        assertNull(p.getPolicyRegistry());
+
+        PolicyRegistryImpl reg = new PolicyRegistryImpl();
+        p.setPolicyRegistry(reg);
+        assertSame(reg, p.getPolicyRegistry());
+    }
+
+    // =========================================================
+    // Policy.merge
+    // =========================================================
+
+    @Test
+    public void testPolicy_merge_componentCounts() {
+        Policy p1 = new Policy();
+        p1.addPolicyComponent(new PrimitiveAssertion(FOO));
+
+        Policy p2 = new Policy();
+        p2.addPolicyComponent(new PrimitiveAssertion(BAR));
+
+        Policy merged = p1.merge(p2);
+
+        // merged has components from both p1 and p2
+        assertEquals(2, merged.getPolicyComponents().size());
+    }
+
+    @Test
+    public void testPolicy_merge_doesNotMutateOriginals() {
+        Policy p1 = new Policy();
+        p1.addPolicyComponent(new PrimitiveAssertion(FOO));
+
+        Policy p2 = new Policy();
+        p2.addPolicyComponent(new PrimitiveAssertion(BAR));
+
+        p1.merge(p2);
+
+        assertEquals(1, p1.getPolicyComponents().size());
+        assertEquals(1, p2.getPolicyComponents().size());
+    }
+
+    // =========================================================
+    // Policy.normalize (programmatic, no XML files)
+    // =========================================================
+
+    @Test
+    public void testPolicy_normalizeEmpty_resultsInEmptyAlternatives() {
+        // An empty Policy normalizes to ExactlyOne containing one empty All
+        Policy empty = new Policy();
+        Policy normalized = empty.normalize(null, true);
+
+        assertNotNull(normalized);
+        // normalized form: ExactlyOne > [one empty All]
+        List<PolicyComponent> top = normalized.getPolicyComponents();
+        assertEquals(1, top.size());
+        assertTrue(top.get(0) instanceof ExactlyOne);
+
+        ExactlyOne eo = (ExactlyOne) top.get(0);
+        assertEquals(1, eo.getPolicyComponents().size());
+        assertTrue(eo.getPolicyComponents().get(0) instanceof All);
+        assertTrue(((All) eo.getPolicyComponents().get(0)).isEmpty());
+    }
+
+    @Test
+    public void testPolicy_normalizeSingleAssertion() {
+        // Policy > ExactlyOne > All > Assertion(FOO)
+        PrimitiveAssertion assertion = new PrimitiveAssertion(FOO);
+        All all = new All();
+        all.addPolicyComponent(assertion);
+        ExactlyOne eo = new ExactlyOne();
+        eo.addPolicyComponent(all);
+        Policy p = new Policy();
+        p.addPolicyComponent(eo);
+
+        Policy normalized = p.normalize(null, true);
+
+        // The top level should still be ExactlyOne
+        assertEquals(1, normalized.getPolicyComponents().size());
+        assertTrue(normalized.getPolicyComponents().get(0) instanceof 
ExactlyOne);
+    }
+
+    @Test
+    public void testPolicy_normalize_resolvesRegistryRef() {
+        // Policy A has PolicyReference("B"). Policy B has assertion(FOO).
+        // Registry maps "B" → policyB.
+        PolicyRegistryImpl reg = new PolicyRegistryImpl();
+
+        PrimitiveAssertion foo = new PrimitiveAssertion(FOO);
+        All allB = new All();
+        allB.addPolicyComponent(foo);
+        ExactlyOne eoB = new ExactlyOne();
+        eoB.addPolicyComponent(allB);
+        Policy policyB = new Policy(reg);
+        policyB.setId("B");
+        policyB.addPolicyComponent(eoB);
+        reg.register("B", policyB);
+
+        PolicyReference refToB = new PolicyReference();
+        refToB.setURI("B");
+        All allA = new All();
+        allA.addPolicyComponent(refToB);
+        ExactlyOne eoA = new ExactlyOne();
+        eoA.addPolicyComponent(allA);
+        Policy policyA = new Policy(reg);
+        policyA.addPolicyComponent(eoA);
+
+        Policy normalized = policyA.normalize(reg, true);
+
+        assertNotNull(normalized);
+        // Should have resolved without throwing
+        assertFalse(normalized.getPolicyComponents().isEmpty());
+    }
+
+    @Test
+    public void testPolicy_normalize_unresolvableRef_throws() {
+        PolicyRegistryImpl reg = new PolicyRegistryImpl();
+
+        PolicyReference ref = new PolicyReference();
+        ref.setURI("NoSuchPolicy");
+        All all = new All();
+        all.addPolicyComponent(ref);
+        ExactlyOne eo = new ExactlyOne();
+        eo.addPolicyComponent(all);
+        Policy p = new Policy(reg);
+        p.addPolicyComponent(eo);
+
+        try {
+            p.normalize(reg, true);
+            fail("Expected RuntimeException for unresolvable PolicyReference");
+        } catch (RuntimeException e) {
+            assertTrue(e.getMessage().contains("can't be resolved"));
+        }
+    }
+
+    @Test
+    public void testPolicy_normalize_preservesNameAndId() {
+        Policy p = new Policy();
+        p.setName("MyPol");
+        p.setId("my-id");
+
+        Policy normalized = p.normalize(null, false);
+
+        assertEquals("MyPol", normalized.getName());
+        assertEquals("my-id", normalized.getId());
+    }
+
+    // =========================================================
+    // PolicyReference
+    // =========================================================
+
+    @Test
+    public void testPolicyReference_getType() {
+        assertEquals(Constants.TYPE_POLICY_REF, new 
PolicyReference().getType());
+    }
+
+    @Test
+    public void testPolicyReference_setGetURI() {
+        PolicyReference ref = new PolicyReference();
+        ref.setURI("#MyPolicy");
+        assertEquals("#MyPolicy", ref.getURI());
+    }
+
+    @Test
+    public void testPolicyReference_equal_sameURI() {
+        PolicyReference r1 = new PolicyReference();
+        r1.setURI("#SomePol");
+        PolicyReference r2 = new PolicyReference();
+        r2.setURI("#SomePol");
+
+        assertTrue(r1.equal(r2));
+    }
+
+    @Test
+    public void testPolicyReference_equal_differentURI() {
+        PolicyReference r1 = new PolicyReference();
+        r1.setURI("#Pol1");
+        PolicyReference r2 = new PolicyReference();
+        r2.setURI("#Pol2");
+
+        assertFalse(r1.equal(r2));
+    }
+
+    @Test
+    public void testPolicyReference_equal_wrongType() {
+        PolicyReference ref = new PolicyReference();
+        ref.setURI("#Pol");
+
+        assertFalse(ref.equal(new PrimitiveAssertion(FOO)));
+    }
+}
diff --git a/src/test/java/org/apache/neethi/PolicyRegistryImplTest.java 
b/src/test/java/org/apache/neethi/PolicyRegistryImplTest.java
new file mode 100644
index 0000000..7c333ef
--- /dev/null
+++ b/src/test/java/org/apache/neethi/PolicyRegistryImplTest.java
@@ -0,0 +1,164 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 org.apache.neethi;
+
+import org.junit.Test;
+
+/**
+ * Unit tests for {@link PolicyRegistryImpl}.
+ */
+public class PolicyRegistryImplTest extends PolicyTestCase {
+
+    // --- register / lookup ---
+
+    @Test
+    public void testLookupMissingKey_returnsNull() {
+        PolicyRegistryImpl reg = new PolicyRegistryImpl();
+        assertNull(reg.lookup("nonExistent"));
+    }
+
+    @Test
+    public void testRegisterAndLookup() {
+        PolicyRegistryImpl reg = new PolicyRegistryImpl();
+        Policy policy = new Policy();
+        policy.setId("p1");
+
+        reg.register("p1", policy);
+
+        assertSame(policy, reg.lookup("p1"));
+    }
+
+    @Test
+    public void testRegisterOverwrite_replacesOldValue() {
+        PolicyRegistryImpl reg = new PolicyRegistryImpl();
+        Policy first = new Policy();
+        first.setId("key");
+        Policy second = new Policy();
+        second.setId("key");
+
+        reg.register("key", first);
+        reg.register("key", second);
+
+        assertSame(second, reg.lookup("key"));
+    }
+
+    @Test
+    public void testRemove_makesLookupReturnNull() {
+        PolicyRegistryImpl reg = new PolicyRegistryImpl();
+        Policy policy = new Policy();
+        reg.register("p", policy);
+
+        reg.remove("p");
+
+        assertNull(reg.lookup("p"));
+    }
+
+    @Test
+    public void testRemove_nonExistentKey_doesNotThrow() {
+        PolicyRegistryImpl reg = new PolicyRegistryImpl();
+        // must not throw
+        reg.remove("ghost");
+    }
+
+    // --- parent registry delegation ---
+
+    @Test
+    public void testParentDelegation_childMissLookesInParent() {
+        PolicyRegistryImpl parent = new PolicyRegistryImpl();
+        Policy policy = new Policy();
+        parent.register("fromParent", policy);
+
+        PolicyRegistryImpl child = new PolicyRegistryImpl(parent);
+
+        assertSame(policy, child.lookup("fromParent"));
+    }
+
+    @Test
+    public void testChildShadowsParent() {
+        Policy parentPolicy = new Policy();
+        Policy childPolicy = new Policy();
+
+        PolicyRegistryImpl parent = new PolicyRegistryImpl();
+        parent.register("key", parentPolicy);
+
+        PolicyRegistryImpl child = new PolicyRegistryImpl(parent);
+        child.register("key", childPolicy);
+
+        assertSame(childPolicy, child.lookup("key"));
+        assertSame(parentPolicy, parent.lookup("key"));
+    }
+
+    @Test
+    public void testParentNotConsulted_whenChildHasKey() {
+        Policy parentPolicy = new Policy();
+        parentPolicy.setId("parent");
+
+        PolicyRegistryImpl parent = new PolicyRegistryImpl();
+        parent.register("key", parentPolicy);
+
+        Policy childPolicy = new Policy();
+        childPolicy.setId("child");
+
+        PolicyRegistryImpl child = new PolicyRegistryImpl(parent);
+        child.register("key", childPolicy);
+
+        assertEquals("child", child.lookup("key").getId());
+    }
+
+    @Test
+    public void testNoParent_missingKeyReturnsNull() {
+        PolicyRegistryImpl child = new PolicyRegistryImpl();
+        assertNull(child.lookup("missing"));
+    }
+
+    // --- setParent / getParent ---
+
+    @Test
+    public void testSetAndGetParent() {
+        PolicyRegistryImpl parent = new PolicyRegistryImpl();
+        PolicyRegistryImpl child = new PolicyRegistryImpl();
+
+        assertNull(child.getParent());
+
+        child.setParent(parent);
+
+        assertSame(parent, child.getParent());
+    }
+
+    @Test
+    public void testSetParent_enablesDelegation() {
+        PolicyRegistryImpl parent = new PolicyRegistryImpl();
+        Policy policy = new Policy();
+        parent.register("p", policy);
+
+        PolicyRegistryImpl child = new PolicyRegistryImpl();
+        child.setParent(parent);
+
+        assertSame(policy, child.lookup("p"));
+    }
+
+    @Test
+    public void testConstructorWithParent_setsParentCorrectly() {
+        PolicyRegistryImpl parent = new PolicyRegistryImpl();
+        PolicyRegistryImpl child = new PolicyRegistryImpl(parent);
+
+        assertSame(parent, child.getParent());
+    }
+}
diff --git 
a/src/test/java/org/apache/neethi/builders/PrimitiveAssertionTest.java 
b/src/test/java/org/apache/neethi/builders/PrimitiveAssertionTest.java
new file mode 100644
index 0000000..b9590e5
--- /dev/null
+++ b/src/test/java/org/apache/neethi/builders/PrimitiveAssertionTest.java
@@ -0,0 +1,342 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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 org.apache.neethi.builders;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.xml.namespace.QName;
+
+import org.apache.neethi.Constants;
+import org.apache.neethi.ExactlyOne;
+import org.apache.neethi.Policy;
+import org.apache.neethi.PolicyComponent;
+import org.apache.neethi.PolicyTestCase;
+
+import org.junit.Test;
+
+/**
+ * Unit tests for {@link PrimitiveAssertion}.
+ */
+public class PrimitiveAssertionTest extends PolicyTestCase {
+
+    private static final QName FOO = new QName("http://example.com";, "Foo");
+    private static final QName BAR = new QName("http://example.com";, "Bar");
+    private static final QName ATTR = new QName("http://example.com";, 
"myAttr");
+
+    // =========================================================
+    // Constructors
+    // =========================================================
+
+    @Test
+    public void testDefaultConstructor_nullName() {
+        PrimitiveAssertion pa = new PrimitiveAssertion();
+        assertNull(pa.getName());
+    }
+
+    @Test
+    public void testQNameConstructor_nameSet() {
+        PrimitiveAssertion pa = new PrimitiveAssertion(FOO);
+        assertEquals(FOO, pa.getName());
+    }
+
+    @Test
+    public void testOptionalConstructor_optionalSet() {
+        PrimitiveAssertion pa = new PrimitiveAssertion(FOO, true);
+        assertTrue(pa.isOptional());
+    }
+
+    @Test
+    public void testIgnorableConstructor_ignorableSet() {
+        PrimitiveAssertion pa = new PrimitiveAssertion(FOO, false, true);
+        assertTrue(pa.isIgnorable());
+    }
+
+    @Test
+    public void testFullConstructor_attributesAndText() {
+        Map<QName, String> atts = new HashMap<QName, String>();
+        atts.put(ATTR, "value");
+
+        PrimitiveAssertion pa = new PrimitiveAssertion(FOO, false, false, 
atts, "text");
+
+        assertEquals("value", pa.getAttribute(ATTR));
+        assertEquals("text", pa.getTextValue());
+    }
+
+    // =========================================================
+    // Defaults
+    // =========================================================
+
+    @Test
+    public void testOptional_falseByDefault() {
+        assertFalse(new PrimitiveAssertion(FOO).isOptional());
+    }
+
+    @Test
+    public void testIgnorable_falseByDefault() {
+        assertFalse(new PrimitiveAssertion(FOO).isIgnorable());
+    }
+
+    @Test
+    public void testTextValue_nullByDefault() {
+        assertNull(new PrimitiveAssertion(FOO).getTextValue());
+    }
+
+    @Test
+    public void testGetAttributes_emptyMapByDefault() {
+        assertTrue(new PrimitiveAssertion(FOO).getAttributes().isEmpty());
+    }
+
+    @Test
+    public void testGetAttribute_absentReturnsNull() {
+        assertNull(new PrimitiveAssertion(FOO).getAttribute(ATTR));
+    }
+
+    // =========================================================
+    // Setters
+    // =========================================================
+
+    @Test
+    public void testSetOptional_roundtrip() {
+        PrimitiveAssertion pa = new PrimitiveAssertion(FOO);
+        pa.setOptional(true);
+        assertTrue(pa.isOptional());
+        pa.setOptional(false);
+        assertFalse(pa.isOptional());
+    }
+
+    @Test
+    public void testSetIgnorable_roundtrip() {
+        PrimitiveAssertion pa = new PrimitiveAssertion(FOO);
+        pa.setIgnorable(true);
+        assertTrue(pa.isIgnorable());
+    }
+
+    @Test
+    public void testSetTextValue_roundtrip() {
+        PrimitiveAssertion pa = new PrimitiveAssertion(FOO);
+        pa.setTextValue("hello");
+        assertEquals("hello", pa.getTextValue());
+    }
+
+    @Test
+    public void testSetName_roundtrip() {
+        PrimitiveAssertion pa = new PrimitiveAssertion();
+        pa.setName(FOO);
+        assertEquals(FOO, pa.getName());
+    }
+
+    // =========================================================
+    // addAttribute / addAttributes / getAttribute
+    // =========================================================
+
+    @Test
+    public void testAddAttribute_roundtrip() {
+        PrimitiveAssertion pa = new PrimitiveAssertion(FOO);
+        pa.addAttribute(ATTR, "42");
+        assertEquals("42", pa.getAttribute(ATTR));
+    }
+
+    @Test
+    public void testAddAttributes_mergesAll() {
+        Map<QName, String> atts = new HashMap<QName, String>();
+        QName k1 = new QName("http://ex.com";, "k1");
+        QName k2 = new QName("http://ex.com";, "k2");
+        atts.put(k1, "v1");
+        atts.put(k2, "v2");
+
+        PrimitiveAssertion pa = new PrimitiveAssertion(FOO);
+        pa.addAttributes(atts);
+
+        assertEquals("v1", pa.getAttribute(k1));
+        assertEquals("v2", pa.getAttribute(k2));
+    }
+
+    @Test
+    public void testGetAttributes_returnsCopy() {
+        PrimitiveAssertion pa = new PrimitiveAssertion(FOO);
+        pa.addAttribute(ATTR, "original");
+
+        Map<QName, String> copy = pa.getAttributes();
+        copy.put(ATTR, "mutated");
+
+        // The internal map must not be affected
+        assertEquals("original", pa.getAttribute(ATTR));
+    }
+
+    // =========================================================
+    // getType
+    // =========================================================
+
+    @Test
+    public void testGetType() {
+        assertEquals(Constants.TYPE_ASSERTION, new 
PrimitiveAssertion(FOO).getType());
+    }
+
+    // =========================================================
+    // equals / hashCode
+    // =========================================================
+
+    @Test
+    public void testEquals_reflexive() {
+        PrimitiveAssertion pa = new PrimitiveAssertion(FOO);
+        assertEquals(pa, pa);
+    }
+
+    @Test
+    public void testEquals_symmetric() {
+        PrimitiveAssertion a = new PrimitiveAssertion(FOO);
+        PrimitiveAssertion b = new PrimitiveAssertion(FOO);
+        assertEquals(a, b);
+        assertEquals(b, a);
+    }
+
+    @Test
+    public void testEquals_differentName() {
+        PrimitiveAssertion a = new PrimitiveAssertion(FOO);
+        PrimitiveAssertion b = new PrimitiveAssertion(BAR);
+        assertFalse(a.equals(b));
+    }
+
+    @Test
+    public void testEquals_differentOptional() {
+        PrimitiveAssertion a = new PrimitiveAssertion(FOO, true);
+        PrimitiveAssertion b = new PrimitiveAssertion(FOO, false);
+        assertFalse(a.equals(b));
+    }
+
+    @Test
+    public void testEquals_differentIgnorable() {
+        PrimitiveAssertion a = new PrimitiveAssertion(FOO, false, true);
+        PrimitiveAssertion b = new PrimitiveAssertion(FOO, false, false);
+        assertFalse(a.equals(b));
+    }
+
+    @Test
+    public void testEquals_differentTextValue() {
+        PrimitiveAssertion a = new PrimitiveAssertion(FOO, false, false, null, 
"text1");
+        PrimitiveAssertion b = new PrimitiveAssertion(FOO, false, false, null, 
"text2");
+        assertFalse(a.equals(b));
+    }
+
+    @Test
+    public void testEquals_differentAttributes() {
+        Map<QName, String> atts1 = new HashMap<QName, String>();
+        atts1.put(ATTR, "A");
+        Map<QName, String> atts2 = new HashMap<QName, String>();
+        atts2.put(ATTR, "B");
+
+        PrimitiveAssertion a = new PrimitiveAssertion(FOO, false, false, 
atts1);
+        PrimitiveAssertion b = new PrimitiveAssertion(FOO, false, false, 
atts2);
+        assertFalse(a.equals(b));
+    }
+
+    @Test
+    public void testEquals_notPrimitiveAssertion() {
+        PrimitiveAssertion pa = new PrimitiveAssertion(FOO);
+        assertFalse(pa.equals("not an assertion"));
+        assertFalse(pa.equals(null));
+    }
+
+    @Test
+    public void testHashCode_equalObjectsSameHash() {
+        PrimitiveAssertion a = new PrimitiveAssertion(FOO, false, false, null, 
"v");
+        PrimitiveAssertion b = new PrimitiveAssertion(FOO, false, false, null, 
"v");
+        assertEquals(a.hashCode(), b.hashCode());
+    }
+
+    @Test
+    public void testHashCode_consistent() {
+        PrimitiveAssertion pa = new PrimitiveAssertion(FOO);
+        int h1 = pa.hashCode();
+        int h2 = pa.hashCode();
+        assertEquals(h1, h2);
+    }
+
+    // =========================================================
+    // equal(PolicyComponent) — the neethi-specific method
+    // =========================================================
+
+    @Test
+    public void testEqualPolicyComponent_sameAssertion() {
+        PrimitiveAssertion a = new PrimitiveAssertion(FOO);
+        PrimitiveAssertion b = new PrimitiveAssertion(FOO);
+        assertTrue(a.equal(b));
+    }
+
+    @Test
+    public void testEqualPolicyComponent_differentAssertion() {
+        PrimitiveAssertion a = new PrimitiveAssertion(FOO);
+        PrimitiveAssertion b = new PrimitiveAssertion(BAR);
+        assertFalse(a.equal(b));
+    }
+
+    @Test
+    public void testEqualPolicyComponent_nonAssertion() {
+        PrimitiveAssertion pa = new PrimitiveAssertion(FOO);
+        assertFalse(pa.equal(new ExactlyOne()));
+    }
+
+    @Test
+    public void testEqualPolicyComponent_reflexive() {
+        PrimitiveAssertion pa = new PrimitiveAssertion(FOO);
+        assertTrue(pa.equal(pa));
+    }
+
+    // =========================================================
+    // normalize()
+    // =========================================================
+
+    @Test
+    public void testNormalize_nonOptional_returnsSelf() {
+        PrimitiveAssertion pa = new PrimitiveAssertion(FOO, false);
+        PolicyComponent normalized = pa.normalize();
+
+        // non-optional assertion normalizes to a clone of itself 
(TYPE_ASSERTION)
+        assertEquals(Constants.TYPE_ASSERTION, normalized.getType());
+    }
+
+    @Test
+    public void testNormalize_optional_returnsPolicy() {
+        PrimitiveAssertion pa = new PrimitiveAssertion(FOO, true);
+        PolicyComponent normalized = pa.normalize();
+
+        // optional assertion normalizes to: Policy > ExactlyOne > 
[All>Assertion, All]
+        assertEquals(Constants.TYPE_POLICY, normalized.getType());
+        Policy p = (Policy) normalized;
+        assertEquals(1, p.getPolicyComponents().size());
+        assertTrue(p.getPolicyComponents().get(0) instanceof ExactlyOne);
+
+        ExactlyOne eo = (ExactlyOne) p.getPolicyComponents().get(0);
+        assertEquals(2, eo.getPolicyComponents().size()); // two alternatives
+    }
+
+    // =========================================================
+    // toString
+    // =========================================================
+
+    @Test
+    public void testToString_containsName() {
+        PrimitiveAssertion pa = new PrimitiveAssertion(FOO);
+        String str = pa.toString();
+        assertNotNull(str);
+        assertTrue(str.contains("Foo"));
+    }
+}
diff --git a/src/test/java/org/apache/neethi/util/PolicyComparatorTest.java 
b/src/test/java/org/apache/neethi/util/PolicyComparatorTest.java
index 86356f4..14d4594 100644
--- a/src/test/java/org/apache/neethi/util/PolicyComparatorTest.java
+++ b/src/test/java/org/apache/neethi/util/PolicyComparatorTest.java
@@ -19,21 +19,187 @@
 
 package org.apache.neethi.util;
 
+import javax.xml.namespace.QName;
+
+import org.apache.neethi.All;
+import org.apache.neethi.ExactlyOne;
 import org.apache.neethi.Policy;
+import org.apache.neethi.PolicyComponent;
 import org.apache.neethi.PolicyTestCase;
+import org.apache.neethi.builders.PrimitiveAssertion;
+
 import org.junit.Test;
 
 public class PolicyComparatorTest extends PolicyTestCase {
 
+    // --- Policy-level comparisons ---
+
     @Test
-    public void testPolicyComparison1() {
+    public void testPolicyComparison_differentNames() {
         Policy policy1 = new Policy();
         policy1.setName("Name_1");
         Policy policy2 = new Policy();
         policy2.setName("Name_2");
 
-        boolean res = PolicyComparator.compare(policy1, policy2);
-        assertEquals(false, res);
+        assertFalse(PolicyComparator.compare(policy1, policy2));
+    }
+
+    @Test
+    public void testPolicyComparison_sameNames() {
+        Policy policy1 = new Policy();
+        policy1.setName("SameName");
+        Policy policy2 = new Policy();
+        policy2.setName("SameName");
+
+        assertTrue(PolicyComparator.compare(policy1, policy2));
+    }
+
+    @Test
+    public void testPolicyComparison_bothNullName() {
+        // Neither policy has a Name → names equal; no Id either → equal
+        Policy policy1 = new Policy();
+        Policy policy2 = new Policy();
+
+        assertTrue(PolicyComparator.compare(policy1, policy2));
+    }
+
+    @Test
+    public void testPolicyComparison_oneNullOneName() {
+        Policy policy1 = new Policy();
+        policy1.setName("SomeName");
+        Policy policy2 = new Policy();
+
+        assertFalse(PolicyComparator.compare(policy1, policy2));
+        assertFalse(PolicyComparator.compare(policy2, policy1));
     }
 
+    @Test
+    public void testPolicyComparison_differentIds() {
+        Policy policy1 = new Policy();
+        policy1.setId("id-1");
+        Policy policy2 = new Policy();
+        policy2.setId("id-2");
+
+        assertFalse(PolicyComparator.compare(policy1, policy2));
+    }
+
+    @Test
+    public void testPolicyComparison_sameIds() {
+        Policy policy1 = new Policy();
+        policy1.setId("shared-id");
+        Policy policy2 = new Policy();
+        policy2.setId("shared-id");
+
+        assertTrue(PolicyComparator.compare(policy1, policy2));
+    }
+
+    @Test
+    public void testPolicyComparison_oneNullId() {
+        Policy policy1 = new Policy();
+        policy1.setId("some-id");
+        Policy policy2 = new Policy();
+
+        assertFalse(PolicyComparator.compare(policy1, policy2));
+        assertFalse(PolicyComparator.compare(policy2, policy1));
+    }
+
+    @Test
+    public void testPolicyComparison_differentNamespaces() {
+        Policy policy1 = new Policy(null, "http://ns1.example.com";);
+        Policy policy2 = new Policy(null, "http://ns2.example.com";);
+
+        assertFalse(PolicyComparator.compare(policy1, policy2));
+    }
+
+    @Test
+    public void testPolicyComparison_sameNamespaceAndName() {
+        Policy policy1 = new Policy(null, "http://example.com/ns";);
+        policy1.setName("Pol");
+        Policy policy2 = new Policy(null, "http://example.com/ns";);
+        policy2.setName("Pol");
+
+        assertTrue(PolicyComparator.compare(policy1, policy2));
+    }
+
+    // --- All comparisons ---
+
+    @Test
+    public void testCompareAll_bothEmpty() {
+        assertTrue(PolicyComparator.compare((PolicyComponent) new All(), new 
All()));
+    }
+
+    @Test
+    public void testCompareAll_withMatchingComponents() {
+        QName qn = new QName("http://example.com";, "Foo");
+        All a1 = new All();
+        a1.addPolicyComponent(new PrimitiveAssertion(qn));
+        All a2 = new All();
+        a2.addPolicyComponent(new PrimitiveAssertion(qn));
+
+        assertTrue(PolicyComparator.compare((PolicyComponent) a1, a2));
+    }
+
+    @Test
+    public void testCompareAll_differentComponents() {
+        All a1 = new All();
+        a1.addPolicyComponent(new PrimitiveAssertion(new 
QName("http://ex.com";, "A")));
+        All a2 = new All();
+        a2.addPolicyComponent(new PrimitiveAssertion(new 
QName("http://ex.com";, "B")));
+
+        assertFalse(PolicyComparator.compare((PolicyComponent) a1, a2));
+    }
+
+    @Test
+    public void testCompareAll_differentSizes() {
+        QName qn = new QName("http://ex.com";, "X");
+        All a1 = new All();
+        a1.addPolicyComponent(new PrimitiveAssertion(qn));
+        All a2 = new All();
+
+        assertFalse(PolicyComparator.compare((PolicyComponent) a1, a2));
+    }
+
+    // --- ExactlyOne comparisons ---
+
+    @Test
+    public void testCompareExactlyOne_bothEmpty() {
+        assertTrue(PolicyComparator.compare((PolicyComponent) new 
ExactlyOne(), new ExactlyOne()));
+    }
+
+    @Test
+    public void testCompareExactlyOne_withMatchingAll() {
+        ExactlyOne e1 = new ExactlyOne();
+        e1.addPolicyComponent(new All());
+        ExactlyOne e2 = new ExactlyOne();
+        e2.addPolicyComponent(new All());
+
+        assertTrue(PolicyComparator.compare((PolicyComponent) e1, e2));
+    }
+
+    // --- Assertion comparisons ---
+
+    @Test
+    public void testCompareAssertions_sameName() {
+        QName qn = new QName("http://ex.com";, "MyAssertion");
+        PrimitiveAssertion a1 = new PrimitiveAssertion(qn);
+        PrimitiveAssertion a2 = new PrimitiveAssertion(qn);
+
+        assertTrue(PolicyComparator.compare((PolicyComponent) a1, a2));
+    }
+
+    @Test
+    public void testCompareAssertions_differentName() {
+        PrimitiveAssertion a1 = new PrimitiveAssertion(new 
QName("http://ex.com";, "Foo"));
+        PrimitiveAssertion a2 = new PrimitiveAssertion(new 
QName("http://ex.com";, "Bar"));
+
+        assertFalse(PolicyComparator.compare((PolicyComponent) a1, a2));
+    }
+
+    // --- Mixed type comparisons ---
+
+    @Test
+    public void testCompare_differentTypes() {
+        // All vs ExactlyOne — getClass() differs → false
+        assertFalse(PolicyComparator.compare((PolicyComponent) new All(), new 
ExactlyOne()));
+    }
 }
\ No newline at end of file


Reply via email to