1package com.peachpasswords.backup23import java.io.File4import javax.xml.parsers.DocumentBuilderFactory5import org.junit.Assert.assertTrue6import org.junit.Test789class BackupRulesCoverageTest {10 @Test11 fun every_shared_preferences_filename_is_excluded_from_both_rule_files() {12 val sourceRoot = projectFile("app/src/main/java")13 val preferences = sourceRoot.walkTopDown()14 .filter { it.isFile && it.extension == "kt" }15 .flatMap { file -> PREFERENCE_DECLARATION.findAll(file.readText()).map { it.groupValues[1] } }16 .map { "$it.xml" }17 .toSet()18 assertTrue("no SharedPreferences declarations were found", preferences.isNotEmpty())1920 val backup = excludedPaths(projectFile("app/src/main/res/xml/backup_rules.xml"))21 val extraction = excludedPaths(projectFile("app/src/main/res/xml/data_extraction_rules.xml"))22 preferences.forEach { filename ->23 assertTrue("$filename is missing from backup_rules.xml", filename in backup)24 assertTrue("$filename is missing from data_extraction_rules.xml", filename in extraction)25 }26 }2728 private fun excludedPaths(file: File): Set<String> {29 val document = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(file)30 return (0 until document.getElementsByTagName("exclude").length)31 .map { index -> document.getElementsByTagName("exclude").item(index).attributes.getNamedItem("path").nodeValue }32 .toSet()33 }3435 private fun projectFile(relativePath: String): File =36 File(relativePath).takeIf { it.exists() } ?: File("../$relativePath")3738 private companion object {39 val PREFERENCE_DECLARATION = Regex(40 "(?m)^\\s*(?:private\\s+|internal\\s+|public\\s+)?(?:const\\s+)?val\\s+\\w*PREFS\\w*\\s*=\\s*\"([^\"]+)\"",41 )42 }43}