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(