Refactor travis testing

This commit is contained in:
2021-06-07 12:36:22 -06:00
commit 8fd76d9a49
34 changed files with 288 additions and 0 deletions

12
src/nat/Archive.hx Normal file
View File

@@ -0,0 +1,12 @@
package nat;
import sys.FileSystem;
import kiss.Prelude;
import sys.io.File;
import tink.Json;
import uuid.Uuid;
using haxe.io.Path;
@:build(kiss.Kiss.build())
class Archive {}

42
src/nat/Archive.kiss Normal file
View File

@@ -0,0 +1,42 @@
(defnew [&prop :String archiveDir]
[:Array<System> systems
[]
:Map<String,Template> templates
(new Map)
:Map<String,Entry> entries
(let [entryFiles (FileSystem.readDirectory (Path.join [archiveDir "entries"]))]
(for file entryFiles =>(file.withoutExtension) ~(the Entry (Json.parse (File.getContent (Path.join [archiveDir "entries" file]))))))])
(defmethod addSystem [:System system]
// Assign entries to the Systems that care about them
(doFor =>id entry entries
(system.checkEntryInOrOut this entry))
(systems.push system))
(defmethod addTemplate [name template]
(dictSet templates name template))
(defmethod :Entry createEntry [template]
(let [e (_newEntry)]
(.prepareEntry (dictGet templates template) e)
(doFor system systems
(system.checkEntryInOrOut this e))
e))
(defmethod saveEntry [:Entry e]
(File.saveContent
(Path.join [archiveDir "entries" (e.id.withExtension "json")])
(Json.stringify e))
// TODO save its components? but it's not obvious how, because it only knows the string keys of them.
// Better yet, retrieving components with mutable access should be done through a
// (withComponent...) macro that serializes the component after the block is done.
//
)
(defun :Entry _newEntry []
(object
id (Uuid.v4)
components (new Map)
files []))

20
src/nat/BoolExpInterp.hx Normal file
View File

@@ -0,0 +1,20 @@
package nat;
import kiss.KissInterp;
import hscript.Parser;
import kiss.Prelude;
@:build(kiss.Kiss.build())
class BoolExpInterp extends KissInterp {
public function new() {
super();
}
override function resolve(id:String):Dynamic {
return try {
super.resolve(id);
} catch (e:Dynamic) {
false;
}
}
}

View File

@@ -0,0 +1,9 @@
(defun eval [:String expStr :Array<String> activeConditions]
(let [hscriptExp
(.parseString (new Parser)
(Prelude.convertToHScript expStr))
interp
(new BoolExpInterp)]
(doFor condition activeConditions
(interp.variables.set condition true))
?(interp.execute hscriptExp)))

7
src/nat/Entry.hx Normal file
View File

@@ -0,0 +1,7 @@
package nat;
typedef Entry = {
id:String,
components:Map<String, String>,
files:Array<String>
};

11
src/nat/Lib.hx Normal file
View File

@@ -0,0 +1,11 @@
package nat;
import kiss.Prelude;
import sys.io.File;
import tink.Json;
import uuid.Uuid;
using haxe.io.Path;
@:build(kiss.Kiss.build())
class Lib {}

20
src/nat/Lib.kiss Normal file
View File

@@ -0,0 +1,20 @@
// Lib is its own class because, while it would make sense to group its functions and macros in Archive.kiss,
// other files would not be able to (load "Archive.kiss") for the macro definitions without taking on Archive's constructor.
(defmacro hasComponent [e componentType]
`(.exists .components ,e ,(symbolName componentType)))
// TODO add to the documentation a hint that macros should use fully qualified paths so macro caller classes don't need to import everything
(defmacro getComponent [archive e componentType]
`(the nat.components ,componentType
(tink.Json.parse
(sys.io.File.getContent
(haxe.io.Path.join [.archiveDir (the nat.Archive ,archive) "components" (+ (dictGet (the Map<String,String> .components ,e) ,(symbolName componentType)) ".json")])))))
(defun tagList [archive e]
(let [t
(getComponent archive e Tags)]
(collect (t.keys))))
(defun tagsMatch [archive e tagsBoolExp]
(BoolExpInterp.eval tagsBoolExp (tagList archive e)))

9
src/nat/System.hx Normal file
View File

@@ -0,0 +1,9 @@
package nat;
import kiss.Prelude;
typedef EntryChecker = (Archive, Entry) -> Bool;
typedef EntryProcessor = (Archive, Entry) -> Void;
@:build(kiss.Kiss.build())
class System {}

13
src/nat/System.kiss Normal file
View File

@@ -0,0 +1,13 @@
(defprop :Map<String,Entry> entries (new Map))
(defmethod :Void process [:Archive archive]
(doFor e (entries.iterator) (processEntry archive e)))
(defnew [&prop :EntryChecker canProcessEntry
&prop :EntryProcessor processEntry]
[])
(defmethod :Void checkEntryInOrOut [:Archive archive :Entry e]
(if (canProcessEntry archive e)
(dictSet entries e.id e)
(entries.remove e.id)))

5
src/nat/Template.hx Normal file
View File

@@ -0,0 +1,5 @@
package nat;
interface Template {
function prepareEntry(e:Entry):Void;
}

View File

@@ -0,0 +1,3 @@
package nat.components;
typedef Tags = Map<String, Date>;

View File

@@ -0,0 +1,4 @@
package nat.components;
typedef Name = String;
typedef Author = String;

View File

@@ -0,0 +1,3 @@
package nat.components;
typedef Tags = Map<String, Int>;

View File

@@ -0,0 +1,6 @@
package nat.systems;
import kiss.Prelude;
@:build(kiss.Kiss.build())
class TagSystem extends System {}

View File

@@ -0,0 +1,9 @@
(load "../Lib.kiss")
// TODO make a &super annotation that passes an argument to the super constructor
(defnew [&prop :String tagFilterString
&prop :EntryProcessor processor]
[]
(super
(lambda [:Archive archive :Entry e] (tagsMatch archive e tagFilterString))
processor))