package com.applang.berichtsheft.test; import java.io.BufferedReader; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.lang.reflect.Method; import java.nio.charset.Charset; import java.util.Arrays; import java.util.Calendar; import java.util.Date; import java.util.Map; import java.util.regex.MatchResult; import java.util.regex.Pattern; import org.json.JSONArray; import android.content.ContentResolver; import android.content.ContentValues; import android.content.Context; import android.content.SharedPreferences; import android.database.ContentObserver; import android.database.Cursor; import android.net.Uri; import android.os.Handler; import android.os.Message; import android.util.Log; import com.applang.UserContext; import com.applang.Util.ValList; import com.applang.berichtsheft.R; import com.applang.berichtsheft.BerichtsheftActivity; import com.applang.provider.NotePad.NoteColumns; import com.applang.provider.NotePad; import com.applang.provider.NotePadProvider; import com.applang.provider.PlantInfo; import com.applang.provider.PlantInfo.Plants; import com.applang.provider.PlantInfoProvider; import com.applang.provider.WeatherInfo.Weathers; import com.applang.provider.WeatherInfoProvider; import static com.applang.Util.*; import static com.applang.Util1.*; import static com.applang.Util2.*; import static com.applang.VelocityUtil.*; public class ProviderTests extends InfraTests<BerichtsheftActivity> { private static final String TAG = ProviderTests.class.getSimpleName(); private SharedPreferences prefs = null; public ProviderTests() { super(getPackageNameByClass(R.class), BerichtsheftActivity.class); } @Override protected void setUp() throws Exception { super.setUp(); assertTrue(mActivity instanceof BerichtsheftActivity); prefs = mActivity.getSharedPreferences(null, Context.MODE_PRIVATE); prefs.edit().putBoolean("keepData", false).commit(); } @Override protected void tearDown() throws Exception { super.tearDown(); } private Handler notifyHandler = new Handler() { @Override public void handleMessage(Message msg) { System.out.println(msg); super.handleMessage(msg); } }; int contentObservations = 0; private void setContentObserver(ContentResolver contentResolver, final Uri notificationUri) { ContentObserver contentObserver = new ContentObserver(notifyHandler) { @Override public void onChange(boolean selfChange) { contentObservations++; } }; contentResolver.registerContentObserver(notificationUri, true, contentObserver); } void keepTestData(final String[] fileNames) { if (prefs.getBoolean("keepData", false)) { impex(mActivity, fileNames, true); } } public int generateNotes(boolean clear, Pattern expat, int grp, int[][] dates, String[] titles, boolean randomizeTimeOfDay, Integer... params) throws Exception { InputStream is = mActivity.getResources().getAssets().open("Kein Fehler im System.txt"); MatchResult[] excerpts = excerptsFrom(is, expat); Integer start = param(0, 0, params); Integer length = param(dates != null ? dates.length : 0, 1, params); Uri uri = NotePadProvider.contentUri(0); ContentResolver contentResolver = mActivity.getContentResolver(); if (clear) { contentResolver.delete(uri, "", null); } int cnt = 0; long time = dateFromTodayInMillis(0); String title = ""; for (int i = start; i < excerpts.length; i++) { MatchResult m = excerpts[i]; int j = i - start; if (isAvailable(j, titles)) title = titles[j]; time = dates != null && j < dates.length ? timeInMillis(dates[j][0], dates[j][1], dates[j][2]) : dateFromTodayInMillis(1, new Date(time), randomizeTimeOfDay); long[] interval = dayInterval(time, 1); ContentValues values = new ContentValues(); values.put("note", m.group(grp)); values.put("title", title); values.put("created", time); values.put("modified", now()); Cursor c = contentResolver.query(uri, strings("_id"), "created between ? and ? and title = ?", strings("" + interval[0], "" + (interval[1] - 1), title), null); boolean update = c != null && c.moveToFirst(); if (update) assertEquals(1, contentResolver.update(uri, values, "_id=?", strings("" + c.getLong(0)))); else assertTrue(contentResolver.insert(uri, values) instanceof Uri); cnt++; if (j >= length - 1) break; } return cnt; } public ValMap results(final int kind) { String sql; switch (kind) { case 1: sql = "select count(*) from notes"; break; case 0: sql = "select title,count(_id) from notes group by title"; break; default: return null; } ContentResolver contentResolver = mActivity.getContentResolver(); return getResults(contentResolver.query(contentUri(NotePad.AUTHORITY, null), null, sql, null, null), new Function<String>() { public String apply(Object... params) { Cursor cursor = param(null, 0, params); switch (kind) { case 1: return "count"; case 0: return cursor.getString(0); default: return null; } } }, new Function<Object>() { public Object apply(Object... params) { Cursor cursor = param(null, 0, params); switch (kind) { case 1: return cursor.getInt(0); case 0: return cursor.getInt(1); default: return null; } } } ); } Pattern expat = Pattern.compile("(?s)\\n([^\\{\\}]+?)(?=\\n)"); int[] date = ints(2012, -Calendar.DECEMBER, 24); public void keinFehlerImSystemm() throws Exception { int[][] dates = new int[][] {date}; int length = 19; assertEquals(length, generateNotes(true, expat, 1, dates, strings("1."), false, 2, length)); length = 7; assertEquals(length, generateNotes(false, expat, 1, dates, strings("2."), false, 21, length)); length = 10; assertEquals(length, generateNotes(false, expat, 1, dates, strings("3."), false, 28, length)); assertEquals(36, results(1).get("count")); } public static void generateNotePadData(Context context, boolean clear, Object[][] records) { ContentResolver contentResolver = context.getContentResolver(); if (clear) { for (int i = 0; i < 3; i++) contentResolver.delete(NotePadProvider.contentUri(i), "", null); } Uri uri = null; long id = -1; for (int i = 0; i < records.length; i++) { Object[] record = records[i]; int index = Arrays.asList(record).indexOf("ROWID"); if (index > -1) record[index] = id; int tableIndex = record[3] == null ? 1 : (record[2] == null ? 2 : 0); ContentValues values = NotePadProvider.contentValues(tableIndex, record); uri = contentResolver.insert(NotePadProvider.contentUri(tableIndex), values); assertEquals(NoteColumns.CONTENT_ITEM_TYPE, contentResolver.getType(uri)); if (index < 0) id = toLong(-1L, uri.getPathSegments().get(1)); } } public static void generateData(ContentResolver contentResolver, Uri uri, boolean clear, Object[][] records) { assertTrue(contentResolver.getType(uri).startsWith(ContentResolver.CURSOR_DIR_BASE_TYPE)); if (clear) { contentResolver.delete(uri, null, null); } try { Class<?> c = Class.forName(uri.getAuthority() + "Provider"); Method contentValues = c.getDeclaredMethod("contentValues", Integer.TYPE, Object[].class); for (int i = 0; i < records.length; i++) { Object[] record = records[i]; ContentValues values = (ContentValues) contentValues.invoke(null, 0, record); Uri urItem = contentResolver.insert(uri, values); assertTrue(contentResolver.getType(urItem).startsWith(ContentResolver.CURSOR_ITEM_BASE_TYPE)); } } catch (Exception e) { Log.e(TAG, "generateData", e); }; } public static void generateTestData(Context context) { long now = now(); generateNotePadData(context, true, new Object[][] { { 1L, "kein", "Kein", null, now }, { 2L, "fehler", "Fehler", null, now }, { 3L, "efhler", "eFhler", null, now }, { 4L, "ehfler", "ehFler", null, now }, { 5L, "im", "in dem", null, -now }, { 6L, "system", "System", null, now }, { 1L, "Velocity1", "$kein $fehler $im $system", now, now }, { 1L, "System", null, 1L, null }, { 2L, "Kein", null, 1L, null }, { 2L, "Velocity2", "$kein $efhler $im $system", now, now }, { 3L, "Fehler", null, 2L, null }, { 4L, "Kein", null, 2L, null }, { 3L, "Velocity3", "$kein $ehfler $im $system", now, now }, { 5L, "Fehler", null, 3L, null }, { 6L, "Kein", null, 3L, null }, }); } public void testData() throws Exception { String dbName = NotePadProvider.DATABASE_NAME; mActivity.deleteDatabase(dbName); generateTestData(mActivity); keepTestData(strings(dbName)); } public void testData3() throws Exception { for (String database : databases(mActivity)) mActivity.deleteDatabase(database); String helloVm = readAsset(mActivity, "hello.vm"); String[] states = getStateStrings(mActivity); generateNotePadData(mActivity, true, new Object[][] { { 1L, "prompt1", "#set($var=\"\")" + "#prompt(\"name\" $var \"xxx\")#if($var)$var\n#end", null, now() }, { 2L, "prompt2", "#set($var=\"\")" + "#prompt(\"ja oder nein\",$var,[\"ja\",\"nein\"])#if($var)$var\n#end" + "#prompt(\"hello or world or cancel\",$var,[\"hello\",\"world\"] true)#if($var)$var\n#end", null, now() }, { 3L, "prompt3", "#set($var=[\"Kein\",\"Fehler\"])" + "#prompt(\"Mehrfachauswahl\" $var [\"Kein\",\"Fehler\",\"im\",\"System\"] true)#if($var)$var\n#end" + "#prompt(\"Einzelauswahl\",$var,[\"Kein\",\"Fehler\",\"im\",\"System\"])#if($var)$var\n#end", null, now() }, { 4L, "spinner", "#spinner(\"states\",$var)" + join("\n", states) + "#end\n#if($var)$var\n#end", null, now() }, { 5L, "cursor", "#cursor(\"plants\",$var," + quoted(PlantInfo.Plants.CONTENT_URI.toString()) + "," + "[" + quoted(PlantInfo.Plants.NAME) + "," + quoted(PlantInfo.Plants._ID) + "," + quoted(PlantInfo.Plants.BOTNAME) + "," + quoted(PlantInfo.Plants.BOTFAMILY) + "])#if($var)$var\n#end", null, now() }, { 6L, "random", "$math.random is a random number", null, now() }, { 7L, "random2", "#set($lower=1)#set($upper=20)" + "$math.random($lower, $upper) is a random number between $lower and $upper", null, now() }, { 8L, "planets", "#set( $Planets = ['Mercury', 'Earth', 'Mars', 'Venus'] )$Planets\n" + "#set( $pLanets = ['Jupiter', 'Saturn', 'Neptune'] )$pLanets\n" + "#set( $plAnets = ['Uranus', 'Pluto', 'Neptune'] )$plAnets\n" + "#set( $plaNets = ['Jupiter', 'Saturn', 'Mars'] )$plaNets\n" + "#set( $planEts = ['Jupiter', 'Venus', 'Neptune'] )$planEts\n" + "#set( $planeTs = ['Earth', 'Saturn', 'Neptune'] )$planeTs\n" + "#set( $planetS = ['Mercury', 'Saturn', 'Neptune'] )$planetS\n" + "#set( $Planets = ['Jupiter', 'Earth', 'Neptune'] )$Planets\n" + "#set( $pLanets = ['Jupiter', 'Saturn', 'Mars'] )$pLanets\n" + "#set( $planets = ['Venus', 'Saturn', 'Neptune'] )\n" + "$planets", null, now() }, { 9L, "hello", helloVm, null, now() }, }); assertEquals(9, recordCount(mActivity, NotePadProvider.contentUri(1))); keinFehlerImSystemm(); generateData(mActivity.getContentResolver(), Plants.CONTENT_URI, true, new Object[][] { { 1L, "Paradeiser", "Nachtschattengewächse", "Solanum lycopersicum", "Solanaceae", "xitomatl" }, { 2L, "chili pepper", "nightshade", "Capsicum", "Solanaceae", "xilli" }, { 3L, "Melanzani", "Nachtschattengewächse", "Solanum melongena", "Solanaceae", "ratatouille" }, { 4L, "potato", "nightshade", "Solanum tuberosum", "Solanaceae", "tartufolo" }, { 5L, "Tobak", "Nachtschattengewächse", "Nicotiana tabacum", "Solanaceae", "tobacco" }, }); assertEquals(5, recordCount(mActivity, Plants.CONTENT_URI)); generateData(mActivity.getContentResolver(), Weathers.CONTENT_URI, true, new Object[][] { { 1L, "here", "overcast", 11.1f, 1f, -1f, 0l, now() }, }); assertEquals(1, recordCount(mActivity, Weathers.CONTENT_URI)); keepTestData(databases(mActivity)); } public static String[] getStateStrings(Context context) { try { InputStream is = context.getResources().openRawResource(R.raw.states); String res = readAll(new BufferedReader(new InputStreamReader(is, Charset.forName("UTF-8")))); return toStrings(((ValList) walkJSON(null, new JSONArray(res), null))); } catch (Exception e) { fail(e.getMessage()); return null; } } private Cursor notesCursor(int tableIndex, String selection, String... selectionArgs) { Cursor cursor = mActivity.managedQuery( NotePadProvider.contentUri(tableIndex), NotePadProvider.FULL_PROJECTION, selection, selectionArgs, NoteColumns.DEFAULT_SORT_ORDER); assertNotNull(cursor); return cursor; } private void fullRecord(Cursor cursor) { assertEquals(5, cursor.getColumnCount()); Object[] values = new Object[5]; values[0] = cursor.getLong(0); values[1] = cursor.getString(1); values[2] = cursor.getString(2); values[3] = cursor.getLong(3); values[4] = cursor.getLong(4); Log.i(TAG, Arrays.toString(values)); } public ValMap noteMap(int tableIndex, String selection, String... selectionArgs) { Cursor cursor = notesCursor(tableIndex, selection, selectionArgs); ValMap map = getResults(cursor, new Function<String>() { public String apply(Object... params) { Cursor cursor = param(null, 0, params); assertTrue(cursor != null); fullRecord(cursor); return cursor.getString(1); } }, new Function<Object>() { public String apply(Object... params) { Cursor cursor = param(null, 0, params); assertTrue(cursor != null); return cursor.getString(2); } } ); return map; } public void testNotePadProvider() throws InterruptedException { mActivity.deleteDatabase(NotePadProvider.DATABASE_NAME); ContentResolver contentResolver = mActivity.getContentResolver(); setContentObserver(contentResolver, NoteColumns.CONTENT_URI); long now = now(); generateNotePadData(mActivity, true, new Object[][] { { 1L, "kein", "Kein", null, now }, { 2L, "fehler", "Fehler", null, now }, { 3L, "efhler", "eFhler", null, now }, { 4L, "ehfler", "ehFler", null, now }, { 5L, "im", "im", null, now }, { 6L, "system", "System", null, now }, { 1L, "Velocity1", "$kein $fehler $im $system", now, now }, { 2L, "Velocity2", "$kein $efhler $im $system", now, now }, { 3L, "Velocity3", "$kein $ehfler $im $system", now, now }, }); ValMap noteMap = noteMap(0, "title like ?", "Velocity%"); assertEquals(3, noteMap.size()); CustomContext noteContext = new CustomContext(noteMap(1, "")); assertEquals(6, noteContext.getKeys().length); com.applang.UserContext.setupVelocity(mActivity, true, getPackageNameByClass(R.class)); ValList list = vlist(); Cursor cursor = notesCursor(0, "title like ?", "Velocity%"); assertTrue(cursor.moveToFirst()); long id = 0; do { String note = cursor.getString(2); note = evaluate(noteContext, note, "notes"); assertFalse(note.contains("$")); if (!note.contains("Fehler")) { long refId = cursor.getLong(0); ContentValues values = NotePadProvider.contentValues(0, ++id, "Fehler", null, refId, null); list.add(values); } System.out.println(note); } while (cursor.moveToNext()); cursor.close(); for (Object item : list) { ContentValues values = (ContentValues) item; Uri uri = contentResolver.insert(NotePadProvider.contentUri(2), values); assertEquals(NoteColumns.CONTENT_ITEM_TYPE, contentResolver.getType(uri)); } noteMap(2, ""); for (int i = 0; i < 2; i++) assertEquals( new int[]{3,6,2}[i], NotePadProvider.countNotes(contentResolver, i, "", null)[0].intValue()); keepTestData(strings(NotePadProvider.DATABASE_NAME)); assertEquals(1, contentResolver.delete(NotePadProvider.contentUri(0), NoteColumns.TITLE + "=?", new String[]{"Velocity2"})); for (int i = 0; i < 2; i++) assertEquals( new int[]{2,6,1}[i], NotePadProvider.countNotes(contentResolver, i, "", null)[0].intValue()); assertEquals(androidLevel < 1 ? 15 : 5, contentObservations); } public void testNotePadProvider2() throws Exception { mActivity.deleteDatabase(NotePadProvider.DATABASE_NAME); long now = now(); Object[][] records = new Object[][] { { 1L, "kein", "Kein", null, now }, { 2L, "fehler", "Fehler", null, now }, { 3L, "efhler", "eFhler", null, now }, { 4L, "ehfler", "ehFler", null, now }, { 5L, "im", "im", null, now }, { 6L, "system", "System", null, now }, { 1L, "Velocity1", "$kein $fehler $im $system", now, now }, { 2L, "Velocity2", "$kein $efhler $im $system", now, now }, { 3L, "Velocity3", "$kein $ehfler $im $system", now, now }, }; generateNotePadData(mActivity, true, records); ContentResolver contentResolver = mActivity.getContentResolver(); for (int i = 0; i < 2; i++) switch (i) { case 0: assertEquals(3, NotePadProvider.getTitles(contentResolver, i, null, null).length); for (int j = 6; j < 9; j++) { long id = (Long) records[j][0]; assertEquals(id, NotePadProvider.getIdOfNote(contentResolver, i, NoteColumns.CREATED_DATE + "=? and " + NoteColumns.TITLE + "=?", strings("" + records[j][3], "" + records[j][1]))); assertTrue(NotePadProvider.fetchNoteById(id, contentResolver, i, null)); } break; case 1: assertEquals(6, NotePadProvider.getTitles(contentResolver, i, null, null).length); for (int j = 0; j < 6; j++) { long id = (Long) records[j][0]; assertEquals(id, NotePadProvider.getIdOfNote(contentResolver, i, NoteColumns.CREATED_DATE + " is null and " + NoteColumns.TITLE + "=?", strings("" + records[j][1]))); assertTrue(NotePadProvider.fetchNoteById(id, contentResolver, i, null)); } break; } } public void testWeatherInfoProvider() throws IOException { mActivity.deleteDatabase(WeatherInfoProvider.DATABASE_NAME); ContentResolver contentResolver = mActivity.getContentResolver(); setContentObserver(contentResolver, Weathers.CONTENT_URI); generateData(contentResolver, Weathers.CONTENT_URI, true, new Object[][] { { 1L, "here", "overcast", 11.1f, 1f, -1f, 0l, }, }); ContentValues values = new ContentValues(); values.put(Weathers.MODIFIED_DATE, now()); assertEquals(1, contentResolver.update(Weathers.CONTENT_URI, values, Weathers.LOCATION + "=?", new String[]{"here"})); Cursor cursor = contentResolver.query( Weathers.CONTENT_URI, WeatherInfoProvider.FULL_PROJECTION, Weathers.LOCATION + "=?", new String[]{"here"}, Weathers.DEFAULT_SORT_ORDER); assertEquals(1, cursor.getCount()); assertTrue(cursor.moveToFirst()); assertEquals("here", cursor.getString(2)); assertEquals("overcast", cursor.getString(1)); assertEquals(11.1f, cursor.getFloat(3)); cursor.close(); assertEquals(3, contentObservations); }; public void testPlantInfoProvider() throws IOException { mActivity.deleteDatabase(PlantInfoProvider.DATABASE_NAME); ContentResolver contentResolver = mActivity.getContentResolver(); setContentObserver(contentResolver, PlantInfoProvider.contentUri(0)); generateData(contentResolver, PlantInfoProvider.contentUri(0), false, new Object[][] { { 1L, "Paradeiser", "Nachtschattengewächse", "Solanum lycopersicum", "Solanaceae", "" }, }); ContentValues values = new ContentValues(); values.put(Plants.GROUP, "xitomatl"); assertEquals(1, contentResolver.update(Plants.CONTENT_URI, values, Plants.NAME + "=?", new String[]{"Paradeiser"})); Cursor cursor = contentResolver.query( Plants.CONTENT_URI, PlantInfoProvider.FULL_PROJECTION, Plants.NAME + "=?", new String[]{"Paradeiser"}, Plants.DEFAULT_SORT_ORDER); assertEquals(1, cursor.getCount()); assertTrue(cursor.moveToFirst()); assertEquals("Paradeiser", cursor.getString(1)); assertEquals("Solanum lycopersicum", cursor.getString(3)); assertEquals("xitomatl", cursor.getString(5)); cursor.close(); assertEquals(2, contentObservations); // 1 insert, 1 update }; private String[] PROJECTION_ID = new String[] { Plants._ID, // 0 }; public void testgetAllEntries() throws IOException { ContentResolver contentResolver = mActivity.getContentResolver(); contentResolver.delete(Plants.CONTENT_URI, null, null); assertEquals(0, contentResolver.query( Plants.CONTENT_URI, PlantInfoProvider.FULL_PROJECTION, null, null, null).getCount()); for (int i = 1; i < 21; i++) { String insertName = "testName" + i; ContentValues values = new ContentValues(); values.put(Plants.NAME, insertName); contentResolver.insert(Plants.CONTENT_URI, values); if (i%2 == 0) { String deleteName = "testName" + (i - 1); contentResolver.delete(Plants.CONTENT_URI, Plants.NAME + "=?", new String[]{deleteName}); } } Cursor cursor = contentResolver.query( Plants.CONTENT_URI, PROJECTION_ID, null, null, Plants.ROWID_SORT_ORDER); assertEquals(10, cursor.getCount()); assertTrue(cursor.moveToFirst()); for ( int i= 1; i < 21;i++) { if (i%2 == 0) { assertEquals(i, cursor.getInt(0)); cursor.moveToNext(); } } }; @SuppressWarnings("rawtypes") public void testMisc() throws Exception { File filesDir = mActivity.getFilesDir(); System.out.printf("filesDir : %s\n", filesDir.getPath()); FileOutputStream outStream = mActivity.openFileOutput("hello", Context.MODE_PRIVATE); outStream.write("hello".getBytes()); outStream.close(); System.out.printf("fileList : %s\n", asList(mActivity.fileList())); System.out.printf("dir 'xxx' : %s\n", mActivity.getDir("xxx", Context.MODE_PRIVATE)); for (String pkg : providerPackages) { Class[] cls = getLocalClasses(pkg, mActivity); System.out.println(com.applang.Util.toString(cls)); for (Class cl : filter(asList(cls), false, new Predicate<Class>() { public boolean apply(Class c) { String name = c.getName(); return !name.contains("$") && !name.endsWith("Provider"); } })) System.out.println(cl.toString()); } ValList list = contentAuthorities(providerPackages, mActivity); System.out.println(list); System.out.println(asList(databases(mActivity))); ContentResolver contentResolver = mActivity.getContentResolver(); list = vlist(); Uri uri = NotePadProvider.contentUri(null); Cursor cursor = contentResolver.query(uri, null, "select name from sqlite_master where type = 'table'", null, null); if (cursor.moveToFirst()) do { list.add(cursor.getString(0)); } while (cursor.moveToNext()); cursor.close(); System.out.println(list.toString()); Map<String,String> anweisungen = UserContext.directives(); for (String key : anweisungen.keySet()) { System.out.println(anweisungen.get(key)); } } }