package com.lordofthejars.nosqlunit.redis.parser; import static org.hamcrest.collection.IsMapContaining.hasValue; import static org.hamcrest.collection.IsMapContaining.hasKey; import static org.hamcrest.CoreMatchers.is; import static org.junit.Assert.assertThat; import static org.mockito.Matchers.eq; import static org.mockito.Mockito.verify; import java.io.ByteArrayInputStream; import java.util.ArrayList; import java.util.Collection; import java.util.List; import java.util.Map; import java.util.Set; import org.junit.Before; import org.junit.Test; import org.mockito.ArgumentCaptor; import org.mockito.Mock; import org.mockito.MockitoAnnotations; import redis.clients.jedis.Jedis; public class WhenRedisDataIsImported { @Mock private Jedis jedis; @Before public void setUp() { MockitoAnnotations.initMocks(this); } private static final String DATA_WITH_SIMPLE_TYPES = "{\n" + "\"data\":[\n" + " {\"simple\": [\n" + " {\n" + " \"key\":\"key1\", \n" + " \"value\":\"value\"\n" + " },\n" + " {\n" + " \"key\":\"key2\", \n" + " \"value\":1.1\n" + " }\n" + " ]\n" + " }\n" + " ]\n" + "}"; private static final String DATA_WITH_SIMPLE_TYPES_AND_TTL = "{\n" + "\"data\":[\n" + " {\"simple\": [\n" + " {\n" + " \"key\":\"key1\", \n" + " \"value\":\"value\"\n" + " \"expireSeconds\":10\n" + " },\n" + " {\n" + " \"key\":\"key2\", \n" + " \"value\":1.1\n" + " }\n" + " ]\n" + " }\n" + " ]\n" + "}"; private static final String DATA_WITH_LIST_TYPES = "{\n" + "\"data\":[\n" + " \n" + " {\"list\": [" + " {\n" + " \"key\":\"key1\",\n" + " \"values\":[\n" + " {\"value\":\"value1\"},\n" + " {\"value\":\"value2\"}\n" + " ]\n" + " },\n" + " {\n" + " \"key\":\"key2\",\n" + " \"values\":[\n" + " {\"value\":\"value3\"},\n" + " {\"value\":\"value4\"}\n" + " ]\n" + " }\n" + " ]\n" + " }\n" + "]\n" + "}"; private static final String DATA_WITH_LIST_TYPES_WITH_TTL = "{\n" + "\"data\":[\n" + " \n" + " {\"list\": [" + " {\n" + " \"key\":\"key1\",\n" + " \"expireSeconds\":10\n" + " \"values\":[\n" + " {\"value\":\"value1\"},\n" + " {\"value\":\"value2\"}\n" + " ]\n" + " },\n" + " {\n" + " \"key\":\"key2\",\n" + " \"values\":[\n" + " {\"value\":\"value3\"},\n" + " {\"value\":\"value4\"}\n" + " ]\n" + " }\n" + " ]\n" + " }\n" + "]\n" + "}"; private static final String DATA_WITH_SET_TYPES = "{\n" + "\"data\":[\n" + " \n" + " {\"set\": [" + " {\n" + " \"key\":\"key1\",\n" + " \"values\":[\n" + " {\"value\":\"value1\"},\n" + " {\"value\":\"value2\"}\n" + " ]\n" + " },\n" + " {\n" + " \"key\":\"key2\",\n" + " \"values\":[\n" + " {\"value\":\"value3\"},\n" + " {\"value\":\"value4\"}\n" + " ]\n" + " }\n" + " ]\n" + " }\n" + "]\n" + "}"; private static final String DATA_WITH_SET_TYPES_WITH_TTL = "{\n" + "\"data\":[\n" + " \n" + " {\"set\": [" + " {\n" + " \"key\":\"key1\",\n" + " \"expireSeconds\":10\n" + " \"values\":[\n" + " {\"value\":\"value1\"},\n" + " {\"value\":\"value2\"}\n" + " ]\n" + " },\n" + " {\n" + " \"key\":\"key2\",\n" + " \"values\":[\n" + " {\"value\":\"value3\"},\n" + " {\"value\":\"value4\"}\n" + " ]\n" + " }\n" + " ]\n" + " }\n" + "]\n" + "}"; private static final String DATA_WITH_SORTSET_TYPES = "{\n" + "\"data\":[ \n" + " {\"sortset\": [{\n" + " \"key\":\"key\",\n" + " \"values\":[\n" + " {\"score\":1, \"value\":\"value1\" },{\"score\":2, \"value\":\"value2\" }]\n" + " }]\n" + " }\n" + "]\n" + "}"; private static final String DATA_WITH_SORTSET_TYPES_WITH_TTL = "{\n" + "\"data\":[ \n" + " {\"sortset\": [{\n" + " \"key\":\"key\",\n" + " \"expireAtSeconds\":1293840000\n" + " \"values\":[\n" + " {\"score\":1, \"value\":\"value1\" },{\"score\":2, \"value\":\"value2\" }]\n" + " }]\n" + " }\n" + "]\n" + "}"; private static final String DATA_WITH_HASH_TYPES = "{\n" + "\"data\":[\n" + " {\"hash\": [\n" + " {\n" + " \"key\":\"user\",\n" + " \"values\":[\n" + " {\"field\":\"name\", \"value\":\"alex\"},\n" + " {\"field\":\"password\", \"value\":\"alex\"}\n" + " ]\n" + " }\n" + " ]\n" + " }\n" + " ]\n" + "}"; private static final String DATA_WITH_HASH_TYPES_WITH_TTL = "{\n" + "\"data\":[\n" + " {\"hash\": [\n" + " {\n" + " \"key\":\"user\",\n" + " \"expireAtSeconds\":1293840000\n" + " \"values\":[\n" + " {\"field\":\"name\", \"value\":\"alex\"},\n" + " {\"field\":\"password\", \"value\":\"alex\"}\n" + " ]\n" + " }\n" + " ]\n" + " }\n" + " ]\n" + "}"; @Test public void simple_types_should_be_set_into_redis() { DataReader dataReader = new DataReader(jedis); dataReader.read(new ByteArrayInputStream(DATA_WITH_SIMPLE_TYPES.getBytes())); verify(jedis).set("key1".getBytes(), "value".getBytes()); verify(jedis).set("key2".getBytes(), new byte[]{new Double(1.1).byteValue()}); } @Test public void simple_types_should_be_set_into_redis_with_TTL() { DataReader dataReader = new DataReader(jedis); dataReader.read(new ByteArrayInputStream(DATA_WITH_SIMPLE_TYPES_AND_TTL.getBytes())); verify(jedis).expire("key1".getBytes(), 10); verify(jedis).set("key1".getBytes(), "value".getBytes()); verify(jedis).set("key2".getBytes(), new byte[]{new Double(1.1).byteValue()}); } @Test public void list_types_should_be_rear_pushed_into_redis() { DataReader dataReader = new DataReader(jedis); dataReader.read(new ByteArrayInputStream(DATA_WITH_LIST_TYPES.getBytes())); List<byte[]> expectedValuesKey1 = convertToByteArray("value1","value2"); verify(jedis).rpush("key1".getBytes(), expectedValuesKey1.toArray(new byte[expectedValuesKey1.size()][])); List<byte[]> expectedValuesKey2 = convertToByteArray("value3","value4"); verify(jedis).rpush("key2".getBytes(), expectedValuesKey2.toArray(new byte[expectedValuesKey1.size()][])); } @Test public void set_types_should_be_added_into_redis() { DataReader dataReader = new DataReader(jedis); dataReader.read(new ByteArrayInputStream(DATA_WITH_SET_TYPES.getBytes())); List<byte[]> expectedValuesKey1 = convertToByteArray("value1","value2"); verify(jedis).sadd("key1".getBytes(), expectedValuesKey1.toArray(new byte[expectedValuesKey1.size()][])); List<byte[]> expectedValuesKey2 = convertToByteArray("value3","value4"); verify(jedis).sadd("key2".getBytes(), expectedValuesKey2.toArray(new byte[expectedValuesKey1.size()][])); } @Test public void set_types_should_be_added_into_redis_with_TTL() { DataReader dataReader = new DataReader(jedis); dataReader.read(new ByteArrayInputStream(DATA_WITH_SET_TYPES_WITH_TTL.getBytes())); verify(jedis).expire("key1".getBytes(), 10); List<byte[]> expectedValuesKey1 = convertToByteArray("value1","value2"); verify(jedis).sadd("key1".getBytes(), expectedValuesKey1.toArray(new byte[expectedValuesKey1.size()][])); List<byte[]> expectedValuesKey2 = convertToByteArray("value3","value4"); verify(jedis).sadd("key2".getBytes(), expectedValuesKey2.toArray(new byte[expectedValuesKey1.size()][])); } @Test public void list_types_should_be_rear_pushed_into_redis_with_TTL() { DataReader dataReader = new DataReader(jedis); dataReader.read(new ByteArrayInputStream(DATA_WITH_LIST_TYPES_WITH_TTL.getBytes())); verify(jedis).expire("key1".getBytes(), 10); List<byte[]> expectedValuesKey1 = convertToByteArray("value1","value2"); verify(jedis).rpush("key1".getBytes(), expectedValuesKey1.toArray(new byte[expectedValuesKey1.size()][])); List<byte[]> expectedValuesKey2 = convertToByteArray("value3","value4"); verify(jedis).rpush("key2".getBytes(), expectedValuesKey2.toArray(new byte[expectedValuesKey1.size()][])); } @Test public void hash_types_should_be_added_into_redis() { DataReader dataReader = new DataReader(jedis); dataReader.read(new ByteArrayInputStream(DATA_WITH_HASH_TYPES.getBytes())); ArgumentCaptor<Map> argument = ArgumentCaptor.forClass(Map.class); verify(jedis).hmset(eq("user".getBytes()), argument.capture()); Map<byte[], byte[]> fieldsMap = argument.getValue(); assertThat(fieldsMap, hasKey("name".getBytes())); assertThat(fieldsMap, hasKey("password".getBytes())); assertThat(fieldsMap, hasValue("alex".getBytes())); } @Test public void hash_types_should_be_added_into_redis_with_TTL() { DataReader dataReader = new DataReader(jedis); dataReader.read(new ByteArrayInputStream(DATA_WITH_HASH_TYPES_WITH_TTL.getBytes())); verify(jedis).expireAt("user".getBytes(), 1293840000); ArgumentCaptor<Map> argument = ArgumentCaptor.forClass(Map.class); verify(jedis).hmset(eq("user".getBytes()), argument.capture()); Map<byte[], byte[]> fieldsMap = argument.getValue(); assertThat(fieldsMap, hasKey("name".getBytes())); assertThat(fieldsMap, hasKey("password".getBytes())); assertThat(fieldsMap, hasValue("alex".getBytes())); } @Test public void sortset_types_should_be_added_into_redis() { DataReader dataReader = new DataReader(jedis); dataReader.read(new ByteArrayInputStream(DATA_WITH_SORTSET_TYPES.getBytes())); ArgumentCaptor<Map> argument = ArgumentCaptor.forClass(Map.class); verify(jedis).zadd(eq("key".getBytes()), argument.capture()); byte[] objectValue1 = (byte[]) firstKeyForValue(argument.getValue(), 1.0); assertThat(objectValue1, is("value1".getBytes())); byte[] objectValue2 = (byte[]) firstKeyForValue(argument.getValue(), 2.0); assertThat(objectValue2, is("value2".getBytes())); } @Test public void sortset_types_should_be_added_into_redis_with_TTL() { DataReader dataReader = new DataReader(jedis); dataReader.read(new ByteArrayInputStream(DATA_WITH_SORTSET_TYPES_WITH_TTL.getBytes())); verify(jedis).expireAt("key".getBytes(), 1293840000); ArgumentCaptor<Map> argument = ArgumentCaptor.forClass(Map.class); verify(jedis).zadd(eq("key".getBytes()), argument.capture()); byte[] objectValue1 = (byte[]) firstKeyForValue(argument.getValue(), 1.0); assertThat(objectValue1, is("value1".getBytes())); byte[] objectValue2 = (byte[]) firstKeyForValue(argument.getValue(), 2.0); assertThat(objectValue2, is("value2".getBytes())); } private List<byte[]> convertToByteArray(String... values) { List<byte[]> bytes = new ArrayList<byte[]>(); for (String value : values) { bytes.add(value.getBytes()); } return bytes; } private <K, V> K firstKeyForValue(Map<K, V> map, V value) { for (Map.Entry<K, V> entry : map.entrySet()) { if (value.equals(entry.getValue())) return entry.getKey(); } return null; } }