/*
*
* * Copyright 2015. Appsi Mobile
* *
* * 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 com.appsimobile.appsii.module.home.config;
import android.content.ContentResolver;
import android.content.Context;
import android.test.mock.MockContentResolver;
import android.test.mock.MockContext;
import net.jcip.annotations.GuardedBy;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.runners.MockitoJUnitRunner;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicReference;
import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertNull;
/**
* Created by nick on 08/03/15.
*/
@RunWith(MockitoJUnitRunner.class)
public class HomeItemConfigurationHelperTest {
HomeItemConfigurationHelper mHomeItemConfigurationHelper;
ArrayList<Runnable> mRunnables;
@Before
public void setUp() throws Exception {
mRunnables = new ArrayList<>();
mHomeItemConfigurationHelper =
new MockHomeItemConfigurationHelper(new TestMockContext(), mRunnables);
}
@Test
public void testGetValue() {
assertEquals("0a", mHomeItemConfigurationHelper.getProperty(0, "keya", null));
assertEquals("0b", mHomeItemConfigurationHelper.getProperty(0, "keyb", null));
assertNull(mHomeItemConfigurationHelper.getProperty(0, "keyc", null));
assertEquals("1a", mHomeItemConfigurationHelper.getProperty(1, "keya", null));
assertNull(mHomeItemConfigurationHelper.getProperty(1, "keyb", null));
assertNull(mHomeItemConfigurationHelper.getProperty(1, "keyc", null));
assertEquals("2a", mHomeItemConfigurationHelper.getProperty(2, "keya", null));
assertNull(mHomeItemConfigurationHelper.getProperty(2, "keyb", null));
assertEquals("2c", mHomeItemConfigurationHelper.getProperty(2, "keyc", null));
assertNull(mHomeItemConfigurationHelper.getProperty(3, "keya", null));
assertNull(mHomeItemConfigurationHelper.getProperty(3, "keyb", null));
assertNull(mHomeItemConfigurationHelper.getProperty(3, "keyc", null));
assertNull(mHomeItemConfigurationHelper.getProperty(4, "keya", null));
assertNull(mHomeItemConfigurationHelper.getProperty(4, "keyb", null));
assertNull(mHomeItemConfigurationHelper.getProperty(4, "keyc", null));
}
@Test
public void testUpdate() throws InterruptedException {
TestConfigurationListener l = new TestConfigurationListener(1, 1);
mHomeItemConfigurationHelper.addConfigurationListener(l);
mHomeItemConfigurationHelper.updateProperty(0, "keya", "u0a");
l.awaitUpdate();
assertEquals(0L, l.updateCellIdAt(0));
assertEquals("keya", l.updateCellKeyAt(0));
assertEquals("u0a", l.updateCellValueAt(0));
assertEquals("u0a", mHomeItemConfigurationHelper.getProperty(0, "keya", null));
mHomeItemConfigurationHelper.removeConfigurationListener(l);
l = new TestConfigurationListener(2, 1);
mHomeItemConfigurationHelper.addConfigurationListener(l);
mHomeItemConfigurationHelper.updateProperty(0, "keyb", "u0b");
mHomeItemConfigurationHelper.updateProperty(0, "keyc", "u0c");
l.awaitUpdate();
assertEquals(0L, l.updateCellIdAt(0));
assertEquals("keyb", l.updateCellKeyAt(0));
assertEquals("u0b", l.updateCellValueAt(0));
assertEquals(0L, l.updateCellIdAt(1));
assertEquals("keyc", l.updateCellKeyAt(1));
assertEquals("u0c", l.updateCellValueAt(1));
assertEquals("u0b", mHomeItemConfigurationHelper.getProperty(0, "keyb", null));
assertEquals("u0c", mHomeItemConfigurationHelper.getProperty(0, "keyc", null));
mHomeItemConfigurationHelper.removeConfigurationListener(l);
l = new TestConfigurationListener(8, 1);
mHomeItemConfigurationHelper.addConfigurationListener(l);
mHomeItemConfigurationHelper.updateProperty(0, "keya", "_a");
mHomeItemConfigurationHelper.updateProperty(0, "keya", "_b");
mHomeItemConfigurationHelper.updateProperty(0, "keya", "_c");
mHomeItemConfigurationHelper.updateProperty(0, "keyb", "b");
mHomeItemConfigurationHelper.updateProperty(0, "keya", "_d");
mHomeItemConfigurationHelper.updateProperty(0, "keya", "_e");
mHomeItemConfigurationHelper.updateProperty(0, "keya", "_f");
mHomeItemConfigurationHelper.updateProperty(0, "keya", "test");
l.awaitUpdate();
assertEquals("test", mHomeItemConfigurationHelper.getProperty(0, "keya", null));
assertEquals("b", mHomeItemConfigurationHelper.getProperty(0, "keyb", null));
mHomeItemConfigurationHelper.removeConfigurationListener(l);
}
@Test
public void testUpdateWithIntermediateDelete() throws InterruptedException {
TestConfigurationListener l;
final AtomicInteger clearCount = new AtomicInteger();
final AtomicReference<String> lastValue = new AtomicReference<>();
mHomeItemConfigurationHelper.addConfigurationListener(
new HomeItemConfigurationHelper.ConfigurationListener() {
@Override
public void onConfigurationOptionUpdated(long cellId, String key,
String value) {
if ("keya".equals(key)) {
lastValue.set(value);
}
}
@Override
public void onConfigurationOptionDeleted(long cellId, String key) {
if ("keya".equals(key)) {
lastValue.set(null);
clearCount.incrementAndGet();
}
}
});
l = new TestConfigurationListener(8, 2);
mHomeItemConfigurationHelper.addConfigurationListener(l);
mHomeItemConfigurationHelper.updateProperty(0, "keya", "_a");
mHomeItemConfigurationHelper.updateProperty(0, "keya", "_b");
mHomeItemConfigurationHelper.updateProperty(0, "keya", "_c");
mHomeItemConfigurationHelper.removeProperty(0, "keya");
mHomeItemConfigurationHelper.updateProperty(0, "keyb", "a");
mHomeItemConfigurationHelper.removeProperty(0, "keyb");
mHomeItemConfigurationHelper.updateProperty(0, "keya", "_d");
mHomeItemConfigurationHelper.updateProperty(0, "keya", "_e");
mHomeItemConfigurationHelper.updateProperty(0, "keya", "_f");
mHomeItemConfigurationHelper.updateProperty(0, "keya", "test");
l.awaitUpdate();
assertEquals("test", mHomeItemConfigurationHelper.getProperty(0, "keya", null));
assertNull(mHomeItemConfigurationHelper.getProperty(0, "keyb", null));
assertEquals("test", lastValue.get());
assertEquals(1, clearCount.get());
mHomeItemConfigurationHelper.removeConfigurationListener(l);
}
void runPendingRunnables() {
final List<Runnable> runnableList = new ArrayList<>(mRunnables);
mRunnables.clear();
new Thread(new Runnable() {
@Override
public void run() {
for (Runnable r : runnableList) {
r.run();
}
}
}).start();
}
private class TestConfigurationListener
implements HomeItemConfigurationHelper.ConfigurationListener {
long mLastDeleteCellId;
String mLastDeleteKey;
@GuardedBy("this")
long[] mUpdateCellIds;
@GuardedBy("this")
String[] mUpdateCellKeys;
@GuardedBy("this")
String[] mUpdateCellValues;
@GuardedBy("this")
int mUpdatePosition;
CountDownLatch mUpdateLatch;
CountDownLatch mDeleteLatch;
TestConfigurationListener(int updateCount, int deleteCount) {
mUpdateLatch = new CountDownLatch(updateCount);
mDeleteLatch = new CountDownLatch(deleteCount);
mUpdateCellIds = new long[updateCount];
mUpdateCellKeys = new String[updateCount];
mUpdateCellValues = new String[updateCount];
}
synchronized long updateCellIdAt(int position) {
return mUpdateCellIds[position];
}
synchronized String updateCellKeyAt(int position) {
return mUpdateCellKeys[position];
}
synchronized String updateCellValueAt(int position) {
return mUpdateCellValues[position];
}
void awaitUpdate() throws InterruptedException {
runPendingRunnables();
mUpdateLatch.await();
}
@Override
public void onConfigurationOptionUpdated(long cellId, String key, String value) {
synchronized (this) {
mUpdateCellIds[mUpdatePosition] = cellId;
mUpdateCellKeys[mUpdatePosition] = key;
mUpdateCellValues[mUpdatePosition] = value;
mUpdatePosition++;
}
mUpdateLatch.countDown();
}
void awaitDelete() throws InterruptedException {
runPendingRunnables();
mDeleteLatch.await();
}
@Override
public void onConfigurationOptionDeleted(long cellId, String key) {
synchronized (this) {
mLastDeleteCellId = cellId;
mLastDeleteKey = key;
}
mDeleteLatch.countDown();
}
}
class TestMockContext extends MockContext {
@Override
public ContentResolver getContentResolver() {
return new MockContentResolver();
}
@Override
public Context getApplicationContext() {
return this;
}
}
}