package com.example.wordbook.provider;

import android.content.ContentValues;
import android.database.Cursor;
import android.net.Uri;
import android.test.ProviderTestCase2;
import android.test.mock.MockContentResolver;

/**
 * コンテンツプロバイダテストクラス
 */
public class WBProviderTest extends ProviderTestCase2<WBProvider> {

	/** MockContentResolver */
	private MockContentResolver mResolver;

	/**
	 * コンストラクタ
	 */
	public WBProviderTest() {
		super(WBProvider.class, WBProvider.AUTHORITY);
	}

	/*
	 * (非 Javadoc)
	 * 
	 * @see android.test.ProviderTestCase2#setUp()
	 */
	@Override
	protected void setUp() throws Exception {
		super.setUp();

		mResolver = getMockContentResolver();

		// クリア
		Uri uri = WBProvider.INFO_CONTENT_URI;
		mResolver.delete(uri, null, null);
	}

	/*
	 * (非 Javadoc)
	 * 
	 * @see android.test.ProviderTestCase2#tearDown()
	 */
	@Override
	protected void tearDown() throws Exception {
		super.tearDown();

		mResolver = null;
	}

	/**
	 * GetType()
	 */
	public void testGetType() {
		Uri uri;

		// コンテンツURI
		uri = WBProvider.INFO_CONTENT_URI;
		assertEquals(WBProvider.INFO_CONTENT_TYPE, mResolver.getType(uri));

		// コンテンツアイテムURI
		uri = Uri.parse(WBProvider.INFO_CONTENT_URI + "/0");
		assertEquals(WBProvider.INFO_CONTENT_ITEM_TYPE, mResolver.getType(uri));
		uri = Uri.parse(WBProvider.INFO_CONTENT_URI + "/65535");
		assertEquals(WBProvider.INFO_CONTENT_ITEM_TYPE, mResolver.getType(uri));

		// WBProviderではなくMockContentResolverのテスト

		// 例外が発生すること
		uri = null;
		try {
			mResolver.getType(uri);
			fail();
		} catch (NullPointerException e) {
		}

		// 不正文字列
		uri = Uri.parse("https://www.google.co.jp/");
		assertNull(mResolver.getType(uri));
		// 非対応URI
		uri = Uri.parse(WBProvider.INFO_CONTENT_URI + "/test");
		assertNull(mResolver.getType(uri));
		uri = Uri.parse(WBProvider.INFO_CONTENT_URI + "/-1");
		assertNull(mResolver.getType(uri));
	}

	/**
	 * testInsert_Content()
	 */
	public void testInsert_Content() {
		Uri uri = WBProvider.INFO_CONTENT_URI;
		ContentValues values = new ContentValues();
		values.put(WBData.InfoColumns.INFO_FILE, 0); // 固定
		values.put(WBData.InfoColumns.INFO_NUM, 1);
		values.put(WBData.InfoColumns.INFO_STAT, 2);
		values.put(WBData.InfoColumns.INFO_LEVEL, 3);
		values.put(WBData.InfoColumns.INFO_FLAG, 4);
		values.put(WBData.InfoColumns.INFO_OK, 5);
		values.put(WBData.InfoColumns.INFO_NG, 6);
		values.put(WBData.InfoColumns.INFO_QUESTION, "Q");
		values.put(WBData.InfoColumns.INFO_ANSWER, "A");
		values.put(WBData.InfoColumns.INFO_DATA1, "D1");
		values.put(WBData.InfoColumns.INFO_DATA2, "D2");

		// 戻り値は追加されたコンテンツアイテムURI
		assertEquals(WBProvider.INFO_CONTENT_ITEM_TYPE,
				mResolver.getType(mResolver.insert(uri, values)));
		assertEquals(WBProvider.INFO_CONTENT_ITEM_TYPE,
				mResolver.getType(mResolver.insert(uri, values)));
	}

	/**
	 * testInsert_ContentItem()
	 */
	public void testInsert_ContentItem() {
		Uri uri;
		ContentValues values = new ContentValues();
		values.put(WBData.InfoColumns.INFO_FILE, 0); // 固定
		values.put(WBData.InfoColumns.INFO_NUM, 1);
		values.put(WBData.InfoColumns.INFO_STAT, 2);
		values.put(WBData.InfoColumns.INFO_LEVEL, 3);
		values.put(WBData.InfoColumns.INFO_FLAG, 4);
		values.put(WBData.InfoColumns.INFO_OK, 5);
		values.put(WBData.InfoColumns.INFO_NG, 6);
		values.put(WBData.InfoColumns.INFO_QUESTION, "Q");
		values.put(WBData.InfoColumns.INFO_ANSWER, "A");
		values.put(WBData.InfoColumns.INFO_DATA1, "D1");
		values.put(WBData.InfoColumns.INFO_DATA2, "D2");

		// 例外が発生すること
		uri = Uri.parse(WBProvider.INFO_CONTENT_URI + "/0");
		try {
			mResolver.insert(uri, values);
			fail();
		} catch (IllegalArgumentException e) {
		}
	}

	/**
	 * testDelete_Content()
	 */
	public void testDelete_Content() {
		Uri uri = WBProvider.INFO_CONTENT_URI;
		// 偶数項目数＝奇数項目数
		final int DATA_NUM = 8;
		ContentValues[] array = new ContentValues[DATA_NUM * 2];
		for (int i = 0; i < array.length; i++) {
			ContentValues values = new ContentValues();
			values.put(WBData.InfoColumns.INFO_FILE, i);
			values.put(WBData.InfoColumns.INFO_NUM, i % 2); // 0 or 1
			values.put(WBData.InfoColumns.INFO_STAT, 2);
			values.put(WBData.InfoColumns.INFO_LEVEL, 3);
			values.put(WBData.InfoColumns.INFO_FLAG, 4);
			values.put(WBData.InfoColumns.INFO_OK, 5);
			values.put(WBData.InfoColumns.INFO_NG, 6);
			values.put(WBData.InfoColumns.INFO_QUESTION, "Q");
			values.put(WBData.InfoColumns.INFO_ANSWER, "A");
			values.put(WBData.InfoColumns.INFO_DATA1, "D1");
			values.put(WBData.InfoColumns.INFO_DATA2, "D2");
			array[i] = values;
		}

		// 初期化
		mResolver.insert(uri, array[0]);

		// 一項目毎
		String sel0 = WBData.InfoColumns.INFO_FILE + "=?";
		String[] arg0 = new String[] { "0" };
		// 戻り値は削除された数（存在する）
		assertEquals(1, mResolver.delete(uri, sel0, arg0));
		// 戻り値は削除された数（存在しない）
		assertEquals(0, mResolver.delete(uri, sel0, arg0));

		// 初期化
		for (int i = 0; i < array.length; i++) {
			mResolver.insert(uri, array[i]);
		}

		// 複数項目
		String sel1 = WBData.InfoColumns.INFO_NUM + "=?";
		String[] arg1_0 = new String[] { "0" };
		String[] arg1_1 = new String[] { "1" };
		String[] arg1_2 = new String[] { "2" };
		// 戻り値は削除された数（存在しない）
		assertEquals(0, mResolver.delete(uri, sel1, arg1_2));
		// 戻り値は削除された数（偶数項目）
		assertEquals(DATA_NUM, mResolver.delete(uri, sel1, arg1_0));
		// 戻り値は削除された数（奇数項目）
		assertEquals(DATA_NUM, mResolver.delete(uri, sel1, arg1_1));
	}

	/**
	 * testDelete_ContentItem()
	 */
	public void testDelete_ContentItem() {
		Uri uri;
		// 偶数項目数＝奇数項目数
		final int DATA_NUM = 8;
		ContentValues[] array = new ContentValues[DATA_NUM * 2];
		for (int i = 0; i < array.length; i++) {
			ContentValues values = new ContentValues();
			values.put(WBData.InfoColumns.INFO_FILE, i);
			values.put(WBData.InfoColumns.INFO_NUM, i % 2); // 0 or 1
			values.put(WBData.InfoColumns.INFO_STAT, 2);
			values.put(WBData.InfoColumns.INFO_LEVEL, 3);
			values.put(WBData.InfoColumns.INFO_FLAG, 4);
			values.put(WBData.InfoColumns.INFO_OK, 5);
			values.put(WBData.InfoColumns.INFO_NG, 6);
			values.put(WBData.InfoColumns.INFO_QUESTION, "Q");
			values.put(WBData.InfoColumns.INFO_ANSWER, "A");
			values.put(WBData.InfoColumns.INFO_DATA1, "D1");
			values.put(WBData.InfoColumns.INFO_DATA2, "D2");
			array[i] = values;
		}

		// 一項目毎
		String sel0 = WBData.InfoColumns.INFO_FILE + "=?";
		String[] arg0 = new String[] { "0" };
		// 戻り値は削除された数（存在する）
		uri = mResolver.insert(WBProvider.INFO_CONTENT_URI, array[0]);
		assertEquals(1, mResolver.delete(uri, sel0, arg0));
		// 戻り値は削除された数（存在しない）
		uri = Uri.parse(WBProvider.INFO_CONTENT_URI + "/0");
		assertEquals(0, mResolver.delete(uri, sel0, arg0));

		// 初期化
		Uri[] res = new Uri[array.length];
		for (int i = 0; i < array.length; i++) {
			res[i] = mResolver.insert(WBProvider.INFO_CONTENT_URI, array[i]);
		}

		// 複数項目
		String sel1 = WBData.InfoColumns.INFO_NUM + "=?";
		String[] arg1_0 = new String[] { "0" };
		String[] arg1_1 = new String[] { "1" };
		String[] arg1_2 = new String[] { "2" };
		// 戻り値は削除された数（存在しない）
		assertEquals(0, mResolver.delete(res[0], sel1, arg1_2));
		// 戻り値は削除された数（偶数項目）
		assertEquals(1, mResolver.delete(res[2], sel1, arg1_0));
		// 戻り値は削除された数（奇数項目）
		assertEquals(1, mResolver.delete(res[3], sel1, arg1_1));
	}

	/**
	 * testUpdate_Content()
	 */
	public void testUpdate_Content() {
		Uri uri = WBProvider.INFO_CONTENT_URI;
		// 偶数項目数＝奇数項目数
		final int DATA_NUM = 8;
		ContentValues[] array = new ContentValues[DATA_NUM * 2];
		for (int i = 0; i < array.length; i++) {
			ContentValues values = new ContentValues();
			values.put(WBData.InfoColumns.INFO_FILE, i);
			values.put(WBData.InfoColumns.INFO_NUM, i % 2); // 0 or 1
			values.put(WBData.InfoColumns.INFO_STAT, 2);
			values.put(WBData.InfoColumns.INFO_LEVEL, 3);
			values.put(WBData.InfoColumns.INFO_FLAG, 4);
			values.put(WBData.InfoColumns.INFO_OK, 5);
			values.put(WBData.InfoColumns.INFO_NG, 6);
			values.put(WBData.InfoColumns.INFO_QUESTION, "Q");
			values.put(WBData.InfoColumns.INFO_ANSWER, "A");
			values.put(WBData.InfoColumns.INFO_DATA1, "D1");
			values.put(WBData.InfoColumns.INFO_DATA2, "D2");
			array[i] = values;
		}
		// 更新項目
		ContentValues update = new ContentValues();
		update.put(WBData.InfoColumns.INFO_FILE, 99); // 範囲外指定
		update.put(WBData.InfoColumns.INFO_NUM, 99); // 範囲外指定
		update.put(WBData.InfoColumns.INFO_STAT, 2);
		update.put(WBData.InfoColumns.INFO_LEVEL, 3);
		update.put(WBData.InfoColumns.INFO_FLAG, 4);
		update.put(WBData.InfoColumns.INFO_OK, 5);
		update.put(WBData.InfoColumns.INFO_NG, 6);
		update.put(WBData.InfoColumns.INFO_QUESTION, "Q");
		update.put(WBData.InfoColumns.INFO_ANSWER, "A");
		update.put(WBData.InfoColumns.INFO_DATA1, "D1");
		update.put(WBData.InfoColumns.INFO_DATA2, "D2");

		// 初期化
		mResolver.insert(uri, array[0]);

		// 一項目毎
		String sel0 = WBData.InfoColumns.INFO_FILE + "=?";
		String[] arg0 = new String[] { "0" };
		// 戻り値は更新された数（存在する）
		assertEquals(1, mResolver.update(uri, update, sel0, arg0));
		// 戻り値は更新された数（存在しない）
		assertEquals(0, mResolver.update(uri, update, sel0, arg0));

		// 初期化
		for (int i = 0; i < array.length; i++) {
			mResolver.insert(uri, array[i]);
		}

		// 複数項目
		String sel1 = WBData.InfoColumns.INFO_NUM + "=?";
		String[] arg1_0 = new String[] { "0" };
		String[] arg1_1 = new String[] { "1" };
		String[] arg1_2 = new String[] { "2" };
		// 戻り値は更新された数（存在しない）
		assertEquals(0, mResolver.update(uri, update, sel1, arg1_2));
		// 戻り値は更新された数（偶数項目）
		assertEquals(DATA_NUM, mResolver.update(uri, update, sel1, arg1_0));
		// 戻り値は更新された数（奇数項目）
		assertEquals(DATA_NUM, mResolver.update(uri, update, sel1, arg1_1));
	}

	/**
	 * testUpdate_ContentItem()
	 */
	public void testUpdate_ContentItem() {
		Uri uri;
		// 偶数項目数＝奇数項目数
		final int DATA_NUM = 8;
		ContentValues[] array = new ContentValues[DATA_NUM * 2];
		for (int i = 0; i < array.length; i++) {
			ContentValues values = new ContentValues();
			values.put(WBData.InfoColumns.INFO_FILE, i);
			values.put(WBData.InfoColumns.INFO_NUM, i % 2); // 0 or 1
			values.put(WBData.InfoColumns.INFO_STAT, 2);
			values.put(WBData.InfoColumns.INFO_LEVEL, 3);
			values.put(WBData.InfoColumns.INFO_FLAG, 4);
			values.put(WBData.InfoColumns.INFO_OK, 5);
			values.put(WBData.InfoColumns.INFO_NG, 6);
			values.put(WBData.InfoColumns.INFO_QUESTION, "Q");
			values.put(WBData.InfoColumns.INFO_ANSWER, "A");
			values.put(WBData.InfoColumns.INFO_DATA1, "D1");
			values.put(WBData.InfoColumns.INFO_DATA2, "D2");
			array[i] = values;
		}
		// 更新項目
		ContentValues update = new ContentValues();
		update.put(WBData.InfoColumns.INFO_FILE, 99); // 範囲外指定
		update.put(WBData.InfoColumns.INFO_NUM, 99); // 範囲外指定
		update.put(WBData.InfoColumns.INFO_STAT, 2);
		update.put(WBData.InfoColumns.INFO_LEVEL, 3);
		update.put(WBData.InfoColumns.INFO_FLAG, 4);
		update.put(WBData.InfoColumns.INFO_OK, 5);
		update.put(WBData.InfoColumns.INFO_NG, 6);
		update.put(WBData.InfoColumns.INFO_QUESTION, "Q");
		update.put(WBData.InfoColumns.INFO_ANSWER, "A");
		update.put(WBData.InfoColumns.INFO_DATA1, "D1");
		update.put(WBData.InfoColumns.INFO_DATA2, "D2");

		// 一項目毎
		String sel0 = WBData.InfoColumns.INFO_FILE + "=?";
		String[] arg0 = new String[] { "0" };
		// 戻り値は更新された数（存在する）
		uri = mResolver.insert(WBProvider.INFO_CONTENT_URI, array[0]);
		assertEquals(1, mResolver.update(uri, update, sel0, arg0));
		// 戻り値は更新された数（存在しない）
		uri = Uri.parse(WBProvider.INFO_CONTENT_URI + "/0");
		assertEquals(0, mResolver.update(uri, update, sel0, arg0));

		// 初期化
		Uri[] res = new Uri[array.length];
		for (int i = 0; i < array.length; i++) {
			res[i] = mResolver.insert(WBProvider.INFO_CONTENT_URI, array[i]);
		}

		// 複数項目
		String sel1 = WBData.InfoColumns.INFO_NUM + "=?";
		String[] arg1_0 = new String[] { "0" };
		String[] arg1_1 = new String[] { "1" };
		String[] arg1_2 = new String[] { "2" };
		// 戻り値は更新された数（存在しない）
		assertEquals(0, mResolver.update(res[0], update, sel1, arg1_2));
		// 戻り値は更新された数（偶数項目）
		assertEquals(1, mResolver.update(res[2], update, sel1, arg1_0));
		// 戻り値は更新された数（奇数項目）
		assertEquals(1, mResolver.update(res[3], update, sel1, arg1_1));
	}

	/**
	 * testQuery_Content()
	 */
	public void testQuery_Content() {
		Uri uri = WBProvider.INFO_CONTENT_URI;
		// 偶数項目数＝奇数項目数
		final int DATA_NUM = 8;
		ContentValues[] array = new ContentValues[DATA_NUM * 2];
		for (int i = 0; i < array.length; i++) {
			ContentValues values = new ContentValues();
			values.put(WBData.InfoColumns.INFO_FILE, i);
			values.put(WBData.InfoColumns.INFO_NUM, i % 2); // 0 or 1
			values.put(WBData.InfoColumns.INFO_STAT, 2);
			values.put(WBData.InfoColumns.INFO_LEVEL, 3);
			values.put(WBData.InfoColumns.INFO_FLAG, 4);
			values.put(WBData.InfoColumns.INFO_OK, 5);
			values.put(WBData.InfoColumns.INFO_NG, 6);
			values.put(WBData.InfoColumns.INFO_QUESTION, "Q");
			values.put(WBData.InfoColumns.INFO_ANSWER, "A");
			values.put(WBData.InfoColumns.INFO_DATA1, "D1");
			values.put(WBData.InfoColumns.INFO_DATA2, "D2");
			array[i] = values;
		}
		// 確認対象キー
		String k0 = WBData.InfoColumns.INFO_FILE;
		String k1 = WBData.InfoColumns.INFO_NUM;
		String k2 = WBData.InfoColumns.INFO_STAT;
		String k3 = WBData.InfoColumns.INFO_LEVEL;
		String k4 = WBData.InfoColumns.INFO_FLAG;
		String k5 = WBData.InfoColumns.INFO_OK;
		String k6 = WBData.InfoColumns.INFO_NG;
		String ks0 = WBData.InfoColumns.INFO_QUESTION;
		String ks1 = WBData.InfoColumns.INFO_ANSWER;
		String ks2 = WBData.InfoColumns.INFO_DATA1;
		String ks3 = WBData.InfoColumns.INFO_DATA2;

		// 初期化
		for (int i = 0; i < array.length; i++) {
			mResolver.insert(uri, array[i]);
		}

		// 偶数項目取得
		String sel0 = WBData.InfoColumns.INFO_NUM + "=?";
		String[] arg0 = new String[] { "0" };
		Cursor c0 = mResolver.query(uri, null, sel0, arg0, null);
		// 項目数一致
		assertEquals(DATA_NUM, c0.getCount());
		for (int i = 0; i < array.length; i += 2) {
			// 取得
			assertTrue(c0.moveToNext());
			// カラム数一致(_id追加)
			assertEquals(array[i].size() + 1, c0.getColumnCount());
			// 内容一致
			assertEquals(array[i].get(k0), c0.getInt(c0.getColumnIndex(k0)));
			assertEquals(array[i].get(k1), c0.getInt(c0.getColumnIndex(k1)));
			assertEquals(array[i].get(k2), c0.getInt(c0.getColumnIndex(k2)));
			assertEquals(array[i].get(k3), c0.getInt(c0.getColumnIndex(k3)));
			assertEquals(array[i].get(k4), c0.getInt(c0.getColumnIndex(k4)));
			assertEquals(array[i].get(k5), c0.getInt(c0.getColumnIndex(k5)));
			assertEquals(array[i].get(k6), c0.getInt(c0.getColumnIndex(k6)));
			assertEquals(array[i].get(ks0),
					c0.getString(c0.getColumnIndex(ks0)));
			assertEquals(array[i].get(ks1),
					c0.getString(c0.getColumnIndex(ks1)));
			assertEquals(array[i].get(ks2),
					c0.getString(c0.getColumnIndex(ks2)));
			assertEquals(array[i].get(ks3),
					c0.getString(c0.getColumnIndex(ks3)));
		}
		// 取得不可
		assertFalse(c0.moveToNext());

		// 奇数項目取得
		String sel1 = WBData.InfoColumns.INFO_NUM + "=?";
		String[] arg1 = new String[] { "1" };
		Cursor c1 = mResolver.query(uri, null, sel1, arg1, null);
		// 項目数一致
		assertEquals(DATA_NUM, c1.getCount());
		for (int i = 1; i < array.length; i += 2) {
			// 取得
			assertTrue(c1.moveToNext());
			// カラム数一致(_id追加)
			assertEquals(array[i].size() + 1, c1.getColumnCount());
			// 内容一致
			assertEquals(array[i].get(k0), c1.getInt(c1.getColumnIndex(k0)));
			assertEquals(array[i].get(k1), c1.getInt(c1.getColumnIndex(k1)));
			assertEquals(array[i].get(k2), c1.getInt(c1.getColumnIndex(k2)));
			assertEquals(array[i].get(k3), c1.getInt(c1.getColumnIndex(k3)));
			assertEquals(array[i].get(k4), c1.getInt(c1.getColumnIndex(k4)));
			assertEquals(array[i].get(k5), c1.getInt(c1.getColumnIndex(k5)));
			assertEquals(array[i].get(k6), c1.getInt(c1.getColumnIndex(k6)));
			assertEquals(array[i].get(ks0),
					c1.getString(c1.getColumnIndex(ks0)));
			assertEquals(array[i].get(ks1),
					c1.getString(c1.getColumnIndex(ks1)));
			assertEquals(array[i].get(ks2),
					c1.getString(c1.getColumnIndex(ks2)));
			assertEquals(array[i].get(ks3),
					c1.getString(c1.getColumnIndex(ks3)));
		}
		// 取得不可
		assertFalse(c1.moveToNext());

		// 非存在項目取得
		String sel2 = WBData.InfoColumns.INFO_NUM + "=?";
		String[] arg2 = new String[] { "2" };
		Cursor c2 = mResolver.query(uri, null, sel2, arg2, null);
		// 項目数一致
		assertEquals(0, c2.getCount());
		// 取得不可
		assertFalse(c2.moveToNext());

		// 全項目取得
		String sel3 = null;
		String[] arg3 = null;
		Cursor c3 = mResolver.query(uri, null, sel3, arg3, null);
		// 項目数一致
		assertEquals(DATA_NUM * 2, c3.getCount());
		for (int i = 0; i < array.length; i++) {
			// 取得
			assertTrue(c3.moveToNext());
			// カラム数一致(_id追加)
			assertEquals(array[i].size() + 1, c3.getColumnCount());
			// 内容一致
			assertEquals(array[i].get(k0), c3.getInt(c3.getColumnIndex(k0)));
			assertEquals(array[i].get(k1), c3.getInt(c3.getColumnIndex(k1)));
			assertEquals(array[i].get(k2), c3.getInt(c3.getColumnIndex(k2)));
			assertEquals(array[i].get(k3), c3.getInt(c3.getColumnIndex(k3)));
			assertEquals(array[i].get(k4), c3.getInt(c3.getColumnIndex(k4)));
			assertEquals(array[i].get(k5), c3.getInt(c3.getColumnIndex(k5)));
			assertEquals(array[i].get(k6), c3.getInt(c3.getColumnIndex(k6)));
			assertEquals(array[i].get(ks0),
					c3.getString(c3.getColumnIndex(ks0)));
			assertEquals(array[i].get(ks1),
					c3.getString(c3.getColumnIndex(ks1)));
			assertEquals(array[i].get(ks2),
					c3.getString(c3.getColumnIndex(ks2)));
			assertEquals(array[i].get(ks3),
					c3.getString(c3.getColumnIndex(ks3)));
		}
		// 取得不可
		assertFalse(c3.moveToNext());
	}

	/**
	 * testQuery_ContentItem()
	 */
	public void testQuery_ContentItem() {
		Uri uri;
		// 偶数項目数＝奇数項目数
		final int DATA_NUM = 8;
		ContentValues[] array = new ContentValues[DATA_NUM * 2];
		for (int i = 0; i < array.length; i++) {
			ContentValues values = new ContentValues();
			values.put(WBData.InfoColumns.INFO_FILE, i);
			values.put(WBData.InfoColumns.INFO_NUM, i % 2); // 0 or 1
			values.put(WBData.InfoColumns.INFO_STAT, 2);
			values.put(WBData.InfoColumns.INFO_LEVEL, 3);
			values.put(WBData.InfoColumns.INFO_FLAG, 4);
			values.put(WBData.InfoColumns.INFO_OK, 5);
			values.put(WBData.InfoColumns.INFO_NG, 6);
			values.put(WBData.InfoColumns.INFO_QUESTION, "Q");
			values.put(WBData.InfoColumns.INFO_ANSWER, "A");
			values.put(WBData.InfoColumns.INFO_DATA1, "D1");
			values.put(WBData.InfoColumns.INFO_DATA2, "D2");
			array[i] = values;
		}
		// 確認対象キー
		String k0 = WBData.InfoColumns.INFO_FILE;
		String k1 = WBData.InfoColumns.INFO_NUM;
		String k2 = WBData.InfoColumns.INFO_STAT;
		String k3 = WBData.InfoColumns.INFO_LEVEL;
		String k4 = WBData.InfoColumns.INFO_FLAG;
		String k5 = WBData.InfoColumns.INFO_OK;
		String k6 = WBData.InfoColumns.INFO_NG;
		String ks0 = WBData.InfoColumns.INFO_QUESTION;
		String ks1 = WBData.InfoColumns.INFO_ANSWER;
		String ks2 = WBData.InfoColumns.INFO_DATA1;
		String ks3 = WBData.InfoColumns.INFO_DATA2;

		// 初期化
		Uri[] res = new Uri[array.length];
		for (int i = 0; i < array.length; i++) {
			res[i] = mResolver.insert(WBProvider.INFO_CONTENT_URI, array[i]);
		}

		// 偶数項目取得
		String sel0 = WBData.InfoColumns.INFO_NUM + "=?";
		String[] arg0 = new String[] { "0" };
		uri = res[2]; // 偶数番目
		ContentValues cv0 = array[2]; // 偶数番目
		Cursor c0 = mResolver.query(uri, null, sel0, arg0, null);
		// 項目数一致
		assertEquals(1, c0.getCount());
		// 取得
		assertTrue(c0.moveToNext());
		// カラム数一致(_id追加)
		assertEquals(cv0.size() + 1, c0.getColumnCount());
		// 内容一致
		assertEquals(cv0.get(k0), c0.getInt(c0.getColumnIndex(k0)));
		assertEquals(cv0.get(k1), c0.getInt(c0.getColumnIndex(k1)));
		assertEquals(cv0.get(k2), c0.getInt(c0.getColumnIndex(k2)));
		assertEquals(cv0.get(k3), c0.getInt(c0.getColumnIndex(k3)));
		assertEquals(cv0.get(k4), c0.getInt(c0.getColumnIndex(k4)));
		assertEquals(cv0.get(k5), c0.getInt(c0.getColumnIndex(k5)));
		assertEquals(cv0.get(k6), c0.getInt(c0.getColumnIndex(k6)));
		assertEquals(cv0.get(ks0), c0.getString(c0.getColumnIndex(ks0)));
		assertEquals(cv0.get(ks1), c0.getString(c0.getColumnIndex(ks1)));
		assertEquals(cv0.get(ks2), c0.getString(c0.getColumnIndex(ks2)));
		assertEquals(cv0.get(ks3), c0.getString(c0.getColumnIndex(ks3)));
		// 取得不可
		assertFalse(c0.moveToNext());

		// 奇数項目取得
		String sel1 = WBData.InfoColumns.INFO_NUM + "=?";
		String[] arg1 = new String[] { "1" };
		uri = res[3]; // 奇数番目
		ContentValues cv1 = array[3]; // 奇数番目
		Cursor c1 = mResolver.query(uri, null, sel1, arg1, null);
		// 項目数一致
		assertEquals(1, c1.getCount());
		// 取得
		assertTrue(c1.moveToNext());
		// カラム数一致(_id追加)
		assertEquals(cv1.size() + 1, c1.getColumnCount());
		// 内容一致
		assertEquals(cv1.get(k0), c1.getInt(c1.getColumnIndex(k0)));
		assertEquals(cv1.get(k1), c1.getInt(c1.getColumnIndex(k1)));
		assertEquals(cv1.get(k2), c1.getInt(c1.getColumnIndex(k2)));
		assertEquals(cv1.get(k3), c1.getInt(c1.getColumnIndex(k3)));
		assertEquals(cv1.get(k4), c1.getInt(c1.getColumnIndex(k4)));
		assertEquals(cv1.get(k5), c1.getInt(c1.getColumnIndex(k5)));
		assertEquals(cv1.get(k6), c1.getInt(c1.getColumnIndex(k6)));
		assertEquals(cv1.get(ks0), c1.getString(c1.getColumnIndex(ks0)));
		assertEquals(cv1.get(ks1), c1.getString(c1.getColumnIndex(ks1)));
		assertEquals(cv1.get(ks2), c1.getString(c1.getColumnIndex(ks2)));
		assertEquals(cv1.get(ks3), c1.getString(c1.getColumnIndex(ks3)));
		// 取得不可
		assertFalse(c1.moveToNext());

		// 非存在項目取得
		String sel2 = WBData.InfoColumns.INFO_NUM + "=?";
		String[] arg2 = new String[] { "2" };
		uri = res[4]; // 対象
		Cursor c2 = mResolver.query(uri, null, sel2, arg2, null);
		// 項目数一致
		assertEquals(0, c2.getCount());
		// 取得不可
		assertFalse(c2.moveToNext());

		// 全項目取得
		String sel3 = null;
		String[] arg3 = null;
		uri = res[5]; // 対象
		ContentValues cv3 = array[5]; // 対象
		Cursor c3 = mResolver.query(uri, null, sel3, arg3, null);
		// 項目数一致
		assertEquals(1, c3.getCount());
		// 取得
		assertTrue(c3.moveToNext());
		// カラム数一致(_id追加)
		assertEquals(cv3.size() + 1, c3.getColumnCount());
		// 内容一致
		assertEquals(cv3.get(k0), c3.getInt(c3.getColumnIndex(k0)));
		assertEquals(cv3.get(k1), c3.getInt(c3.getColumnIndex(k1)));
		assertEquals(cv3.get(k2), c3.getInt(c3.getColumnIndex(k2)));
		assertEquals(cv3.get(k3), c3.getInt(c3.getColumnIndex(k3)));
		assertEquals(cv3.get(k4), c3.getInt(c3.getColumnIndex(k4)));
		assertEquals(cv3.get(k5), c3.getInt(c3.getColumnIndex(k5)));
		assertEquals(cv3.get(k6), c3.getInt(c3.getColumnIndex(k6)));
		assertEquals(cv3.get(ks0), c3.getString(c3.getColumnIndex(ks0)));
		assertEquals(cv3.get(ks1), c3.getString(c3.getColumnIndex(ks1)));
		assertEquals(cv3.get(ks2), c3.getString(c3.getColumnIndex(ks2)));
		assertEquals(cv3.get(ks3), c3.getString(c3.getColumnIndex(ks3)));
		// 取得不可
		assertFalse(c3.moveToNext());
	}

	/**
	 * testQuery_Projection()
	 */
	public void testQuery_Projection() {
		Uri uri = WBProvider.INFO_CONTENT_URI;
		final int DATA_NUM = 8;
		ContentValues[] array = new ContentValues[DATA_NUM];
		for (int i = 0; i < array.length; i++) {
			ContentValues values = new ContentValues();
			values.put(WBData.InfoColumns.INFO_FILE, i);
			values.put(WBData.InfoColumns.INFO_NUM, 1);
			values.put(WBData.InfoColumns.INFO_STAT, 2);
			values.put(WBData.InfoColumns.INFO_LEVEL, 3);
			values.put(WBData.InfoColumns.INFO_FLAG, 4);
			values.put(WBData.InfoColumns.INFO_OK, 5);
			values.put(WBData.InfoColumns.INFO_NG, 6);
			values.put(WBData.InfoColumns.INFO_QUESTION, "Q");
			values.put(WBData.InfoColumns.INFO_ANSWER, "A");
			values.put(WBData.InfoColumns.INFO_DATA1, "D1");
			values.put(WBData.InfoColumns.INFO_DATA2, "D2");
			array[i] = values;
		}
		// 確認対象キー
		String k0 = WBData.InfoColumns.INFO_FILE;
		String k1 = WBData.InfoColumns.INFO_NUM;
		String k2 = WBData.InfoColumns.INFO_STAT;
		String k3 = WBData.InfoColumns.INFO_LEVEL;
		String k4 = WBData.InfoColumns.INFO_FLAG;
		String k5 = WBData.InfoColumns.INFO_OK;
		String k6 = WBData.InfoColumns.INFO_NG;
		String ks0 = WBData.InfoColumns.INFO_QUESTION;
		String ks1 = WBData.InfoColumns.INFO_ANSWER;
		String ks2 = WBData.InfoColumns.INFO_DATA1;
		String ks3 = WBData.InfoColumns.INFO_DATA2;
		// 取得列リスト
		String[] pjt = { k0, k2, k5, k6, ks2, ks3 };

		// 初期化
		for (int i = 0; i < array.length; i++) {
			mResolver.insert(uri, array[i]);
		}

		// 対象項目のみ取得
		String sel0 = WBData.InfoColumns.INFO_FILE + "=?";
		String[] arg0 = new String[] { "0" };
		ContentValues cv0 = array[0];
		Cursor c0 = mResolver.query(uri, pjt, sel0, arg0, null);
		assertTrue(c0.moveToNext());
		// 取得列の内容が一致
		assertEquals(cv0.get(k0), c0.getInt(c0.getColumnIndex(k0)));
		assertEquals(cv0.get(k2), c0.getInt(c0.getColumnIndex(k2)));
		assertEquals(cv0.get(k5), c0.getInt(c0.getColumnIndex(k5)));
		assertEquals(cv0.get(k6), c0.getInt(c0.getColumnIndex(k6)));
		assertEquals(cv0.get(ks2), c0.getString(c0.getColumnIndex(ks2)));
		assertEquals(cv0.get(ks3), c0.getString(c0.getColumnIndex(ks3)));
		// 存在しない場合はindexが-1
		assertEquals(-1, c0.getColumnIndex(k1));
		assertEquals(-1, c0.getColumnIndex(k3));
		assertEquals(-1, c0.getColumnIndex(k4));
		assertEquals(-1, c0.getColumnIndex(ks0));
		assertEquals(-1, c0.getColumnIndex(ks1));
	}

	/**
	 * testQuery_Sort()
	 */
	public void testQuery_Sort() {
		Uri uri = WBProvider.INFO_CONTENT_URI;
		final int DATA_NUM = 8;
		ContentValues[] array = new ContentValues[DATA_NUM];
		for (int i = 0; i < array.length; i++) {
			ContentValues values = new ContentValues();
			values.put(WBData.InfoColumns.INFO_FILE, i);
			values.put(WBData.InfoColumns.INFO_NUM, array.length - i - 1); // 逆
			values.put(WBData.InfoColumns.INFO_STAT, 2);
			values.put(WBData.InfoColumns.INFO_LEVEL, 3);
			values.put(WBData.InfoColumns.INFO_FLAG, 4);
			values.put(WBData.InfoColumns.INFO_OK, 5);
			values.put(WBData.InfoColumns.INFO_NG, 6);
			values.put(WBData.InfoColumns.INFO_QUESTION, "Q");
			values.put(WBData.InfoColumns.INFO_ANSWER, "A");
			values.put(WBData.InfoColumns.INFO_DATA1, "D1");
			values.put(WBData.InfoColumns.INFO_DATA2, "D2");
			array[i] = values;
		}
		// 確認対象キー
		String k0 = WBData.InfoColumns.INFO_FILE;
		String k1 = WBData.InfoColumns.INFO_NUM;

		// 初期化
		for (int i = 0; i < array.length; i++) {
			mResolver.insert(uri, array[i]);
		}

		// 全項目取得
		String sel = null;
		String[] arg = null;
		// デフォルト時は登録順
		Cursor c0 = mResolver.query(uri, null, sel, arg, null);
		for (int i = 0; i < array.length; i++) {
			ContentValues cv = array[i];
			assertTrue(c0.moveToNext());
			assertEquals(cv.get(k0), c0.getInt(c0.getColumnIndex(k0)));
		}
		// NUM昇順
		Cursor c1 = mResolver.query(uri, null, sel, arg, k1 + " ASC");
		for (int i = 0; i < array.length; i++) {
			ContentValues cv = array[array.length - i - 1];
			assertTrue(c1.moveToNext());
			assertEquals(cv.get(k1), c1.getInt(c1.getColumnIndex(k1)));
		}
		// NUM降順
		Cursor c2 = mResolver.query(uri, null, sel, arg, k1 + " DESC");
		for (int i = 0; i < array.length; i++) {
			ContentValues cv = array[i];
			assertTrue(c2.moveToNext());
			assertEquals(cv.get(k1), c2.getInt(c2.getColumnIndex(k1)));
		}
	}

	/**
	 * testQuery_Limit()
	 */
	public void testQuery_Limit() {
		Uri uri = WBProvider.INFO_CONTENT_URI;
		final int NUM1 = 8;
		final int NUM2 = 16;
		ContentValues[] array = new ContentValues[NUM1 + NUM2];
		for (int i = 0; i < array.length; i++) {
			ContentValues values = new ContentValues();
			values.put(WBData.InfoColumns.INFO_FILE, i);
			values.put(WBData.InfoColumns.INFO_NUM, 1);
			values.put(WBData.InfoColumns.INFO_STAT, 2);
			values.put(WBData.InfoColumns.INFO_LEVEL, 3);
			values.put(WBData.InfoColumns.INFO_FLAG, 4);
			values.put(WBData.InfoColumns.INFO_OK, 5);
			values.put(WBData.InfoColumns.INFO_NG, 6);
			values.put(WBData.InfoColumns.INFO_QUESTION, "Q");
			values.put(WBData.InfoColumns.INFO_ANSWER, "A");
			values.put(WBData.InfoColumns.INFO_DATA1, "D1");
			values.put(WBData.InfoColumns.INFO_DATA2, "D2");
			array[i] = values;
		}

		// 初期化
		for (int i = 0; i < array.length; i++) {
			mResolver.insert(uri, array[i]);
		}

		// 全項目取得
		String sel = null;
		String[] arg = null;
		// デフォルト時は全て
		Cursor c0 = mResolver.query(uri, null, sel, arg, null);
		assertEquals(NUM1 + NUM2, c0.getCount());
		// 最初からNUM1まで
		String limit1 = Integer.toString(0) + "," + Integer.toString(NUM1);
		Uri uri1 = uri.buildUpon().appendQueryParameter("limit", limit1)
				.build();
		Cursor c1 = mResolver.query(uri1, null, sel, arg, null);
		assertEquals(NUM1, c1.getCount());
		// NUM2から最後まで
		String limit2 = Integer.toString(NUM1) + "," + Integer.toString(NUM2);
		Uri uri2 = uri.buildUpon().appendQueryParameter("limit", limit2)
				.build();
		Cursor c2 = mResolver.query(uri2, null, sel, arg, null);
		assertEquals(NUM2, c2.getCount());
	}

}
