/*
* Copyright 2011 Robert W. Vawter III <bob@vawter.org>
*
* 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 org.jsonddl.impl;
import static org.easymock.EasyMock.createStrictMock;
import static org.easymock.EasyMock.expect;
import static org.easymock.EasyMock.replay;
import static org.easymock.EasyMock.verify;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotSame;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.fail;
import java.lang.annotation.ElementType;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.jsonddl.JsonDdlObject;
import org.junit.Test;
/**
* Unit tests for {@link Protected}.
*/
public class ProtectedTest {
@Test
@SuppressWarnings({ "rawtypes", "unchecked" })
public void testJsonDdlObject() {
JsonDdlObject<?> obj = createStrictMock(JsonDdlObject.class);
JsonDdlObject.Builder builder = createStrictMock(JsonDdlObject.Builder.class);
expect(builder.build()).andReturn(obj).times(2);
replay(obj, builder);
assertSame(obj, Protected.object((Object) obj));
assertSame(obj, Protected.object((Object) builder));
assertSame(obj, Protected.object((JsonDdlObject) obj));
assertSame(obj, Protected.object((JsonDdlObject) builder));
verify(obj, builder);
}
@Test
public void testList() {
assertNull(Protected.object((List<?>) null));
assertSame(Collections.emptyList(), Protected.object(Collections.emptyList()));
assertEquals(Collections.singletonList("a").getClass(), Protected.object(Arrays.asList("b"))
.getClass());
List<String> input = Arrays.asList("a", "b", "c");
List<String> output = Protected.object(input);
assertEquals(input, output);
assertNotSame(input, output);
// Protecting a protected list should be idempotent
assertSame(output, Protected.object(output));
// But re-protecting the input list shouldn't be
assertNotSame(output, Protected.object(input));
// Mutations to input list aren't visible
input.set(0, "b");
assertEquals("a", output.get(0));
// Changes to the protected list fail
try {
output.set(0, "b");
fail();
} catch (UnsupportedOperationException expected) {}
}
@Test
public void testMap() {
assertNull(Protected.object((Map<?, ?>) null));
assertSame(Collections.emptyMap(), Protected.object(Collections.emptyMap()));
Map<String, String> singletonMap = new HashMap<String, String>();
singletonMap.put("a", "b");
assertEquals(Collections.singletonMap("a", "b").getClass(), Protected.object(singletonMap)
.getClass());
Map<String, String> input = new HashMap<String, String>();
input.put("a", "b");
input.put("c", "d");
input.put("e", "f");
Map<String, String> output = Protected.object(input);
assertEquals(input, output);
assertNotSame(input, output);
// Protecting a protected list should be idempotent
assertSame(output, Protected.object(output));
// But re-protecting the input list shouldn't be
assertNotSame(output, Protected.object(input));
// Mutations to input list aren't visible
input.put("a", "q");
assertEquals("b", output.get("a"));
// Changes to the protected list fail
try {
output.put("a", "b");
fail();
} catch (UnsupportedOperationException expected) {}
}
@Test
@SuppressWarnings("unchecked")
public void testMixedTypes() {
List<Object> input = Arrays.<Object> asList(null, true, 1, 1.0, "Hello world",
ElementType.METHOD, Arrays.asList(1, 2, 3), Collections.singletonMap("a", "b"));
List<Object> output = Protected.object(input);
assertEquals(input, output);
try {
((List<Object>) output.get(6)).set(0, 0);
fail();
} catch (UnsupportedOperationException expected) {}
try {
((Map<Object, Object>) output.get(7)).put(0, 0);
fail();
} catch (UnsupportedOperationException expected) {}
}
@Test
public void testUnknown() {
try {
Protected.object(new Object());
fail();
} catch (IllegalArgumentException expected) {}
}
}