mirror of
https://github.com/processing/processing4.git
synced 2026-01-27 10:21:26 +01:00
Merge branch 'test-schema' into gradle-welcome-screen
This commit is contained in:
@@ -35,6 +35,11 @@ sourceSets{
|
||||
srcDirs("resources", listOf("languages", "fonts", "theme").map { "../build/shared/lib/$it" })
|
||||
}
|
||||
}
|
||||
test{
|
||||
kotlin{
|
||||
srcDirs("test")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
compose.desktop {
|
||||
@@ -105,6 +110,17 @@ dependencies {
|
||||
|
||||
implementation(libs.compottie)
|
||||
implementation(libs.kaml)
|
||||
|
||||
testImplementation(kotlin("test"))
|
||||
testImplementation(libs.mockitoKotlin)
|
||||
testImplementation(libs.junitJupiter)
|
||||
testImplementation(libs.junitJupiterParams)
|
||||
}
|
||||
|
||||
tasks.test {
|
||||
useJUnitPlatform()
|
||||
workingDir = file("build/test")
|
||||
workingDir.mkdirs()
|
||||
}
|
||||
|
||||
tasks.compileJava{
|
||||
|
||||
@@ -1364,10 +1364,10 @@ public class Base {
|
||||
* @param schemeUri the full URI, including pde://
|
||||
*/
|
||||
public Editor handleScheme(String schemeUri) {
|
||||
// var result = Schema.handleSchema(schemeUri, this);
|
||||
// if (result != null) {
|
||||
// return result;
|
||||
// }
|
||||
var result = Schema.handleSchema(schemeUri, this);
|
||||
if (result != null) {
|
||||
return result;
|
||||
}
|
||||
|
||||
String location = schemeUri.substring(6);
|
||||
if (location.length() > 0) {
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
package processing.app;
|
||||
|
||||
import java.awt.EventQueue;
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
import java.util.zip.ZipFile;
|
||||
@@ -330,7 +329,7 @@ public class Library extends LocalContribution {
|
||||
* imports to specific libraries.
|
||||
* @param importToLibraryTable mapping from package names to Library objects
|
||||
*/
|
||||
static boolean instruced = false;
|
||||
static boolean instructed = false;
|
||||
// public void addPackageList(HashMap<String,Library> importToLibraryTable) {
|
||||
public void addPackageList(Map<String, List<Library>> importToLibraryTable) {
|
||||
// PApplet.println(packages);
|
||||
@@ -343,8 +342,8 @@ public class Library extends LocalContribution {
|
||||
libraries = new ArrayList<>();
|
||||
importToLibraryTable.put(pkg, libraries);
|
||||
} else {
|
||||
if(!instruced) {
|
||||
instruced = true;
|
||||
if(!instructed) {
|
||||
instructed = true;
|
||||
Messages.err("The library found in");
|
||||
Messages.err(getPath());
|
||||
Messages.err("conflicts with");
|
||||
|
||||
@@ -53,7 +53,11 @@ class Schema {
|
||||
private fun handleSketchUrl(uri: URI): Editor?{
|
||||
val url = File(uri.path.replace("/url/", ""))
|
||||
|
||||
val tempSketchFolder = File(Base.untitledFolder, url.nameWithoutExtension)
|
||||
val rand = (1..6)
|
||||
.map { (('a'..'z') + ('A'..'Z')).random() }
|
||||
.joinToString("")
|
||||
|
||||
val tempSketchFolder = File(File(Base.untitledFolder, rand), url.nameWithoutExtension)
|
||||
tempSketchFolder.mkdirs()
|
||||
val tempSketchFile = File(tempSketchFolder, "${tempSketchFolder.name}.pde")
|
||||
|
||||
@@ -71,7 +75,7 @@ class Schema {
|
||||
?.map { it.split("=") }
|
||||
?.associate {
|
||||
URLDecoder.decode(it[0], StandardCharsets.UTF_8) to
|
||||
URLDecoder.decode(it[1], StandardCharsets.UTF_8)
|
||||
URLDecoder.decode(it[1], StandardCharsets.UTF_8)
|
||||
}
|
||||
?: emptyMap()
|
||||
options["data"]?.let{ data ->
|
||||
@@ -81,7 +85,7 @@ class Schema {
|
||||
downloadFiles(uri, code, File(sketchFolder, "code"))
|
||||
}
|
||||
options["pde"]?.let{ pde ->
|
||||
downloadFiles(uri, pde, sketchFolder)
|
||||
downloadFiles(uri, pde, sketchFolder, "pde")
|
||||
}
|
||||
options["mode"]?.let{ mode ->
|
||||
val modeFile = File(sketchFolder, "sketch.properties")
|
||||
@@ -89,7 +93,7 @@ class Schema {
|
||||
}
|
||||
|
||||
}
|
||||
private fun downloadFiles(uri: URI, urlList: String, targetFolder: File){
|
||||
private fun downloadFiles(uri: URI, urlList: String, targetFolder: File, extension: String = ""){
|
||||
Thread{
|
||||
targetFolder.mkdirs()
|
||||
|
||||
@@ -101,37 +105,31 @@ class Schema {
|
||||
val files = urlList.split(",")
|
||||
|
||||
files.filter { it.isNotBlank() }
|
||||
.map{ it.split(":", limit = 2) }
|
||||
.map{ segments ->
|
||||
if(segments.size == 2){
|
||||
if(segments[0].isBlank()){
|
||||
return@map listOf(null, segments[1])
|
||||
}
|
||||
return@map segments
|
||||
}
|
||||
return@map listOf(null, segments[0])
|
||||
.map {
|
||||
if (it.contains(":")) it
|
||||
else "$it:$it"
|
||||
}
|
||||
.map{ it.split(":", limit = 2) }
|
||||
.forEach { (name, content) ->
|
||||
var target = File(targetFolder, name)
|
||||
if(extension.isNotBlank() && target.extension != extension){
|
||||
target = File(targetFolder, "$name.$extension")
|
||||
}
|
||||
try{
|
||||
// Try to decode the content as base64
|
||||
val file = Base64.getDecoder().decode(content)
|
||||
if(name == null){
|
||||
if(name.isBlank()){
|
||||
Messages.err("Base64 files needs to start with a file name followed by a colon")
|
||||
return@forEach
|
||||
}
|
||||
File(targetFolder, name).writeBytes(file)
|
||||
target.writeBytes(file)
|
||||
}catch(_: IllegalArgumentException){
|
||||
// Assume it's a URL and download it
|
||||
var url = URI.create(content)
|
||||
if(url.host == null){
|
||||
url = URI.create("https://$base/$content")
|
||||
}
|
||||
if(url.scheme == null){
|
||||
url = URI.create("https://$content")
|
||||
}
|
||||
|
||||
val target = File(targetFolder, name ?: url.path.split("/").last())
|
||||
url.toURL().openStream().use { input ->
|
||||
val url = URL(when{
|
||||
content.startsWith("https://") -> content
|
||||
content.startsWith("http://") -> content.replace("http://", "https://")
|
||||
URL("https://$content").path.isNotBlank() -> "https://$content"
|
||||
else -> "https://$base/$content"
|
||||
})
|
||||
url.openStream().use { input ->
|
||||
target.outputStream().use { output ->
|
||||
input.copyTo(output)
|
||||
}
|
||||
@@ -148,7 +146,7 @@ class Schema {
|
||||
?.map { it.split("=") }
|
||||
?.associate {
|
||||
URLDecoder.decode(it[0], StandardCharsets.UTF_8) to
|
||||
URLDecoder.decode(it[1], StandardCharsets.UTF_8)
|
||||
URLDecoder.decode(it[1], StandardCharsets.UTF_8)
|
||||
}
|
||||
?: emptyMap()
|
||||
for ((key, value) in options){
|
||||
|
||||
113
app/test/processing/app/SchemaTest.kt
Normal file
113
app/test/processing/app/SchemaTest.kt
Normal file
@@ -0,0 +1,113 @@
|
||||
package processing.app
|
||||
|
||||
import org.junit.jupiter.params.ParameterizedTest
|
||||
import org.junit.jupiter.params.provider.ValueSource
|
||||
import org.mockito.ArgumentCaptor
|
||||
import org.mockito.MockedStatic
|
||||
import org.mockito.Mockito.mockStatic
|
||||
import org.mockito.kotlin.mock
|
||||
import org.mockito.kotlin.verify
|
||||
import java.io.File
|
||||
import kotlin.io.encoding.Base64
|
||||
import kotlin.io.encoding.ExperimentalEncodingApi
|
||||
import kotlin.test.Test
|
||||
|
||||
|
||||
class SchemaTest {
|
||||
private val base: Base = mock<Base>{
|
||||
|
||||
}
|
||||
companion object {
|
||||
val preferences: MockedStatic<Preferences> = mockStatic(Preferences::class.java)
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
fun testLocalFiles() {
|
||||
val file = "/this/is/a/local/file"
|
||||
Schema.handleSchema("pde://$file", base)
|
||||
verify(base).handleOpen(file)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testNewSketch() {
|
||||
Schema.handleSchema("pde://sketch/new", base)
|
||||
verify(base).handleNew()
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalEncodingApi::class)
|
||||
@Test
|
||||
fun testBase64SketchAndExtraFiles() {
|
||||
val sketch = """
|
||||
void setup(){
|
||||
|
||||
}
|
||||
void draw(){
|
||||
|
||||
}
|
||||
""".trimIndent()
|
||||
|
||||
val base64 = Base64.encode(sketch.toByteArray())
|
||||
Schema.handleSchema("pde://sketch/base64/$base64?pde=Module:$base64", base)
|
||||
val captor = ArgumentCaptor.forClass(String::class.java)
|
||||
|
||||
verify(base).handleOpenUntitled(captor.capture())
|
||||
|
||||
val file = File(captor.value)
|
||||
assert(file.exists())
|
||||
assert(file.readText() == sketch)
|
||||
|
||||
val extra = file.parentFile.resolve("Module.pde")
|
||||
assert(extra.exists())
|
||||
assert(extra.readText() == sketch)
|
||||
file.parentFile.deleteRecursively()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testURLSketch() {
|
||||
Schema.handleSchema("pde://sketch/url/github.com/processing/processing-examples/raw/refs/heads/main/Basics/Arrays/Array/Array.pde", base)
|
||||
|
||||
val captor = ArgumentCaptor.forClass(String::class.java)
|
||||
verify(base).handleOpenUntitled(captor.capture())
|
||||
val output = File(captor.value)
|
||||
assert(output.exists())
|
||||
assert(output.name == "Array.pde")
|
||||
assert(output.extension == "pde")
|
||||
assert(output.parentFile.name == "Array")
|
||||
|
||||
output.parentFile.parentFile.deleteRecursively()
|
||||
}
|
||||
|
||||
@ParameterizedTest
|
||||
@ValueSource(strings = [
|
||||
"Module.pde:https://github.com/processing/processing-examples/raw/refs/heads/main/Basics/Arrays/ArrayObjects/Module.pde",
|
||||
"Module.pde",
|
||||
"Module:Module.pde",
|
||||
"Module:https://github.com/processing/processing-examples/raw/refs/heads/main/Basics/Arrays/ArrayObjects/Module.pde",
|
||||
"Module.pde:github.com/processing/processing-examples/raw/refs/heads/main/Basics/Arrays/ArrayObjects/Module.pde"
|
||||
])
|
||||
fun testURLSketchWithFile(file: String){
|
||||
Schema.handleSchema("pde://sketch/url/github.com/processing/processing-examples/raw/refs/heads/main/Basics/Arrays/ArrayObjects/ArrayObjects.pde?pde=$file", base)
|
||||
|
||||
val captor = ArgumentCaptor.forClass(String::class.java)
|
||||
verify(base).handleOpenUntitled(captor.capture())
|
||||
|
||||
// wait for threads to resolve
|
||||
Thread.sleep(1000)
|
||||
|
||||
val output = File(captor.value)
|
||||
assert(output.parentFile.name == "ArrayObjects")
|
||||
assert(output.exists())
|
||||
assert(output.parentFile.resolve("Module.pde").exists())
|
||||
output.parentFile.parentFile.deleteRecursively()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testPreferences() {
|
||||
Schema.handleSchema("pde://preferences?test=value", base)
|
||||
preferences.verify {
|
||||
Preferences.set("test", "value")
|
||||
Preferences.save()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -63,7 +63,7 @@ dependencies {
|
||||
```
|
||||
|
||||
## Developing for Core
|
||||
The easiest way to develop for core, without the need to build the whole project, is to use the `examples/src` sketches. In
|
||||
The easiest way to develop for core, without the need to build the whole project, is to use the `examples/src` sketches.
|
||||
|
||||
## PGraphics Modes
|
||||
Documentation on how to develop graphics modes as a library should go here.
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
kotlin = "2.0.20"
|
||||
compose-plugin = "1.7.1"
|
||||
jogl = "2.5.0"
|
||||
jupiter = "5.12.0"
|
||||
|
||||
[libraries]
|
||||
jogl = { module = "org.jogamp.jogl:jogl-all-main", version.ref = "jogl" }
|
||||
@@ -12,7 +13,10 @@ jnaplatform = { module = "net.java.dev.jna:jna-platform", version = "5.12.1" }
|
||||
compottie = { module = "io.github.alexzhirkevich:compottie", version = "2.0.0-rc02" }
|
||||
kaml = { module = "com.charleskorn.kaml:kaml", version = "0.65.0" }
|
||||
junit = { module = "junit:junit", version = "4.13.2" }
|
||||
junitJupiter = { module = "org.junit.jupiter:junit-jupiter", version.ref = "jupiter" }
|
||||
junitJupiterParams = { module = "org.junit.jupiter:junit-jupiter-params", version.ref = "jupiter" }
|
||||
mockito = { module = "org.mockito:mockito-core", version = "4.11.0" }
|
||||
mockitoKotlin = { module = "org.mockito.kotlin:mockito-kotlin", version = "5.4.0" }
|
||||
antlr = { module = "org.antlr:antlr4", version = "4.7.2" }
|
||||
eclipseJDT = { module = "org.eclipse.jdt:org.eclipse.jdt.core", version = "3.16.0" }
|
||||
eclipseJDTCompiler = { module = "org.eclipse.jdt:org.eclipse.jdt.compiler.apt", version = "1.3.400" }
|
||||
|
||||
Reference in New Issue
Block a user