app/src/test/java/dev/equwal/inkdim/DimTest.kt (3924 bytes)
1 // SPDX-License-Identifier: GPL-3.0-or-later 2 // Copyright (c) 2026 equwal 3 package dev.equwal.inkdim 4 5 import org.junit.Assert.assertEquals 6 import org.junit.Assert.assertFalse 7 import org.junit.Assert.assertNull 8 import org.junit.Assert.assertTrue 9 import org.junit.Test 10 import java.util.Random 11 12 /** Tests for the pure functions of [Dim]. */ 13 class DimTest { 14 15 // ---- Dim.next ---------------------------------------------------------- 16 17 @Test fun `the node value wins over what the app remembers`() { 18 // The node says the light is already down, so a toggle goes back up. 19 assertFalse(Dim.next(1, false, Dim.Action.TOGGLE)) 20 // The node says the light is up, so a toggle goes down. 21 assertTrue(Dim.next(60, true, Dim.Action.TOGGLE)) 22 } 23 24 @Test fun `a node value at or below the on value counts as on`() { 25 assertFalse(Dim.next(0, false, Dim.Action.TOGGLE)) 26 assertFalse(Dim.next(Dim.ON_VALUE, false, Dim.Action.TOGGLE)) 27 assertTrue(Dim.next(Dim.ON_VALUE + 1, false, Dim.Action.TOGGLE)) 28 } 29 30 @Test fun `no node value falls back to what the app remembers`() { 31 assertFalse(Dim.next(null, true, Dim.Action.TOGGLE)) 32 assertTrue(Dim.next(null, false, Dim.Action.TOGGLE)) 33 } 34 35 @Test fun `on and off give the same answer whatever the state is`() { 36 for (node in listOf(null, 0, 1, 5, 128, 255)) { 37 for (remembered in listOf(true, false)) { 38 assertTrue(Dim.next(node, remembered, Dim.Action.ON)) 39 assertFalse(Dim.next(node, remembered, Dim.Action.OFF)) 40 } 41 } 42 } 43 44 // ---- Dim.parseRead ----------------------------------------------------- 45 46 @Test fun `the reader takes the value the node prints`() { 47 assertEquals(1, Dim.parseRead("1\n")) 48 assertEquals(60, Dim.parseRead(" 60 \n")) 49 assertEquals(255, Dim.parseRead("255")) 50 } 51 52 @Test fun `the reader gives nothing for output that holds no value`() { 53 assertNull(Dim.parseRead("")) 54 assertNull(Dim.parseRead("\n \n")) 55 assertNull(Dim.parseRead("/system/bin/sh: cat: No such file or directory")) 56 assertNull(Dim.parseRead("null")) 57 } 58 59 /** 60 * Junk input must never throw. The generator makes output that is close to 61 * the real thing, because a value that looks right but does not fit an Int 62 * is what breaks a reader. 63 */ 64 @Test fun `the reader never throws on junk`() { 65 val r = Random(13) 66 val numbers = listOf( 67 "0", "1", "5", "255", "-3", "+7", "007", 68 "99999999999999999999", "2147483648", "1.5", "1 2" 69 ) 70 val noise = listOf( 71 "", " ", "\t", "\n", "\r\n", "null", "cat:", "Permission denied", 72 "/sys/class/leds/lcd-backlight/brightness", "su:", "not found", "💩" 73 ) 74 75 fun pick(xs: List<String>) = xs[r.nextInt(xs.size)] 76 77 repeat(2000) { 78 val text = (0 until r.nextInt(5)).joinToString("\n") { 79 pick(noise + numbers) + pick(noise) + pick(numbers + noise) 80 } 81 // Nothing is claimed about the result. It must only come back. 82 Dim.parseRead(text) 83 } 84 } 85 86 // ---- the shell commands ------------------------------------------------ 87 88 @Test fun `the write falls back to su and quotes every node`() { 89 val command = Dim.writeCommand(Dim.nodes, Dim.ON_VALUE) 90 assertTrue(command.contains("su 0")) 91 for (node in Dim.nodes) assertTrue(command.contains("'$node'")) 92 assertTrue(Dim.nodes.isNotEmpty()) 93 } 94 95 @Test fun `the read quotes every node`() { 96 val command = Dim.readCommand(Dim.nodes) 97 for (node in Dim.nodes) assertTrue(command.contains("'$node'")) 98 } 99 100 @Test fun `off puts back the brightness the system holds`() { 101 assertTrue(Dim.restoreCommand().contains("settings put system screen_brightness")) 102 } 103 }