Commit 3e9ac10f authored by Lückemeyer's avatar Lückemeyer
Browse files

claude generated tests, 2 iterations

parent 791dd602
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="AndroidTestResultsUserPreferences">
<option name="androidTestResultsTableState">
<map>
<entry key="28629151">
<value>
<AndroidTestResultsTableState>
<option name="preferredColumnWidths">
<map>
<entry key="Duration" value="90" />
<entry key="Medium_Phone_2" value="120" />
<entry key="Tests" value="360" />
</map>
</option>
</AndroidTestResultsTableState>
</value>
</entry>
</map>
</option>
</component>
</project>
\ No newline at end of file
...@@ -6,6 +6,10 @@ ...@@ -6,6 +6,10 @@
<option name="selectionMode" value="DROPDOWN" /> <option name="selectionMode" value="DROPDOWN" />
<DialogSelection /> <DialogSelection />
</SelectionState> </SelectionState>
<SelectionState runConfigName="All Tests">
<option name="selectionMode" value="DROPDOWN" />
<DialogSelection />
</SelectionState>
</selectionStates> </selectionStates>
</component> </component>
</project> </project>
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<project version="4"> <project version="4">
<component name="ExternalStorageConfigurationManager" enabled="true" /> <component name="ExternalStorageConfigurationManager" enabled="true" />
<component name="ProjectRootManager" version="2" languageLevel="JDK_21" default="true" project-jdk-name="jbr-21" project-jdk-type="JavaSDK"> <component name="ProjectRootManager" version="2" languageLevel="JDK_21" default="true" project-jdk-name="jbr-21" project-jdk-type="JavaSDK">
......
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>
\ No newline at end of file
...@@ -58,4 +58,14 @@ dependencies { ...@@ -58,4 +58,14 @@ dependencies {
// Lifecycle / LiveData // Lifecycle / LiveData
implementation 'androidx.lifecycle:lifecycle-livedata:2.6.2' implementation 'androidx.lifecycle:lifecycle-livedata:2.6.2'
implementation 'androidx.lifecycle:lifecycle-viewmodel:2.6.2' implementation 'androidx.lifecycle:lifecycle-viewmodel:2.6.2'
// Core test infrastructure
androidTestImplementation 'androidx.test:core:1.5.0'
androidTestImplementation 'androidx.test.ext:junit:1.1.5'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'
androidTestImplementation 'androidx.test:runner:1.5.2'
androidTestImplementation 'androidx.test:rules:1.5.0'
androidTestImplementation 'androidx.room:room-testing:2.5.2'
testImplementation 'junit:junit:4.13.2'
} }
package dev.lueckemeyer.vocoach;
import android.content.Context;
import android.net.Uri;
import androidx.room.Room;
import androidx.test.core.app.ApplicationProvider;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.util.List;
import dev.lueckemeyer.vocoach.db.VocabDatabase;
import dev.lueckemeyer.vocoach.db.dao.*;
import dev.lueckemeyer.vocoach.db.entity.*;
import dev.lueckemeyer.vocoach.importer.CsvImporter;
import dev.lueckemeyer.vocoach.importer.CsvExporter;
import dev.lueckemeyer.vocoach.repository.TrainingRepository;
import static org.junit.Assert.*;
/**
* Instrumented tests covering the six core scenarios:
*
* 1. Import vocabulary from CSV
* 2. Export data and match against original CSV
* 3. Correct answer in native→fr direction
* 4. Wrong answer in fr→native direction
* 5. Stats reflect those results
* 6. Memorize box view shows the word that moved up
*/
@RunWith(AndroidJUnit4.class)
public class VoCoachInstrumentedTest {
private VocabDatabase db;
private Context ctx;
// ── Minimal 1-card CSV matching the VoCoach import format ────────────────
private static final String CSV_HEADER =
"word_type,french,native_lang,phonetic,example_sentence,notes," +
"book_title,book_description,unit_position,unit_title," +
"volet_position,volet_title," +
"gender,plural_form,is_proper," +
"infinitive,verb_group,participe_passe,participe_present," +
"auxiliary,is_reflexive,is_irregular," +
"feminine_form,plural_form_adj,feminine_plural_form,derived_from";
/** One noun: le chat / die Katze */
private static final String CSV_NOUN_ROW =
"noun,le chat,die Katze,ʃa,,," +
"TestBook,,1,Unité 1,1,Volet 1," +
"m,,false," +
",,,,,,," +
",,,";
/** One verb: parler / sprechen */
private static final String CSV_VERB_ROW =
"verb,parler,sprechen,paʁ.le,,," +
"TestBook,,1,Unité 1,1,Volet 1," +
",,," +
"parler,1,parlé,parlant,avoir,false,false," +
",,,";
// ── Setup / teardown ──────────────────────────────────────────────────────
@Before
public void setUp() {
ctx = ApplicationProvider.getApplicationContext();
// Replace the singleton with an in-memory database for isolation.
// We use allowMainThreadQueries() in tests for simplicity.
db = Room.inMemoryDatabaseBuilder(ctx, VocabDatabase.class)
.allowMainThreadQueries()
.build();
VocabDatabase.setTestInstance(db); // see note below about this method
}
@After
public void tearDown() {
db.close();
VocabDatabase.setTestInstance(null);
}
// ─────────────────────────────────────────────────────────────────────────
// Scenario 1 — Import vocabulary from CSV
// ─────────────────────────────────────────────────────────────────────────
@Test
public void importVocabulary_insertsCardAndLeitnerState() throws Exception {
Uri csvUri = writeTempCsv("import_test.csv",
CSV_HEADER + "\n" + CSV_NOUN_ROW);
CsvImporter.Result result = new CsvImporter(ctx).importFromUri(csvUri);
assertNull("Import should succeed", result.errorMessage);
assertEquals("One card inserted", 1, result.cardsInserted);
// Card exists
List<Card> cards = db.cardDao().getByVoletSync(voletId());
assertEquals(1, cards.size());
assertEquals("le chat", cards.get(0).french);
assertEquals("die Katze", cards.get(0).nativeLang);
// Noun detail
NounDetail nd = db.detailDao().getNounSync(cards.get(0).id);
assertNotNull(nd);
assertEquals("m", nd.gender);
// Two leitner states (one per direction) both in box 1
LeitnerState lsFr = db.leitnerStateDao()
.getSync(cards.get(0).id, "fr_to_native");
LeitnerState lsNat = db.leitnerStateDao()
.getSync(cards.get(0).id, "native_to_fr");
assertNotNull(lsFr);
assertNotNull(lsNat);
assertEquals(1, lsFr.boxNumber);
assertEquals(1, lsNat.boxNumber);
}
// ─────────────────────────────────────────────────────────────────────────
// Scenario 2 — Export and match against the original CSV
// ─────────────────────────────────────────────────────────────────────────
@Test
public void exportData_roundTripsToEquivalentCsv() throws Exception {
// Import first
Uri importUri = writeTempCsv("roundtrip_import.csv",
CSV_HEADER + "\n" + CSV_NOUN_ROW);
new CsvImporter(ctx).importFromUri(importUri);
// Export
File exportFile = new File(ctx.getCacheDir(), "roundtrip_export.csv");
Uri exportUri = Uri.fromFile(exportFile);
CsvExporter.Result er = new CsvExporter(ctx).exportToUri(exportUri);
assertNull("Export should succeed", er.errorMessage);
assertEquals(1, er.cardsExported);
// Read exported CSV
String exported = readFile(exportFile);
assertTrue("Exported CSV contains french word",
exported.contains("le chat"));
assertTrue("Exported CSV contains german word",
exported.contains("die Katze"));
assertTrue("Exported CSV contains book title",
exported.contains("TestBook"));
assertTrue("Exported CSV contains gender",
exported.contains(",m,"));
// Leitner box columns present (both should be 1)
assertTrue("Exported CSV contains leitner_box_fr column header",
exported.contains("leitner_box_fr"));
assertTrue("Box value exported",
exported.contains(",1,1"));
}
// ─────────────────────────────────────────────────────────────────────────
// Scenario 3 — Correct answer in native→fr
// ─────────────────────────────────────────────────────────────────────────
@Test
public void correctAnswer_nativeToFr_promotesBox() {
importNounCard();
Card card = firstCard();
LeitnerState ls = db.leitnerStateDao().getSync(card.id, "native_to_fr");
assertEquals("Starts in box 1", 1, ls.boxNumber);
// Simulate a correct answer
TrainingRepository repo = new TrainingRepository(ctx);
int sessionId = repo.getOrCreateSession("native_to_fr");
repo.recordResult(ls, true, sessionId);
LeitnerState updated = db.leitnerStateDao().getSync(card.id, "native_to_fr");
assertEquals("Promoted to box 2", 2, updated.boxNumber);
// Try record created
List<TryRecord> tries = db.tryDao().getForStateSync(ls.id);
assertEquals(1, tries.size());
assertTrue(tries.get(0).correct);
}
// ─────────────────────────────────────────────────────────────────────────
// Scenario 4 — Wrong answer in fr→native
// ─────────────────────────────────────────────────────────────────────────
@Test
public void wrongAnswer_frToNative_staysInBox1() {
importNounCard();
Card card = firstCard();
LeitnerState ls = db.leitnerStateDao().getSync(card.id, "fr_to_native");
TrainingRepository repo = new TrainingRepository(ctx);
int sessionId = repo.getOrCreateSession("fr_to_native");
repo.recordResult(ls, false, sessionId);
LeitnerState updated = db.leitnerStateDao().getSync(card.id, "fr_to_native");
assertEquals("Wrong answer in box 1 stays at box 1", 1, updated.boxNumber);
List<TryRecord> tries = db.tryDao().getForStateSync(ls.id);
assertEquals(1, tries.size());
assertFalse(tries.get(0).correct);
}
// ─────────────────────────────────────────────────────────────────────────
// Scenario 5 — Stats reflect the recorded answers
// ─────────────────────────────────────────────────────────────────────────
@Test
public void stats_reflectCorrectAndWrongAnswers() {
importNounCard();
Card card = firstCard();
TrainingRepository repo = new TrainingRepository(ctx);
// Record one correct (native→fr) and one wrong (fr→native)
LeitnerState lsNat = db.leitnerStateDao().getSync(card.id, "native_to_fr");
LeitnerState lsFr = db.leitnerStateDao().getSync(card.id, "fr_to_native");
int session = repo.getOrCreateSession("fr_to_native");
repo.recordResult(lsNat, true, session);
repo.recordResult(lsFr, false, session);
List<TryDao.VoletStat> voletStats = repo.getVoletStats();
assertFalse("Volet stats not empty", voletStats.isEmpty());
TryDao.VoletStat stat = voletStats.get(0);
assertEquals("Total = 2 (one per direction)", 2, stat.total);
assertEquals("Correct = 1", 1, stat.correct);
List<TryDao.DayStat> dayStats = repo.getDayStats();
assertFalse("Day stats not empty", dayStats.isEmpty());
assertEquals(2, dayStats.get(0).total);
assertEquals(1, dayStats.get(0).correct);
}
// ─────────────────────────────────────────────────────────────────────────
// Scenario 6 — Memorize box view: word moved to box 2 after correct answer
// ─────────────────────────────────────────────────────────────────────────
@Test
public void memorizeBoxView_showsPromotedCard() {
importNounCard();
Card card = firstCard();
TrainingRepository repo = new TrainingRepository(ctx);
// Give a correct answer in native→fr → card moves to box 2
LeitnerState ls = db.leitnerStateDao().getSync(card.id, "native_to_fr");
repo.recordResult(ls, true, repo.getOrCreateSession("native_to_fr"));
// Box 1 (native→fr) should now be empty for this card
List<Card> inBox1 = db.cardDao().getByBoxSync(1, "native_to_fr");
// the card was never attempted in fr_to_native so it still appears in box 1
// via getUnattemptedForDirectionSync — but via getByBoxSync it is NOT there
assertFalse("Card no longer returned by getByBoxSync for box 1",
inBox1.stream().anyMatch(c -> c.id == card.id));
// Box 2 (native→fr) should contain the card
List<Card> inBox2 = db.cardDao().getByBoxSync(2, "native_to_fr");
assertTrue("Card appears in box 2 after correct answer",
inBox2.stream().anyMatch(c -> c.id == card.id));
}
// ─────────────────────────────────────────────────────────────────────────
// Helpers
// ─────────────────────────────────────────────────────────────────────────
private void importNounCard() {
try {
Uri uri = writeTempCsv("helper_import.csv",
CSV_HEADER + "\n" + CSV_NOUN_ROW);
new CsvImporter(ctx).importFromUri(uri);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
private Card firstCard() {
return db.cardDao().getByVoletSync(voletId()).get(0);
}
private int voletId() {
List<Volet> volets = db.voletDao().getAllSync();
assertFalse("Database should contain at least one volet", volets.isEmpty());
return volets.get(0).id;
}
private Uri writeTempCsv(String filename, String content) throws Exception {
File f = new File(ctx.getCacheDir(), filename);
try (Writer w = new OutputStreamWriter(
new FileOutputStream(f), StandardCharsets.UTF_8)) {
w.write(content);
}
return Uri.fromFile(f);
}
private String readFile(File f) throws Exception {
StringBuilder sb = new StringBuilder();
try (BufferedReader r = new BufferedReader(
new InputStreamReader(new FileInputStream(f), StandardCharsets.UTF_8))) {
String line;
while ((line = r.readLine()) != null) sb.append(line).append('\n');
}
return sb.toString();
}
}
...@@ -15,6 +15,14 @@ public abstract class VocabDatabase extends RoomDatabase { ...@@ -15,6 +15,14 @@ public abstract class VocabDatabase extends RoomDatabase {
private static volatile VocabDatabase INSTANCE; private static volatile VocabDatabase INSTANCE;
/**
* Injects a test instance (typically an in-memory database).
* Call from @Before / @After in instrumented tests only.
*/
public static void setTestInstance(VocabDatabase instance) {
INSTANCE = instance;
}
public abstract BookDao bookDao(); public abstract BookDao bookDao();
public abstract UnitDao unitDao(); public abstract UnitDao unitDao();
public abstract VoletDao voletDao(); public abstract VoletDao voletDao();
......
...@@ -650,7 +650,7 @@ code + .copy-button { ...@@ -650,7 +650,7 @@ code + .copy-button {
<script type="text/javascript"> <script type="text/javascript">
function configurationCacheProblems() { return ( function configurationCacheProblems() { return (
// begin-report-data // begin-report-data
{"diagnostics":[{"problem":[{"text":"Properties should be assigned using the 'propName = value' syntax. Setting a property via the Gradle-generated 'propName value' or 'propName(value)' syntax in Groovy DSL has been deprecated."}],"severity":"WARNING","problemDetails":[{"text":"This is scheduled to be removed in Gradle 10."}],"contextualLabel":"Properties should be assigned using the 'propName = value' syntax. Setting a property via the Gradle-generated 'propName value' or 'propName(value)' syntax in Groovy DSL has been deprecated.","documentationLink":"https://docs.gradle.org/9.0.0/userguide/upgrading_version_8.html#groovy_space_assignment_syntax","problemId":[{"name":"deprecation","displayName":"Deprecation"},{"name":"properties-should-be-assigned-using-the-propname-value-syntax-setting-a-property-via-the-gradle-generated-propname-value-or-propname-value-syntax-in-groovy-dsl","displayName":"Properties should be assigned using the 'propName = value' syntax. Setting a property via the Gradle-generated 'propName value' or 'propName(value)' syntax in Groovy DSL has been deprecated."}],"solutions":[[{"text":"Use assignment ('namespace = <value>') instead."}]]},{"problem":[{"text":"Properties should be assigned using the 'propName = value' syntax. Setting a property via the Gradle-generated 'propName value' or 'propName(value)' syntax in Groovy DSL has been deprecated."}],"severity":"WARNING","problemDetails":[{"text":"This is scheduled to be removed in Gradle 10."}],"contextualLabel":"Properties should be assigned using the 'propName = value' syntax. Setting a property via the Gradle-generated 'propName value' or 'propName(value)' syntax in Groovy DSL has been deprecated.","documentationLink":"https://docs.gradle.org/9.0.0/userguide/upgrading_version_8.html#groovy_space_assignment_syntax","problemId":[{"name":"deprecation","displayName":"Deprecation"},{"name":"properties-should-be-assigned-using-the-propname-value-syntax-setting-a-property-via-the-gradle-generated-propname-value-or-propname-value-syntax-in-groovy-dsl","displayName":"Properties should be assigned using the 'propName = value' syntax. Setting a property via the Gradle-generated 'propName value' or 'propName(value)' syntax in Groovy DSL has been deprecated."}],"solutions":[[{"text":"Use assignment ('compileSdk = <value>') instead."}]]},{"problem":[{"text":"Properties should be assigned using the 'propName = value' syntax. Setting a property via the Gradle-generated 'propName value' or 'propName(value)' syntax in Groovy DSL has been deprecated."}],"severity":"WARNING","problemDetails":[{"text":"This is scheduled to be removed in Gradle 10."}],"contextualLabel":"Properties should be assigned using the 'propName = value' syntax. Setting a property via the Gradle-generated 'propName value' or 'propName(value)' syntax in Groovy DSL has been deprecated.","documentationLink":"https://docs.gradle.org/9.0.0/userguide/upgrading_version_8.html#groovy_space_assignment_syntax","problemId":[{"name":"deprecation","displayName":"Deprecation"},{"name":"properties-should-be-assigned-using-the-propname-value-syntax-setting-a-property-via-the-gradle-generated-propname-value-or-propname-value-syntax-in-groovy-dsl","displayName":"Properties should be assigned using the 'propName = value' syntax. Setting a property via the Gradle-generated 'propName value' or 'propName(value)' syntax in Groovy DSL has been deprecated."}],"solutions":[[{"text":"Use assignment ('minSdk = <value>') instead."}]]},{"problem":[{"text":"Properties should be assigned using the 'propName = value' syntax. Setting a property via the Gradle-generated 'propName value' or 'propName(value)' syntax in Groovy DSL has been deprecated."}],"severity":"WARNING","problemDetails":[{"text":"This is scheduled to be removed in Gradle 10."}],"contextualLabel":"Properties should be assigned using the 'propName = value' syntax. Setting a property via the Gradle-generated 'propName value' or 'propName(value)' syntax in Groovy DSL has been deprecated.","documentationLink":"https://docs.gradle.org/9.0.0/userguide/upgrading_version_8.html#groovy_space_assignment_syntax","problemId":[{"name":"deprecation","displayName":"Deprecation"},{"name":"properties-should-be-assigned-using-the-propname-value-syntax-setting-a-property-via-the-gradle-generated-propname-value-or-propname-value-syntax-in-groovy-dsl","displayName":"Properties should be assigned using the 'propName = value' syntax. Setting a property via the Gradle-generated 'propName value' or 'propName(value)' syntax in Groovy DSL has been deprecated."}],"solutions":[[{"text":"Use assignment ('targetSdk = <value>') instead."}]]},{"problem":[{"text":"Properties should be assigned using the 'propName = value' syntax. Setting a property via the Gradle-generated 'propName value' or 'propName(value)' syntax in Groovy DSL has been deprecated."}],"severity":"WARNING","problemDetails":[{"text":"This is scheduled to be removed in Gradle 10."}],"contextualLabel":"Properties should be assigned using the 'propName = value' syntax. Setting a property via the Gradle-generated 'propName value' or 'propName(value)' syntax in Groovy DSL has been deprecated.","documentationLink":"https://docs.gradle.org/9.0.0/userguide/upgrading_version_8.html#groovy_space_assignment_syntax","problemId":[{"name":"deprecation","displayName":"Deprecation"},{"name":"properties-should-be-assigned-using-the-propname-value-syntax-setting-a-property-via-the-gradle-generated-propname-value-or-propname-value-syntax-in-groovy-dsl","displayName":"Properties should be assigned using the 'propName = value' syntax. Setting a property via the Gradle-generated 'propName value' or 'propName(value)' syntax in Groovy DSL has been deprecated."}],"solutions":[[{"text":"Use assignment ('viewBinding = <value>') instead."}]]},{"locations":[{"pluginId":"com.android.internal.application"}],"problem":[{"text":"The StartParameter.isConfigurationCacheRequested property has been deprecated."}],"severity":"WARNING","problemDetails":[{"text":"This is scheduled to be removed in Gradle 10."}],"contextualLabel":"The StartParameter.isConfigurationCacheRequested property has been deprecated.","documentationLink":"https://docs.gradle.org/9.0.0/userguide/upgrading_version_8.html#deprecated_startparameter_is_configuration_cache_requested","problemId":[{"name":"deprecation","displayName":"Deprecation"},{"name":"the-startparameter-isconfigurationcacherequested-property-has-been-deprecated","displayName":"The StartParameter.isConfigurationCacheRequested property has been deprecated."}],"solutions":[[{"text":"Please use 'configurationCache.requested' property on 'BuildFeatures' service instead."}]]}],"problemsReport":{"totalProblemCount":6,"buildName":"VoCoach","requestedTasks":":app:assembleDebug","documentationLink":"https://docs.gradle.org/9.0.0/userguide/reporting_problems.html","documentationLinkCaption":"Problem report","summaries":[]}} {"diagnostics":[{"problem":[{"text":"Properties should be assigned using the 'propName = value' syntax. Setting a property via the Gradle-generated 'propName value' or 'propName(value)' syntax in Groovy DSL has been deprecated."}],"severity":"WARNING","problemDetails":[{"text":"This is scheduled to be removed in Gradle 10."}],"contextualLabel":"Properties should be assigned using the 'propName = value' syntax. Setting a property via the Gradle-generated 'propName value' or 'propName(value)' syntax in Groovy DSL has been deprecated.","documentationLink":"https://docs.gradle.org/9.0.0/userguide/upgrading_version_8.html#groovy_space_assignment_syntax","problemId":[{"name":"deprecation","displayName":"Deprecation"},{"name":"properties-should-be-assigned-using-the-propname-value-syntax-setting-a-property-via-the-gradle-generated-propname-value-or-propname-value-syntax-in-groovy-dsl","displayName":"Properties should be assigned using the 'propName = value' syntax. Setting a property via the Gradle-generated 'propName value' or 'propName(value)' syntax in Groovy DSL has been deprecated."}],"solutions":[[{"text":"Use assignment ('namespace = <value>') instead."}]]},{"problem":[{"text":"Properties should be assigned using the 'propName = value' syntax. Setting a property via the Gradle-generated 'propName value' or 'propName(value)' syntax in Groovy DSL has been deprecated."}],"severity":"WARNING","problemDetails":[{"text":"This is scheduled to be removed in Gradle 10."}],"contextualLabel":"Properties should be assigned using the 'propName = value' syntax. Setting a property via the Gradle-generated 'propName value' or 'propName(value)' syntax in Groovy DSL has been deprecated.","documentationLink":"https://docs.gradle.org/9.0.0/userguide/upgrading_version_8.html#groovy_space_assignment_syntax","problemId":[{"name":"deprecation","displayName":"Deprecation"},{"name":"properties-should-be-assigned-using-the-propname-value-syntax-setting-a-property-via-the-gradle-generated-propname-value-or-propname-value-syntax-in-groovy-dsl","displayName":"Properties should be assigned using the 'propName = value' syntax. Setting a property via the Gradle-generated 'propName value' or 'propName(value)' syntax in Groovy DSL has been deprecated."}],"solutions":[[{"text":"Use assignment ('compileSdk = <value>') instead."}]]},{"problem":[{"text":"Properties should be assigned using the 'propName = value' syntax. Setting a property via the Gradle-generated 'propName value' or 'propName(value)' syntax in Groovy DSL has been deprecated."}],"severity":"WARNING","problemDetails":[{"text":"This is scheduled to be removed in Gradle 10."}],"contextualLabel":"Properties should be assigned using the 'propName = value' syntax. Setting a property via the Gradle-generated 'propName value' or 'propName(value)' syntax in Groovy DSL has been deprecated.","documentationLink":"https://docs.gradle.org/9.0.0/userguide/upgrading_version_8.html#groovy_space_assignment_syntax","problemId":[{"name":"deprecation","displayName":"Deprecation"},{"name":"properties-should-be-assigned-using-the-propname-value-syntax-setting-a-property-via-the-gradle-generated-propname-value-or-propname-value-syntax-in-groovy-dsl","displayName":"Properties should be assigned using the 'propName = value' syntax. Setting a property via the Gradle-generated 'propName value' or 'propName(value)' syntax in Groovy DSL has been deprecated."}],"solutions":[[{"text":"Use assignment ('minSdk = <value>') instead."}]]},{"problem":[{"text":"Properties should be assigned using the 'propName = value' syntax. Setting a property via the Gradle-generated 'propName value' or 'propName(value)' syntax in Groovy DSL has been deprecated."}],"severity":"WARNING","problemDetails":[{"text":"This is scheduled to be removed in Gradle 10."}],"contextualLabel":"Properties should be assigned using the 'propName = value' syntax. Setting a property via the Gradle-generated 'propName value' or 'propName(value)' syntax in Groovy DSL has been deprecated.","documentationLink":"https://docs.gradle.org/9.0.0/userguide/upgrading_version_8.html#groovy_space_assignment_syntax","problemId":[{"name":"deprecation","displayName":"Deprecation"},{"name":"properties-should-be-assigned-using-the-propname-value-syntax-setting-a-property-via-the-gradle-generated-propname-value-or-propname-value-syntax-in-groovy-dsl","displayName":"Properties should be assigned using the 'propName = value' syntax. Setting a property via the Gradle-generated 'propName value' or 'propName(value)' syntax in Groovy DSL has been deprecated."}],"solutions":[[{"text":"Use assignment ('targetSdk = <value>') instead."}]]},{"problem":[{"text":"Properties should be assigned using the 'propName = value' syntax. Setting a property via the Gradle-generated 'propName value' or 'propName(value)' syntax in Groovy DSL has been deprecated."}],"severity":"WARNING","problemDetails":[{"text":"This is scheduled to be removed in Gradle 10."}],"contextualLabel":"Properties should be assigned using the 'propName = value' syntax. Setting a property via the Gradle-generated 'propName value' or 'propName(value)' syntax in Groovy DSL has been deprecated.","documentationLink":"https://docs.gradle.org/9.0.0/userguide/upgrading_version_8.html#groovy_space_assignment_syntax","problemId":[{"name":"deprecation","displayName":"Deprecation"},{"name":"properties-should-be-assigned-using-the-propname-value-syntax-setting-a-property-via-the-gradle-generated-propname-value-or-propname-value-syntax-in-groovy-dsl","displayName":"Properties should be assigned using the 'propName = value' syntax. Setting a property via the Gradle-generated 'propName value' or 'propName(value)' syntax in Groovy DSL has been deprecated."}],"solutions":[[{"text":"Use assignment ('viewBinding = <value>') instead."}]]},{"locations":[{"pluginId":"com.android.internal.application"}],"problem":[{"text":"The StartParameter.isConfigurationCacheRequested property has been deprecated."}],"severity":"WARNING","problemDetails":[{"text":"This is scheduled to be removed in Gradle 10."}],"contextualLabel":"The StartParameter.isConfigurationCacheRequested property has been deprecated.","documentationLink":"https://docs.gradle.org/9.0.0/userguide/upgrading_version_8.html#deprecated_startparameter_is_configuration_cache_requested","problemId":[{"name":"deprecation","displayName":"Deprecation"},{"name":"the-startparameter-isconfigurationcacherequested-property-has-been-deprecated","displayName":"The StartParameter.isConfigurationCacheRequested property has been deprecated."}],"solutions":[[{"text":"Please use 'configurationCache.requested' property on 'BuildFeatures' service instead."}]]}],"problemsReport":{"totalProblemCount":6,"buildName":"VoCoach","requestedTasks":":app:assembleDebug :app:assembleDebugUnitTest :app:assembleDebugAndroidTest","documentationLink":"https://docs.gradle.org/9.0.0/userguide/reporting_problems.html","documentationLinkCaption":"Problem report","summaries":[]}}
// end-report-data // end-report-data
);} );}
</script> </script>
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment