Search in sources :

Example 41 with CHANGED

use of com.ichi2.anki.CardBrowser.Column.CHANGED in project AnkiChinaAndroid by ankichinateam.

the class CardTemplateEditorTest method testEditTemplateContents.

@Test
@SuppressWarnings("PMD.NPathComplexity")
public void testEditTemplateContents() throws Exception {
    String modelName = "Basic";
    // Start the CardTemplateEditor with a specific model, and make sure the model starts unchanged
    JSONObject collectionBasicModelOriginal = getCurrentDatabaseModelCopy(modelName);
    Intent intent = new Intent(Intent.ACTION_VIEW);
    intent.putExtra("modelId", collectionBasicModelOriginal.getLong("id"));
    ActivityController<CardTemplateEditor> templateEditorController = Robolectric.buildActivity(CardTemplateEditor.class, intent).create().start().resume().visible();
    saveControllerForCleanup(templateEditorController);
    CardTemplateEditor testEditor = (CardTemplateEditor) templateEditorController.get();
    Assert.assertFalse("Model should not have changed yet", testEditor.modelHasChanged());
    // Change the model and make sure it registers as changed, but the database is unchanged
    EditText templateFront = testEditor.findViewById(R.id.front_edit);
    String TEST_MODEL_QFMT_EDIT = "!@#$%^&*TEST*&^%$#@!";
    templateFront.getText().append(TEST_MODEL_QFMT_EDIT);
    advanceRobolectricLooper();
    Assert.assertTrue("Model did not change after edit?", testEditor.modelHasChanged());
    Assert.assertEquals("Change already in database?", collectionBasicModelOriginal.toString().trim(), getCurrentDatabaseModelCopy(modelName).toString().trim());
    // Kill and restart the Activity, make sure model edit is preserved
    Bundle outBundle = new Bundle();
    templateEditorController.saveInstanceState(outBundle);
    templateEditorController.pause().stop().destroy();
    templateEditorController = Robolectric.buildActivity(CardTemplateEditor.class).create(outBundle).start().resume().visible();
    saveControllerForCleanup(templateEditorController);
    testEditor = (CardTemplateEditor) templateEditorController.get();
    ShadowActivity shadowTestEditor = shadowOf(testEditor);
    Assert.assertTrue("model change not preserved across activity lifecycle?", testEditor.modelHasChanged());
    Assert.assertEquals("Change already in database?", collectionBasicModelOriginal.toString().trim(), getCurrentDatabaseModelCopy(modelName).toString().trim());
    // Make sure we get a confirmation dialog if we hit the back button
    Assert.assertTrue("Unable to click?", shadowTestEditor.clickMenuItem(android.R.id.home));
    advanceRobolectricLooper();
    Assert.assertEquals("Wrong dialog shown?", getDialogText(true), getResourceString(R.string.discard_unsaved_changes));
    clickDialogButton(DialogAction.NEGATIVE, true);
    advanceRobolectricLooper();
    Assert.assertTrue("model change not preserved despite canceling back button?", testEditor.modelHasChanged());
    // Make sure we things are cleared out after a cancel
    Assert.assertTrue("Unable to click?", shadowTestEditor.clickMenuItem(android.R.id.home));
    Assert.assertEquals("Wrong dialog shown?", getDialogText(true), getResourceString(R.string.discard_unsaved_changes));
    clickDialogButton(DialogAction.POSITIVE, true);
    advanceRobolectricLooper();
    Assert.assertFalse("model change not cleared despite discarding changes?", testEditor.modelHasChanged());
    // Get going for content edit assertions again...
    templateEditorController = Robolectric.buildActivity(CardTemplateEditor.class, intent).create().start().resume().visible();
    saveControllerForCleanup(templateEditorController);
    testEditor = (CardTemplateEditor) templateEditorController.get();
    shadowTestEditor = shadowOf(testEditor);
    templateFront = testEditor.findViewById(R.id.front_edit);
    templateFront.getText().append(TEST_MODEL_QFMT_EDIT);
    advanceRobolectricLooper();
    Assert.assertTrue("Model did not change after edit?", testEditor.modelHasChanged());
    // Make sure we pass the edit to the Previewer
    Assert.assertTrue("Unable to click?", shadowTestEditor.clickMenuItem(R.id.action_preview));
    advanceRobolectricLooper();
    Intent startedIntent = shadowTestEditor.getNextStartedActivity();
    ShadowIntent shadowIntent = shadowOf(startedIntent);
    advanceRobolectricLooper();
    Assert.assertEquals("Previewer not started?", CardTemplatePreviewer.class.getName(), shadowIntent.getIntentClass().getName());
    Assert.assertNotNull("intent did not have model JSON filename?", startedIntent.getStringExtra(TemporaryModel.INTENT_MODEL_FILENAME));
    Assert.assertNotEquals("Model sent to Previewer is unchanged?", testEditor.getTempModel().getModel(), TemporaryModel.getTempModel(startedIntent.getStringExtra(TemporaryModel.INTENT_MODEL_FILENAME)));
    Assert.assertEquals("Change already in database?", collectionBasicModelOriginal.toString().trim(), getCurrentDatabaseModelCopy(modelName).toString().trim());
    shadowTestEditor.receiveResult(startedIntent, Activity.RESULT_OK, new Intent());
    // Save the template then fetch it from the collection to see if it was saved correctly
    JSONObject testEditorModelEdited = testEditor.getTempModel().getModel();
    advanceRobolectricLooper();
    Assert.assertTrue("Unable to click?", shadowTestEditor.clickMenuItem(R.id.action_confirm));
    advanceRobolectricLooper();
    JSONObject collectionBasicModelCopyEdited = getCurrentDatabaseModelCopy(modelName);
    Assert.assertNotEquals("model is unchanged?", collectionBasicModelOriginal, collectionBasicModelCopyEdited);
    Assert.assertEquals("model did not save?", testEditorModelEdited.toString().trim(), collectionBasicModelCopyEdited.toString().trim());
    Assert.assertTrue("model does not have our change?", collectionBasicModelCopyEdited.toString().contains(TEST_MODEL_QFMT_EDIT));
}
Also used : EditText(android.widget.EditText) ShadowIntent(org.robolectric.shadows.ShadowIntent) JSONObject(com.ichi2.utils.JSONObject) Bundle(android.os.Bundle) ShadowActivity(org.robolectric.shadows.ShadowActivity) ShadowIntent(org.robolectric.shadows.ShadowIntent) Intent(android.content.Intent) Test(org.junit.Test)

Example 42 with CHANGED

use of com.ichi2.anki.CardBrowser.Column.CHANGED in project AnkiChinaAndroid by ankichinateam.

the class CardTemplateEditorTest method testDeletePendingAddExistingCardCount.

/**
 * Deleting a template you just added - but in the same ordinal as a previous pending delete - should get it's card count correct
 */
@SuppressWarnings("PMD.ExcessiveMethodLength")
@Test
public void testDeletePendingAddExistingCardCount() {
    String modelName = "Basic (optional reversed card)";
    Model collectionBasicModelOriginal = getCurrentDatabaseModelCopy(modelName);
    // Start the CardTemplateEditor with a specific model, and make sure the model starts unchanged
    Intent intent = new Intent(Intent.ACTION_VIEW);
    intent.putExtra("modelId", collectionBasicModelOriginal.getLong("id"));
    ActivityController<CardTemplateEditor> templateEditorController = Robolectric.buildActivity(CardTemplateEditor.class, intent).create().start().resume().visible();
    saveControllerForCleanup(templateEditorController);
    CardTemplateEditor testEditor = (CardTemplateEditor) templateEditorController.get();
    Assert.assertFalse("Model should not have changed yet", testEditor.modelHasChanged());
    Assert.assertEquals("Model should have 2 templates now", 2, testEditor.getTempModel().getTemplateCount());
    Assert.assertFalse("Ordinal pending add?", TemporaryModel.isOrdinalPendingAdd(testEditor.getTempModel(), 0));
    Assert.assertFalse("Ordinal pending add?", TemporaryModel.isOrdinalPendingAdd(testEditor.getTempModel(), 1));
    // Create note with forward and back info
    Note selectiveGeneratedNote = getCol().newNote(collectionBasicModelOriginal);
    selectiveGeneratedNote.setField(0, "TestFront");
    selectiveGeneratedNote.setField(1, "TestBack");
    selectiveGeneratedNote.setField(2, "y");
    getCol().addNote(selectiveGeneratedNote);
    Assert.assertEquals("card generation should result in two cards", 2, getModelCardCount(collectionBasicModelOriginal));
    // Delete ord 1 / 'Card 2' and check the message
    ShadowActivity shadowTestEditor = shadowOf(testEditor);
    testEditor.mViewPager.setCurrentItem(1);
    Assert.assertTrue("Unable to click?", shadowTestEditor.clickMenuItem(R.id.action_delete));
    advanceRobolectricLooper();
    Assert.assertEquals("Did not show dialog about deleting template and it's card?", getQuantityString(R.plurals.card_template_editor_confirm_delete, 1, 1, "Card 2"), getDialogText(true));
    clickDialogButton(DialogAction.POSITIVE, true);
    advanceRobolectricLooper();
    Assert.assertTrue("Model should have changed", testEditor.modelHasChanged());
    Assert.assertNotNull("Cannot delete template?", getCol().getModels().getCardIdsForModel(collectionBasicModelOriginal.getLong("id"), new int[] { 0 }));
    Assert.assertNotNull("Cannot delete template?", getCol().getModels().getCardIdsForModel(collectionBasicModelOriginal.getLong("id"), new int[] { 1 }));
    Assert.assertNull("Can delete both templates?", getCol().getModels().getCardIdsForModel(collectionBasicModelOriginal.getLong("id"), new int[] { 0, 1 }));
    Assert.assertEquals("Change in database despite no save?", collectionBasicModelOriginal.toString().trim(), getCurrentDatabaseModelCopy(modelName).toString().trim());
    Assert.assertEquals("Model should have 1 template", 1, testEditor.getTempModel().getTemplateCount());
    // Add a template - click add, click confirm for card add, click confirm again for full sync
    shadowTestEditor.clickMenuItem(R.id.action_add);
    advanceRobolectricLooper();
    Assert.assertTrue("Model should have changed", testEditor.modelHasChanged());
    Assert.assertEquals("Change added but not adjusted correctly?", 1, TemporaryModel.getAdjustedAddOrdinalAtChangeIndex(testEditor.getTempModel(), 1));
    Assert.assertFalse("Ordinal pending add?", TemporaryModel.isOrdinalPendingAdd(testEditor.getTempModel(), 0));
    Assert.assertTrue("Ordinal not pending add?", TemporaryModel.isOrdinalPendingAdd(testEditor.getTempModel(), 1));
    Assert.assertEquals("Model should have 2 templates", 2, testEditor.getTempModel().getTemplateCount());
    // Delete ord 1 / 'Card 2' again and check the message - it's in the same spot as the pre-existing template but there are no cards actually associated
    testEditor.mViewPager.setCurrentItem(1);
    Assert.assertTrue("Unable to click?", shadowTestEditor.clickMenuItem(R.id.action_delete));
    advanceRobolectricLooper();
    Assert.assertEquals("Did not show dialog about deleting template and it's card?", getQuantityString(R.plurals.card_template_editor_confirm_delete, 0, 0, "Card 2"), getDialogText(true));
    clickDialogButton(DialogAction.POSITIVE, true);
    advanceRobolectricLooper();
    Assert.assertTrue("Model should have changed", testEditor.modelHasChanged());
    Assert.assertNotNull("Cannot delete template?", getCol().getModels().getCardIdsForModel(collectionBasicModelOriginal.getLong("id"), new int[] { 0 }));
    Assert.assertNotNull("Cannot delete template?", getCol().getModels().getCardIdsForModel(collectionBasicModelOriginal.getLong("id"), new int[] { 1 }));
    Assert.assertNull("Can delete both templates?", getCol().getModels().getCardIdsForModel(collectionBasicModelOriginal.getLong("id"), new int[] { 0, 1 }));
    Assert.assertEquals("Change in database despite no save?", collectionBasicModelOriginal.toString().trim(), getCurrentDatabaseModelCopy(modelName).toString().trim());
    Assert.assertEquals("Model should have 1 template", 1, testEditor.getTempModel().getTemplateCount());
    // Save it out and make some assertions
    Assert.assertTrue("Unable to click?", shadowTestEditor.clickMenuItem(R.id.action_confirm));
    advanceRobolectricLooper();
    Assert.assertFalse("Model should now be unchanged", testEditor.modelHasChanged());
    Assert.assertEquals("card generation should result in 1 card", 1, getModelCardCount(collectionBasicModelOriginal));
}
Also used : Note(com.ichi2.libanki.Note) Model(com.ichi2.libanki.Model) ShadowActivity(org.robolectric.shadows.ShadowActivity) ShadowIntent(org.robolectric.shadows.ShadowIntent) Intent(android.content.Intent) Test(org.junit.Test)

Example 43 with CHANGED

use of com.ichi2.anki.CardBrowser.Column.CHANGED in project AnkiChinaAndroid by ankichinateam.

the class CardTemplateEditorTest method testTemplateAdd.

@Test
public void testTemplateAdd() throws Exception {
    // Make sure we test previewing a new card template - not working for real yet
    String modelName = "Basic";
    JSONObject collectionBasicModelOriginal = getCurrentDatabaseModelCopy(modelName);
    Intent intent = new Intent(Intent.ACTION_VIEW);
    intent.putExtra("modelId", collectionBasicModelOriginal.getLong("id"));
    ActivityController<CardTemplateEditor> templateEditorController = Robolectric.buildActivity(CardTemplateEditor.class, intent).create().start().resume().visible();
    saveControllerForCleanup(templateEditorController);
    CardTemplateEditor testEditor = (CardTemplateEditor) templateEditorController.get();
    Assert.assertFalse("Ordinal pending add?", TemporaryModel.isOrdinalPendingAdd(testEditor.getTempModel(), 0));
    // Try to add a template - click add, click confirm for card add, click confirm again for full sync
    ShadowActivity shadowTestEditor = shadowOf(testEditor);
    Assert.assertTrue("Unable to click?", shadowTestEditor.clickMenuItem(R.id.action_add));
    advanceRobolectricLooper();
    // if AnkiDroid moves to match AnkiDesktop it will pop a dialog to confirm card create
    // Assert.assertEquals("Wrong dialog shown?", "This will create NN cards. Proceed?", getDialogText());
    // clickDialogButton(DialogAction.POSITIVE);
    Assert.assertTrue("Model should have changed", testEditor.modelHasChanged());
    Assert.assertEquals("Change not pending add?", 1, TemporaryModel.getAdjustedAddOrdinalAtChangeIndex(testEditor.getTempModel(), 0));
    Assert.assertFalse("Ordinal pending add?", TemporaryModel.isOrdinalPendingAdd(testEditor.getTempModel(), 0));
    Assert.assertTrue("Ordinal not pending add?", TemporaryModel.isOrdinalPendingAdd(testEditor.getTempModel(), 1));
    Assert.assertEquals("Model should have 2 templates now", 2, testEditor.getTempModel().getTemplateCount());
    // Make sure we pass the new template to the Previewer
    Assert.assertTrue("Unable to click?", shadowTestEditor.clickMenuItem(R.id.action_preview));
    Intent startedIntent = shadowTestEditor.getNextStartedActivity();
    ShadowIntent shadowIntent = shadowOf(startedIntent);
    Assert.assertEquals("Previewer not started?", CardTemplatePreviewer.class.getName(), shadowIntent.getIntentClass().getName());
    Assert.assertNotNull("intent did not have model JSON filename?", startedIntent.getStringExtra(TemporaryModel.INTENT_MODEL_FILENAME));
    Assert.assertEquals("intent did not have ordinal?", 1, startedIntent.getIntExtra("ordinal", -1));
    Assert.assertNotEquals("Model sent to Previewer is unchanged?", testEditor.getTempModel().getModel(), TemporaryModel.getTempModel(startedIntent.getStringExtra(TemporaryModel.INTENT_MODEL_FILENAME)));
    Assert.assertEquals("Change already in database?", collectionBasicModelOriginal.toString().trim(), getCurrentDatabaseModelCopy(modelName).toString().trim());
    // Save the change to the database and make sure there are two templates after
    JSONObject testEditorModelEdited = testEditor.getTempModel().getModel();
    Assert.assertTrue("Unable to click?", shadowTestEditor.clickMenuItem(R.id.action_confirm));
    advanceRobolectricLooper();
    JSONObject collectionBasicModelCopyEdited = getCurrentDatabaseModelCopy(modelName);
    Assert.assertNotEquals("model is unchanged?", collectionBasicModelOriginal, collectionBasicModelCopyEdited);
    Assert.assertEquals("model did not save?", testEditorModelEdited.toString().trim(), collectionBasicModelCopyEdited.toString().trim());
}
Also used : ShadowIntent(org.robolectric.shadows.ShadowIntent) JSONObject(com.ichi2.utils.JSONObject) ShadowActivity(org.robolectric.shadows.ShadowActivity) ShadowIntent(org.robolectric.shadows.ShadowIntent) Intent(android.content.Intent) Test(org.junit.Test)

Example 44 with CHANGED

use of com.ichi2.anki.CardBrowser.Column.CHANGED in project AnkiChinaAndroid by ankichinateam.

the class ImportTest method testAnki2DiffmodelTemplates.

@Test
public void testAnki2DiffmodelTemplates() throws IOException, JSONException, ImportExportException {
    // different from the above as this one tests only the template text being
    // changed, not the number of cards/fields
    // import the first version of the model
    String tmp = Shared.getTestFilePath(InstrumentationRegistry.getInstrumentation().getTargetContext(), "diffmodeltemplates-1.apkg");
    AnkiPackageImporter imp = new AnkiPackageImporter(testCol, tmp);
    imp.setDupeOnSchemaChange(true);
    imp.run();
    // then the version with updated template
    tmp = Shared.getTestFilePath(InstrumentationRegistry.getInstrumentation().getTargetContext(), "diffmodeltemplates-2.apkg");
    imp = new AnkiPackageImporter(testCol, tmp);
    imp.setDupeOnSchemaChange(true);
    imp.run();
    // collection should contain the note we imported
    assertEquals(1, testCol.noteCount());
    // the front template should contain the text added in the 2nd package
    Long tcid = testCol.findCards("").get(0);
    Note tnote = testCol.getCard(tcid).note();
    assertTrue(testCol.findTemplates(tnote).get(0).getString("qfmt").contains("Changed Front Template"));
}
Also used : AnkiPackageImporter(com.ichi2.libanki.importer.AnkiPackageImporter) Note(com.ichi2.libanki.Note) Test(org.junit.Test)

Example 45 with CHANGED

use of com.ichi2.anki.CardBrowser.Column.CHANGED in project AnkiChinaAndroid by ankichinateam.

the class Anki2Importer method _importNotes.

/**
 * Notes
 * ***********************************************************
 */
private void _importNotes() {
    // build guid -> (id,mod,mid) hash & map of existing note ids
    mNotes = new HashMap<>();
    Set<Long> existing = new HashSet<>();
    Cursor cur = null;
    try {
        cur = mDst.getDb().getDatabase().query("select id, guid, mod, mid from notes", null);
        while (cur.moveToNext()) {
            long id = cur.getLong(0);
            String guid = cur.getString(1);
            long mod = cur.getLong(2);
            long mid = cur.getLong(3);
            mNotes.put(guid, new Object[] { id, mod, mid });
            existing.add(id);
        }
    } finally {
        if (cur != null) {
            cur.close();
        }
    }
    // we may need to rewrite the guid if the model schemas don't match,
    // so we need to keep track of the changes for the card import stage
    mChangedGuids = new HashMap<>();
    // we ignore updates to changed schemas. we need to note the ignored
    // guids, so we avoid importing invalid cards
    mIgnoredGuids = new HashMap<>();
    // iterate over source collection
    ArrayList<Object[]> add = new ArrayList<>();
    int totalAddCount = 0;
    final int thresExecAdd = 1000;
    ArrayList<Object[]> update = new ArrayList<>();
    int totalUpdateCount = 0;
    final int thresExecUpdate = 1000;
    ArrayList<Long> dirty = new ArrayList<>();
    int totalDirtyCount = 0;
    final int thresExecDirty = 1000;
    int usn = mDst.usn();
    int dupes = 0;
    ArrayList<String> dupesIgnored = new ArrayList<>();
    try {
        mDst.getDb().getDatabase().beginTransaction();
        cur = mSrc.getDb().getDatabase().query("select * from notes", null);
        // Counters for progress updates
        int total = cur.getCount();
        boolean largeCollection = total > 200;
        int onePercent = total / 100;
        int i = 0;
        while (cur.moveToNext()) {
            // turn the db result into a mutable list
            Object[] note = new Object[] { cur.getLong(0), cur.getString(1), cur.getLong(2), cur.getLong(3), cur.getInt(4), cur.getString(5), cur.getString(6), cur.getString(7), cur.getLong(8), cur.getInt(9), cur.getString(10) };
            boolean shouldAdd = _uniquifyNote(note);
            if (shouldAdd) {
                // ensure id is unique
                while (existing.contains(note[0])) {
                    note[0] = ((Long) note[0]) + 999;
                }
                existing.add((Long) note[0]);
                // bump usn
                note[4] = usn;
                // update media references in case of dupes
                note[6] = _mungeMedia((Long) note[MID], (String) note[6]);
                add.add(note);
                dirty.add((Long) note[0]);
                // note we have the added guid
                mNotes.put((String) note[GUID], new Object[] { note[0], note[3], note[MID] });
            } else {
                // a duplicate or changed schema - safe to update?
                dupes += 1;
                if (mAllowUpdate) {
                    Object[] n = mNotes.get(note[GUID]);
                    long oldNid = (Long) n[0];
                    long oldMod = (Long) n[1];
                    long oldMid = (Long) n[2];
                    // will update if incoming note more recent
                    if (oldMod < (Long) note[MOD]) {
                        // safe if note types identical
                        if (oldMid == (Long) note[MID]) {
                            // incoming note should use existing id
                            note[0] = oldNid;
                            note[4] = usn;
                            note[6] = _mungeMedia((Long) note[MID], (String) note[6]);
                            update.add(note);
                            dirty.add((Long) note[0]);
                        } else {
                            dupesIgnored.add(String.format("%s: %s", mCol.getModels().get(oldMid).getString("name"), ((String) note[6]).replace("\u001f", ",")));
                            mIgnoredGuids.put((String) note[GUID], true);
                        }
                    }
                }
            }
            i++;
            // add to col partially, so as to avoid OOM
            if (add.size() >= thresExecAdd) {
                totalAddCount += add.size();
                addNotes(add);
                add.clear();
                Timber.d("add notes: %d", totalAddCount);
            }
            // add to col partially, so as to avoid OOM
            if (update.size() >= thresExecUpdate) {
                totalUpdateCount += update.size();
                updateNotes(update);
                update.clear();
                Timber.d("update notes: %d", totalUpdateCount);
            }
            // add to col partially, so as to avoid OOM
            if (dirty.size() >= thresExecDirty) {
                totalDirtyCount += dirty.size();
                long[] das = Utils.collection2Array(dirty);
                mDst.updateFieldCache(das);
                mDst.getTags().registerNotes(das);
                dirty.clear();
                Timber.d("dirty notes: %d", totalDirtyCount);
            }
            if (total != 0 && (!largeCollection || i % onePercent == 0)) {
                // Calls to publishProgress are reasonably expensive due to res.getString()
                publishProgress(i * 100 / total, 0, 0);
            }
        }
        publishProgress(100, 0, 0);
        // summarize partial add/update/dirty results for total values
        totalAddCount += add.size();
        totalUpdateCount += update.size();
        totalDirtyCount += dirty.size();
        if (dupes > 0) {
            mLog.add(getRes().getString(R.string.import_update_details, totalUpdateCount, dupes));
            if (dupesIgnored.size() > 0) {
                mLog.add(getRes().getString(R.string.import_update_ignored));
            }
        }
        // export info for calling code
        mDupes = dupes;
        mAdded = totalAddCount;
        mUpdated = totalUpdateCount;
        Timber.d("add notes total:    %d", totalAddCount);
        Timber.d("update notes total: %d", totalUpdateCount);
        Timber.d("dirty notes total:  %d", totalDirtyCount);
        // add to col (for last chunk)
        addNotes(add);
        add.clear();
        updateNotes(update);
        update.clear();
        mDst.getDb().getDatabase().setTransactionSuccessful();
    } finally {
        if (cur != null) {
            cur.close();
        }
        if (mDst.getDb().getDatabase().inTransaction()) {
            try {
                mDst.getDb().getDatabase().endTransaction();
            } catch (Exception e) {
                Timber.w(e);
            }
        }
    }
    long[] das = Utils.collection2Array(dirty);
    mDst.updateFieldCache(das);
    mDst.getTags().registerNotes(das);
}
Also used : ArrayList(java.util.ArrayList) Cursor(android.database.Cursor) ConfirmModSchemaException(com.ichi2.anki.exception.ConfirmModSchemaException) ImportExportException(com.ichi2.anki.exception.ImportExportException) IOException(java.io.IOException) FileNotFoundException(java.io.FileNotFoundException) HashSet(java.util.HashSet)

Aggregations

JSONObject (com.ichi2.utils.JSONObject)19 Test (org.junit.Test)19 Note (com.ichi2.libanki.Note)16 Card (com.ichi2.libanki.Card)15 Collection (com.ichi2.libanki.Collection)15 Model (com.ichi2.libanki.Model)12 Intent (android.content.Intent)9 JSONArray (com.ichi2.utils.JSONArray)9 JSONException (com.ichi2.utils.JSONException)8 List (java.util.List)7 ShadowActivity (org.robolectric.shadows.ShadowActivity)7 ArrayList (java.util.ArrayList)6 Map (java.util.Map)6 ShadowIntent (org.robolectric.shadows.ShadowIntent)6 ConfirmModSchemaException (com.ichi2.anki.exception.ConfirmModSchemaException)5 Cursor (android.database.Cursor)4 MatrixCursor (android.database.MatrixCursor)4 TaskData (com.ichi2.async.TaskData)4 Deck (com.ichi2.libanki.Deck)4 AbstractSched (com.ichi2.libanki.sched.AbstractSched)4