Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
name: CI

on:
push:
branches: [main]
pull_request:

jobs:
build:
name: build / unit tests / lint
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- name: Set up JDK 17
uses: actions/setup-java@v4
with:
distribution: temurin
java-version: "17"

- name: Set up Gradle
uses: gradle/actions/setup-gradle@v4

- name: Build, test, and lint
run: ./gradlew --no-daemon assembleDebug testDebugUnitTest lintDebug
2 changes: 2 additions & 0 deletions app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -88,4 +88,6 @@ dependencies {
implementation(libs.kotlinx.coroutines.android)

debugImplementation(libs.androidx.ui.tooling)

testImplementation("junit:junit:4.13.2")
}
10 changes: 10 additions & 0 deletions app/src/main/res/drawable/ic_launcher_background.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="108dp"
android:height="108dp"
android:viewportWidth="108"
android:viewportHeight="108">
<path
android:fillColor="#1B1B2F"
android:pathData="M0,0h108v108h-108z" />
</vector>
16 changes: 16 additions & 0 deletions app/src/main/res/drawable/ic_launcher_foreground.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="108dp"
android:height="108dp"
android:viewportWidth="108"
android:viewportHeight="108">
<group
android:scaleX="2.2"
android:scaleY="2.2"
android:translateX="27.6"
android:translateY="27.6">
<path
android:fillColor="#FFFFFF"
android:pathData="M12,3v10.55c-0.59,-0.34 -1.27,-0.55 -2,-0.55C7.79,13 6,14.79 6,17s1.79,4 4,4s4,-1.79 4,-4V7h4V3H12z" />
</group>
</vector>
3 changes: 1 addition & 2 deletions app/src/main/res/drawable/ic_music_note.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,7 @@
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24"
android:tint="?attr/colorControlNormal">
android:viewportHeight="24">
<path
android:fillColor="@android:color/white"
android:pathData="M12,3v10.55c-0.59,-0.34 -1.27,-0.55 -2,-0.55C7.79,13 6,14.79 6,17s1.79,4 4,4s4,-1.79 4,-4V7h4V3H12z" />
Expand Down
5 changes: 5 additions & 0 deletions app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@drawable/ic_launcher_background" />
<foreground android:drawable="@drawable/ic_launcher_foreground" />
</adaptive-icon>
66 changes: 66 additions & 0 deletions app/src/test/java/com/retune432/app/util/AudioConverterTest.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
package com.retune432.app.util

import org.junit.Assert.assertEquals
import org.junit.Assert.assertFalse
import org.junit.Assert.assertTrue
import org.junit.Test

/**
* Unit tests for the pure (non-Android) logic in [AudioConverter]:
* extension parsing, the supported-format check, and the 432/440 pitch ratio.
* The Context/Uri/FFmpeg paths are intentionally not exercised here.
*/
class AudioConverterTest {

@Test
fun ratio_shifts_a440_down_to_a432() {
assertEquals(432.0 / 440.0, AudioConverter.RATIO, 0.0)
// ~31.77 cents down: ratio is just under 1.0
assertTrue(AudioConverter.RATIO < 1.0)
assertEquals(0.98181, AudioConverter.RATIO, 1e-5)
}

@Test
fun getExtension_returns_lowercased_suffix() {
assertEquals("mp3", AudioConverter.getExtension("song.mp3"))
assertEquals("flac", AudioConverter.getExtension("My Track.FLAC"))
assertEquals("m4a", AudioConverter.getExtension("a.b.c.M4A"))
}

@Test
fun getExtension_handles_no_dot_and_trailing_dot() {
assertEquals("", AudioConverter.getExtension("noextension"))
assertEquals("", AudioConverter.getExtension("trailing."))
assertEquals("", AudioConverter.getExtension(""))
}

@Test
fun getExtension_handles_dotfiles() {
// ".flac" has no name before the dot, so substringAfterLast yields "flac"
assertEquals("flac", AudioConverter.getExtension(".flac"))
}

@Test
fun isSupported_accepts_every_declared_format_case_insensitively() {
for (ext in AudioConverter.SUPPORTED_EXTENSIONS) {
assertTrue(ext, AudioConverter.isSupported("track.$ext"))
assertTrue(ext, AudioConverter.isSupported("TRACK.${ext.uppercase()}"))
}
}

@Test
fun isSupported_rejects_unknown_and_extensionless() {
assertFalse(AudioConverter.isSupported("video.mp4"))
assertFalse(AudioConverter.isSupported("doc.txt"))
assertFalse(AudioConverter.isSupported("README"))
assertFalse(AudioConverter.isSupported(""))
}

@Test
fun supported_extensions_are_lowercase_and_nonempty() {
assertTrue(AudioConverter.SUPPORTED_EXTENSIONS.isNotEmpty())
for (ext in AudioConverter.SUPPORTED_EXTENSIONS) {
assertEquals(ext, ext.lowercase())
}
}
}
Binary file added gradle/wrapper/gradle-wrapper.jar
Binary file not shown.
2 changes: 2 additions & 0 deletions gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.9-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
Loading
Loading