diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..47f6d98 --- /dev/null +++ b/.gitattributes @@ -0,0 +1 @@ +*.ai binary diff --git a/app/src/androidTest/java/life/andre/message487/UiThreadDeviceTest.kt b/app/src/androidTest/java/life/andre/message487/UiThreadDeviceTest.kt index cfb8221..1a4be4d 100644 --- a/app/src/androidTest/java/life/andre/message487/UiThreadDeviceTest.kt +++ b/app/src/androidTest/java/life/andre/message487/UiThreadDeviceTest.kt @@ -4,6 +4,9 @@ import android.os.StrictMode import androidx.activity.ComponentActivity import androidx.compose.ui.test.* import androidx.compose.ui.test.junit4.createAndroidComposeRule +import androidx.core.view.ViewCompat +import androidx.core.view.WindowCompat +import androidx.core.view.WindowInsetsCompat import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.platform.app.InstrumentationRegistry import org.junit.After @@ -109,8 +112,20 @@ class UiThreadDeviceTest { model.settings.value.imageMaxEdge == 2048 && !model.state.value.busy } node(R.string.image_max_edge).assertIsEnabled() + // Finish editing before navigation moves as the IME closes. + compose.runOnUiThread { + val window = compose.activity.window + WindowCompat.getInsetsController(window, window.decorView).hide(WindowInsetsCompat.Type.ime()) + } + compose.waitUntil(10_000) { + compose.runOnIdle { + ViewCompat.getRootWindowInsets(compose.activity.window.decorView) + ?.isVisible(WindowInsetsCompat.Type.ime()) != true + } + } icon(R.string.back).performClick() - node(R.string.journal).performClick() + compose.onNode(hasText(app.getString(R.string.journal)) and hasClickAction()) + .performClick().assertIsSelected() icon(R.string.back).performClick() icon(R.string.diagnostics).performClick() node(R.string.refresh_log).performClick() diff --git a/scripts/tests/test_release_automation.py b/scripts/tests/test_release_automation.py index c74dabb..8dab5b4 100644 --- a/scripts/tests/test_release_automation.py +++ b/scripts/tests/test_release_automation.py @@ -30,6 +30,44 @@ class ReleaseTests(unittest.TestCase): + def test_release_diff_treats_illustrator_documents_as_binary(self): + with tempfile.TemporaryDirectory() as temp: + root = Path(temp) + (root / '.gitattributes').write_bytes( + (Path(__file__).parents[2] / '.gitattributes').read_bytes() + ) + artwork = root / 'branding.ai' + artwork.write_bytes(b'%PDF-1.6\noriginal artwork\n') + svg = root / 'icon.svg' + svg.write_text('\n') + + def git(*args): + return m.command('git', '-C', str(root), *args) + + git('init', '-q') + git('add', '.') + git( + '-c', + 'user.name=Test', + '-c', + 'user.email=test@example.invalid', + '-c', + 'commit.gpgsign=false', + 'commit', + '-qm', + 'Initial artwork', + ) + # No NUL bytes: Git's automatic detection otherwise considers this text. + artwork.write_bytes(b'%PDF-1.6\nupdated artwork\xff\xfe\n') + svg.write_text('\n') + with patch.dict(os.environ, {'LC_ALL': 'C'}): + diff = git( + 'diff', '--no-ext-diff', '--no-textconv', '--unified=3', 'HEAD' + ) + self.assertIn('Binary files a/branding.ai and b/branding.ai differ', diff) + self.assertIn('+', diff) + self.assertNotIn('updated artwork', diff) + def test_generator_retries_only_length_errors_and_stops_after_three_attempts(self): def response(notes, status='completed'): return io.BytesIO(