diff --git a/core/gradle.properties b/core/gradle.properties deleted file mode 100644 index f97ebb7d3..000000000 --- a/core/gradle.properties +++ /dev/null @@ -1 +0,0 @@ -org.gradle.parallel=true diff --git a/core/src/jvmTest/kotlin/org/isoron/platform/concurrency/ObservableTest.kt b/core/src/commonTest/kotlin/org/isoron/platform/concurrency/ObservableTest.kt similarity index 80% rename from core/src/jvmTest/kotlin/org/isoron/platform/concurrency/ObservableTest.kt rename to core/src/commonTest/kotlin/org/isoron/platform/concurrency/ObservableTest.kt index 7c6333040..25fd37659 100644 --- a/core/src/jvmTest/kotlin/org/isoron/platform/concurrency/ObservableTest.kt +++ b/core/src/commonTest/kotlin/org/isoron/platform/concurrency/ObservableTest.kt @@ -19,7 +19,6 @@ package org.isoron.platform.concurrency -import java.util.concurrent.* import kotlin.test.* class ObservableTest { @@ -29,20 +28,19 @@ class ObservableTest { } @Test - fun test() { - val latch = CountDownLatch(1) + fun testNotifyListeners() { + var wasCalled = false + val listener = object : TestListener { override fun onDataChanged(data: Int) { assertEquals(42, data) - latch.countDown() + wasCalled = true } } + val observable = Observable() observable.addListener(listener) - observable.notifyListeners { l -> - l.onDataChanged(42) - } - observable.removeListener(listener) - assertTrue(latch.await(3, TimeUnit.SECONDS)) + observable.notifyListeners { it.onDataChanged(42) } + assertTrue(wasCalled) } } \ No newline at end of file diff --git a/core/src/commonTest/kotlin/org/isoron/platform/gui/CanvasTest.kt b/core/src/commonTest/kotlin/org/isoron/platform/gui/CanvasTest.kt new file mode 100644 index 000000000..2e84f3d93 --- /dev/null +++ b/core/src/commonTest/kotlin/org/isoron/platform/gui/CanvasTest.kt @@ -0,0 +1,71 @@ +/* + * Copyright (C) 2016-2019 Álinson Santos Xavier + * + * This file is part of Loop Habit Tracker. + * + * Loop Habit Tracker is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by the + * Free Software Foundation, either version 3 of the License, or (at your + * option) any later version. + * + * Loop Habit Tracker is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +package org.isoron.platform.gui + +class CanvasTest(val platform: Platform) { + interface Platform { + fun createCanvas(width: Int, height: Int): Canvas + fun writePng(canvas: Canvas, filename: String) + } + + fun testDrawing() { + val canvas = platform.createCanvas(500, 400) + + canvas.setColor(Color(0x303030)) + canvas.fillRect(0.0, 0.0, 500.0, 400.0) + + canvas.setColor(Color(0x606060)) + canvas.setStrokeWidth(25.0) + canvas.drawRect(100.0, 100.0, 300.0, 200.0) + + canvas.setColor(Color(0xFFFF00)) + canvas.setStrokeWidth(1.0) + canvas.drawRect(0.0, 0.0, 100.0, 100.0) + canvas.fillCircle(50.0, 50.0, 30.0) + canvas.drawRect(0.0, 100.0, 100.0, 100.0) + canvas.fillArc(50.0, 150.0, 30.0, 90.0, 135.0) + canvas.drawRect(0.0, 200.0, 100.0, 100.0) + canvas.fillArc(50.0, 250.0, 30.0, 90.0, -135.0) + canvas.drawRect(0.0, 300.0, 100.0, 100.0) + canvas.fillArc(50.0, 350.0, 30.0, 45.0, 90.0) + + canvas.setColor(Color(0xFF0000)) + canvas.setStrokeWidth(2.0) + canvas.drawLine(0.0, 0.0, 500.0, 400.0) + canvas.drawLine(500.0, 0.0, 0.0, 400.0) + + canvas.setFont(Font.BOLD) + canvas.setFontSize(50.0) + canvas.setColor(Color(0x00FF00)) + canvas.setTextAlign(TextAlign.CENTER) + canvas.drawText("HELLO", 250.0, 100.0) + + canvas.setTextAlign(TextAlign.RIGHT) + canvas.drawText("HELLO", 250.0, 150.0) + + canvas.setTextAlign(TextAlign.LEFT) + canvas.drawText("HELLO", 250.0, 200.0) + + canvas.setFont(Font.FONT_AWESOME) + canvas.drawText(FontAwesome.CHECK, 250.0, 300.0) + + platform.writePng(canvas, "CanvasTest.png") + } +} \ No newline at end of file diff --git a/core/src/jvmTest/kotlin/org/isoron/uhabits/models/CheckmarkListTest.kt b/core/src/commonTest/kotlin/org/isoron/uhabits/models/CheckmarkListTest.kt similarity index 98% rename from core/src/jvmTest/kotlin/org/isoron/uhabits/models/CheckmarkListTest.kt rename to core/src/commonTest/kotlin/org/isoron/uhabits/models/CheckmarkListTest.kt index 9da1185ed..b96965066 100644 --- a/core/src/jvmTest/kotlin/org/isoron/uhabits/models/CheckmarkListTest.kt +++ b/core/src/commonTest/kotlin/org/isoron/uhabits/models/CheckmarkListTest.kt @@ -20,14 +20,12 @@ package org.isoron.uhabits.models import org.isoron.platform.time.* -import org.isoron.uhabits.* import org.isoron.uhabits.models.Checkmark.Companion.CHECKED_AUTOMATIC import org.isoron.uhabits.models.Checkmark.Companion.CHECKED_MANUAL import org.isoron.uhabits.models.Checkmark.Companion.UNCHECKED -import org.junit.Test import kotlin.test.* -class CheckmarkListTest : BaseTest() { +class CheckmarkListTest { private val today = LocalDate(2019, 1, 30) diff --git a/core/src/commonTest/kotlin/ScoreListTest.kt b/core/src/commonTest/kotlin/org/isoron/uhabits/models/ScoreListTest.kt similarity index 100% rename from core/src/commonTest/kotlin/ScoreListTest.kt rename to core/src/commonTest/kotlin/org/isoron/uhabits/models/ScoreListTest.kt diff --git a/core/src/jsMain/kotlin/org/isoron/platform/gui/HtmlCanvas.kt b/core/src/jsMain/kotlin/org/isoron/platform/gui/HtmlCanvas.kt new file mode 100644 index 000000000..e1dde3c56 --- /dev/null +++ b/core/src/jsMain/kotlin/org/isoron/platform/gui/HtmlCanvas.kt @@ -0,0 +1,110 @@ +/* + * Copyright (C) 2016-2019 Álinson Santos Xavier + * + * This file is part of Loop Habit Tracker. + * + * Loop Habit Tracker is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by the + * Free Software Foundation, either version 3 of the License, or (at your + * option) any later version. + * + * Loop Habit Tracker is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +package org.isoron.platform.gui + +import org.w3c.dom.* +import kotlin.browser.* +import kotlin.math.* + +class HtmlCanvas(val canvas: HTMLCanvasElement) : Canvas { + + val ctx = canvas.getContext("2d") as CanvasRenderingContext2D + var fontSize = 12.0 + var fontWeight = "" + var fontFamily = "sans-serif" + var align = CanvasTextAlign.CENTER + + override fun setColor(color: Color) { + val c = "rgb(${color.red * 255}, ${color.green * 255}, ${color.blue * 255})" + ctx.fillStyle = c; + ctx.strokeStyle = c; + } + + override fun drawLine(x1: Double, y1: Double, x2: Double, y2: Double) { + ctx.beginPath() + ctx.moveTo(x1 + 0.5, y1 + 0.5) + ctx.lineTo(x2 + 0.5, y2 + 0.5) + ctx.stroke() + } + + override fun drawText(text: String, x: Double, y: Double) { + ctx.font = "${fontWeight} ${fontSize}px ${fontFamily}" + ctx.textAlign = align + ctx.textBaseline = CanvasTextBaseline.MIDDLE + ctx.fillText(text, x, y) + } + + override fun fillRect(x: Double, y: Double, width: Double, height: Double) { + ctx.fillRect(x - 0.5, y - 0.5, width + 1.0, height + 1.0) + } + + override fun drawRect(x: Double, y: Double, width: Double, height: Double) { + ctx.strokeRect(x - 0.5, y - 0.5, width + 1.0, height + 1.0) + } + + override fun getHeight(): Double { + return canvas.height.toDouble() + } + + override fun getWidth(): Double { + return canvas.width.toDouble() + } + + override fun setFont(font: Font) { + fontWeight = if (font == Font.BOLD) "bold" else "" + fontFamily = if (font == Font.FONT_AWESOME) "FontAwesome" else "sans-serif" + } + + override fun setFontSize(size: Double) { + fontSize = size + } + + override fun setStrokeWidth(size: Double) { + ctx.lineWidth = size + } + + override fun fillArc(centerX: Double, + centerY: Double, + radius: Double, + startAngle: Double, + swipeAngle: Double) { + val from = startAngle / 180 * PI + val to = (startAngle + swipeAngle) / 180 * PI + ctx.beginPath() + ctx.moveTo(centerX, centerY) + ctx.arc(centerX, centerY, radius, -from, -to, swipeAngle >= 0) + ctx.lineTo(centerX, centerY) + ctx.fill() + } + + override fun fillCircle(centerX: Double, centerY: Double, radius: Double) { + ctx.beginPath() + ctx.arc(centerX, centerY, radius, 0.0, 2 * PI) + ctx.fill() + } + + override fun setTextAlign(align: TextAlign) { + this.align = when(align) { + TextAlign.LEFT -> CanvasTextAlign.LEFT + TextAlign.CENTER -> CanvasTextAlign.CENTER + TextAlign.RIGHT -> CanvasTextAlign.RIGHT + } + } +} \ No newline at end of file diff --git a/core/src/jsTest/kotlin/org/isoron/platform/gui/HtmlCanvasTest.kt b/core/src/jsTest/kotlin/org/isoron/platform/gui/HtmlCanvasTest.kt new file mode 100644 index 000000000..ed6da9f1b --- /dev/null +++ b/core/src/jsTest/kotlin/org/isoron/platform/gui/HtmlCanvasTest.kt @@ -0,0 +1,37 @@ +/* + * Copyright (C) 2016-2019 Álinson Santos Xavier + * + * This file is part of Loop Habit Tracker. + * + * Loop Habit Tracker is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by the + * Free Software Foundation, either version 3 of the License, or (at your + * option) any later version. + * + * Loop Habit Tracker is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along + * with this program. If not, see . + */ + +package org.isoron.platform.gui + +import org.w3c.dom.* + +class HtmlCanvasTest(val canvas: HTMLCanvasElement) : CanvasTest.Platform { + + override fun createCanvas(width: Int, height: Int): Canvas { + return HtmlCanvas(canvas) + } + + override fun writePng(canvas: Canvas, filename: String) { + } + + fun testDrawing() { + val test = CanvasTest(this) + test.testDrawing() + } +} \ No newline at end of file diff --git a/core/src/jvmMain/kotlin/org/isoron/platform/gui/JavaCanvas.kt b/core/src/jvmMain/kotlin/org/isoron/platform/gui/JavaCanvas.kt index c3aba7003..f8f34055d 100644 --- a/core/src/jvmMain/kotlin/org/isoron/platform/gui/JavaCanvas.kt +++ b/core/src/jvmMain/kotlin/org/isoron/platform/gui/JavaCanvas.kt @@ -23,6 +23,7 @@ import org.isoron.platform.io.* import java.awt.* import java.awt.RenderingHints.* import java.awt.font.* +import java.awt.image.* import kotlin.math.* fun createFont(path: String): java.awt.Font { @@ -34,15 +35,16 @@ private val NOTO_REGULAR_FONT = createFont("fonts/NotoSans-Regular.ttf") private val NOTO_BOLD_FONT = createFont("fonts/NotoSans-Bold.ttf") private val FONT_AWESOME_FONT = createFont("fonts/FontAwesome.ttf") -class JavaCanvas(val g2d: Graphics2D, - val widthPx: Int, - val heightPx: Int, +class JavaCanvas(val image: BufferedImage, val pixelScale: Double = 2.0) : Canvas { private val frc = FontRenderContext(null, true, true) private var fontSize = 12.0 private var font = Font.REGULAR private var textAlign = TextAlign.CENTER + val widthPx = image.width + val heightPx = image.height + val g2d = image.createGraphics() init { g2d.setRenderingHint(KEY_ANTIALIASING, VALUE_ANTIALIAS_ON); diff --git a/core/src/jvmTest/kotlin/org/isoron/platform/JavaCanvasTest.kt b/core/src/jvmTest/kotlin/org/isoron/platform/JavaCanvasTest.kt index 673a406b9..dbb245827 100644 --- a/core/src/jvmTest/kotlin/org/isoron/platform/JavaCanvasTest.kt +++ b/core/src/jvmTest/kotlin/org/isoron/platform/JavaCanvasTest.kt @@ -26,50 +26,19 @@ import java.io.* import javax.imageio.* -class JavaCanvasTest { - @Test - fun testDrawing() { - val image = BufferedImage(500, 400, BufferedImage.TYPE_INT_RGB) - val canvas = JavaCanvas(image.createGraphics(), 500, 400, pixelScale=1.0) - - canvas.setColor(Color(0x303030)) - canvas.fillRect(0.0, 0.0, 500.0, 400.0) - - canvas.setColor(Color(0x606060)) - canvas.setStrokeWidth(25.0) - canvas.drawRect(100.0, 100.0, 300.0, 200.0) - - canvas.setColor(Color(0xFFFF00)) - canvas.setStrokeWidth(1.0) - canvas.drawRect(0.0, 0.0, 100.0, 100.0) - canvas.fillCircle(50.0, 50.0, 30.0) - canvas.drawRect(0.0, 100.0, 100.0, 100.0) - canvas.fillArc(50.0, 150.0, 30.0, 90.0, 135.0) - canvas.drawRect(0.0, 200.0, 100.0, 100.0) - canvas.fillArc(50.0, 250.0, 30.0, 90.0, -135.0) - canvas.drawRect(0.0, 300.0, 100.0, 100.0) - canvas.fillArc(50.0, 350.0, 30.0, 45.0, 90.0) - - canvas.setColor(Color(0xFF0000)) - canvas.setStrokeWidth(2.0) - canvas.drawLine(0.0, 0.0, 500.0, 400.0) - canvas.drawLine(500.0, 0.0, 0.0, 400.0) +class JavaCanvasTest : CanvasTest.Platform { + private val commonTest = CanvasTest(this) - canvas.setFont(Font.BOLD) - canvas.setFontSize(50.0) - canvas.setColor(Color(0x00FF00)) - canvas.setTextAlign(TextAlign.CENTER) - canvas.drawText("HELLO", 250.0, 100.0) - - canvas.setTextAlign(TextAlign.RIGHT) - canvas.drawText("HELLO", 250.0, 150.0) - - canvas.setTextAlign(TextAlign.LEFT) - canvas.drawText("HELLO", 250.0, 200.0) + @Test + fun testDrawing() = commonTest.testDrawing() - canvas.setFont(Font.FONT_AWESOME) - canvas.drawText(FontAwesome.CHECK, 250.0, 300.0) + override fun createCanvas(width: Int, height: Int): Canvas { + val image = BufferedImage(width, height, BufferedImage.TYPE_INT_RGB) + return JavaCanvas(image, pixelScale=1.0) + } - ImageIO.write(image, "png", File("/tmp/JavaCanvasTest.png")) + override fun writePng(canvas: Canvas, filename: String) { + val javaCanvas = canvas as JavaCanvas + ImageIO.write(javaCanvas.image, "png", File("/tmp/JavaCanvasTest.png")) } } \ No newline at end of file diff --git a/core/src/jvmTest/kotlin/org/isoron/uhabits/Base.kt b/core/src/jvmTest/kotlin/org/isoron/uhabits/Base.kt index 75cbc83d7..14d266300 100644 --- a/core/src/jvmTest/kotlin/org/isoron/uhabits/Base.kt +++ b/core/src/jvmTest/kotlin/org/isoron/uhabits/Base.kt @@ -79,7 +79,7 @@ open class BaseViewTest { component: Component, threshold: Double = 1e-3) { val actual = BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB) - val canvas = JavaCanvas(actual.createGraphics(), width, height) + val canvas = JavaCanvas(actual) val expectedFile: JavaResourceFile val actualPath = "/tmp/${expectedPath}" diff --git a/ios/Tests/Platform/IosCanvasTest.swift b/ios/Tests/Platform/IosCanvasTest.swift index 81982036a..5fc790655 100644 --- a/ios/Tests/Platform/IosCanvasTest.swift +++ b/ios/Tests/Platform/IosCanvasTest.swift @@ -25,8 +25,8 @@ import UIKit class IosCanvasTest : XCTestCase { func testDraw() { UIGraphicsBeginImageContext(CGSize(width: 500, height: 400)) - let canvas = IosCanvas(withBounds: CGRect(x: 0, y: 0, width: 500, height: 400)) + canvas.setColor(color: Color(rgb: 0x303030)) canvas.fillRect(x: 0.0, y: 0.0, width: 500.0, height: 400.0) diff --git a/web/Makefile b/web/Makefile index 9a856eed6..1e475f895 100644 --- a/web/Makefile +++ b/web/Makefile @@ -10,12 +10,10 @@ core: $(test_bundle): test/index.js core mkdir -p build/bundles - npx webpack $< --silent --mode production --output $@ + npx webpack $< --silent --mode development --target web --output $@ test: $(test_bundle) $(node_modules) - mkdir -p build/reports - npx mocha $@ --reporter xunit > build/reports/tests.xml - npx mocha $@ + open test/index.html clean: rm -rf build diff --git a/web/package-lock.json b/web/package-lock.json index a4e2653ca..8f5f45c23 100644 --- a/web/package-lock.json +++ b/web/package-lock.json @@ -2231,6 +2231,11 @@ "readable-stream": "^2.3.6" } }, + "fontawesome": { + "version": "5.6.3", + "resolved": "https://registry.npmjs.org/fontawesome/-/fontawesome-5.6.3.tgz", + "integrity": "sha512-FCc+CawwsJWWprVEg9X14yI7zI+l9YVAyhzgu70qwGeDn0tLLDH/dVfqgij72g4BBGgLGfK2qnvFGAmYUkhaWg==" + }, "for-in": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", diff --git a/web/test/FontAwesome.ttf b/web/test/FontAwesome.ttf new file mode 100644 index 000000000..e89738de5 Binary files /dev/null and b/web/test/FontAwesome.ttf differ diff --git a/web/test/canvas.html b/web/test/canvas.html new file mode 100644 index 000000000..77eabfa5c --- /dev/null +++ b/web/test/canvas.html @@ -0,0 +1,21 @@ + + + + Canvas Test + + + + + + + + diff --git a/web/test/index.html b/web/test/index.html new file mode 100644 index 000000000..198a3e01e --- /dev/null +++ b/web/test/index.html @@ -0,0 +1,15 @@ + + + + Mocha Tests + + + +
+ + + + + + + diff --git a/web/test/index.js b/web/test/index.js index d6b5eb38d..8e7ea7631 100644 --- a/web/test/index.js +++ b/web/test/index.js @@ -1,2 +1,3 @@ var assert = require('assert'); var coreTest = require('core_test'); +document.coreTest = coreTest