From 616d1c09a0b6197b8a6f0916f5321ebb08440aff Mon Sep 17 00:00:00 2001 From: Brendan Robert Date: Fri, 24 Jul 2015 00:32:15 -0700 Subject: [PATCH] Added roundtrip test for lemonade stand and fixed bugs to make test pass --- .../java/jace/applesoft/ApplesoftProgram.java | 8 +- src/main/java/jace/applesoft/Command.java | 4 +- src/main/java/jace/applesoft/Line.java | 20 ++--- src/main/java/jace/core/Keyboard.java | 4 +- src/test/java/jace/ide/ApplesoftTest.java | 85 ++++++++++++++++++ src/test/resources/jace/lemonade_stand.bin | Bin 0 -> 11731 bytes 6 files changed, 102 insertions(+), 19 deletions(-) create mode 100644 src/test/java/jace/ide/ApplesoftTest.java create mode 100755 src/test/resources/jace/lemonade_stand.bin diff --git a/src/main/java/jace/applesoft/ApplesoftProgram.java b/src/main/java/jace/applesoft/ApplesoftProgram.java index 6d6c98f..c40e0a7 100755 --- a/src/main/java/jace/applesoft/ApplesoftProgram.java +++ b/src/main/java/jace/applesoft/ApplesoftProgram.java @@ -66,10 +66,6 @@ public class ApplesoftProgram { return bytes; } - public static ApplesoftProgram fromBinary(List binary) { - return fromBinary(binary, 0x0801); - } - public static ApplesoftProgram fromMemory(RAM memory) { int startAddress = memory.readWordRaw(startingAddressPointer); int nextCheck = memory.readWordRaw(startAddress); @@ -84,6 +80,10 @@ public class ApplesoftProgram { return fromBinary(bytes, startAddress); } + public static ApplesoftProgram fromBinary(List binary) { + return fromBinary(binary, 0x0801); + } + public static ApplesoftProgram fromBinary(List binary, int startAddress) { ApplesoftProgram program = new ApplesoftProgram(); int currentAddress = startAddress; diff --git a/src/main/java/jace/applesoft/Command.java b/src/main/java/jace/applesoft/Command.java index ec006af..a48bdbc 100755 --- a/src/main/java/jace/applesoft/Command.java +++ b/src/main/java/jace/applesoft/Command.java @@ -143,8 +143,8 @@ public class Command { for (TOKEN t : values()) { int i = start; boolean found = true; - for (int j = 0; j < t.toString().length() && j + i < search.length(); j++) { - while (search.charAt(j + i) == ' ') { + for (int j = 0; j < t.toString().length(); j++) { + while (i+j < search.length() && search.charAt(j + i) == ' ') { i++; } if (i + j >= search.length() diff --git a/src/main/java/jace/applesoft/Line.java b/src/main/java/jace/applesoft/Line.java index 103c5cd..d7fb860 100755 --- a/src/main/java/jace/applesoft/Line.java +++ b/src/main/java/jace/applesoft/Line.java @@ -154,7 +154,6 @@ public class Line { Command currentCommand = new Command(); l.commands.add(currentCommand); l.length = 4; - lineString = lineString.trim(); String upperLineString = lineString.toUpperCase(); for (int i = 0; i < lineString.length(); i++) { if (!hasLineNumber) { @@ -183,24 +182,23 @@ public class Line { Command.ByteOrToken part = new Command.ByteOrToken(TOKEN.PRINT); currentCommand.parts.add(part); l.length++; + } else if (lineString.charAt(i) == ' ') { + continue; } else { TOKEN match = Command.TOKEN.findMatch(upperLineString, i); if (match != null) { - if (match == TOKEN.REM) { - isComment = true; - } Command.ByteOrToken part = new Command.ByteOrToken(match); currentCommand.parts.add(part); - for (int j=0; j+i <= match.toString().length(); j++) { - while (lineString.charAt(i+j) == ' ') { + if (match == TOKEN.REM || match == TOKEN.DATA) { + isComment = true; + } + for (int j=0; j < match.toString().length(); j++, i++) { + while (i < lineString.length() && lineString.charAt(i) == ' ') { i++; } } - i += match.toString().length() - 1; - if (isComment) { - while (i+1 < lineString.length() && lineString.charAt(i+1) == ' ') { - i++; - } + if (!isComment) { + i--; } l.length++; } else { diff --git a/src/main/java/jace/core/Keyboard.java b/src/main/java/jace/core/Keyboard.java index 7820dc4..5f9ec9d 100644 --- a/src/main/java/jace/core/Keyboard.java +++ b/src/main/java/jace/core/Keyboard.java @@ -95,7 +95,7 @@ public class Keyboard implements Reconfigurable { registerKeyHandler(new KeyHandler(code) { @Override public boolean handleKeyUp(KeyEvent e) { - if (!action.notifyOnRelease()) { + if (action == null || !action.notifyOnRelease()) { return false; } // System.out.println("Key up: "+method.toString()); @@ -131,7 +131,7 @@ public class Keyboard implements Reconfigurable { if (returnValue != null) { return (Boolean) returnValue; } - return action.consumeKeyEvent(); + return action != null ? action.consumeKeyEvent() : null; } }, owner); } diff --git a/src/test/java/jace/ide/ApplesoftTest.java b/src/test/java/jace/ide/ApplesoftTest.java new file mode 100644 index 0000000..13277da --- /dev/null +++ b/src/test/java/jace/ide/ApplesoftTest.java @@ -0,0 +1,85 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package jace.ide; + +import com.google.common.collect.Lists; +import jace.Emulator; +import jace.apple2e.Apple2e; +import jace.applesoft.ApplesoftProgram; +import jace.core.Video; +import java.io.BufferedInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.net.URISyntaxException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.List; +import javafx.scene.image.WritableImage; +import org.junit.After; +import org.junit.AfterClass; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; +import static org.junit.Assert.*; + +/** + * + * @author blurry + */ +public class ApplesoftTest { + + public ApplesoftTest() { + } + + static Byte[] lemonadeStandBinary; + + @BeforeClass + public static void setUpClass() throws URISyntaxException, IOException { +// Emulator.computer = new Apple2e(); +// Emulator.computer.card6.setValue(null); +// Emulator.computer.card7.setValue(null); + + byte[] lemonadeStand = readBinary("/jace/lemonade_stand.bin"); + lemonadeStandBinary = ApplesoftProgram.toObjects(lemonadeStand); + } + + public static byte[] readBinary(String path) throws IOException, URISyntaxException { + Path resource = Paths.get(ApplesoftTest.class.getResource(path).toURI()); + return Files.readAllBytes(resource); + } + + @AfterClass + public static void tearDownClass() { + } + + @Before + public void setUp() { + } + + @After + public void tearDown() { + } + + @Test + public void deserializeBinary() { + ApplesoftProgram program = ApplesoftProgram.fromBinary(Lists.newArrayList(lemonadeStandBinary), 0x0801); + assertNotNull(program); + assertNotSame("", program.toString()); + } + + @Test + public void roundTripStringComparison() { + ApplesoftProgram program = ApplesoftProgram.fromBinary(Lists.newArrayList(lemonadeStandBinary), 0x0801); + String serialized = program.toString(); + ApplesoftProgram deserialized = ApplesoftProgram.fromString(serialized); + String[] serializedLines = serialized.split("\\n"); + String[] researializedLines = deserialized.toString().split("\\n"); + for (int i=0; i < serializedLines.length; i++) { + assertEquals("Line "+(i+1)+" should match", serializedLines[i], researializedLines[i]); + } + } +} diff --git a/src/test/resources/jace/lemonade_stand.bin b/src/test/resources/jace/lemonade_stand.bin new file mode 100755 index 0000000000000000000000000000000000000000..d5d165cf75c56f76da6a180199ee0320bbfff49e GIT binary patch literal 11731 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 OZlGS_orzl+WB&ukfcfeG literal 0 HcmV?d00001