diff options
| author | Elizabeth Hunt <me@liz.coffee> | 2026-02-15 10:08:30 -0800 |
|---|---|---|
| committer | Elizabeth Hunt <me@liz.coffee> | 2026-02-15 10:12:08 -0800 |
| commit | d6a294e14604aecd9046cbc19dc1837ca694fbb0 (patch) | |
| tree | 616e87e59f9ee95253acce05aa26405523a9acd7 /core/src/test/java/coffee/liz/abstractionengine | |
| parent | 347564c592325007cb81dbdf1a07831c2ae003c3 (diff) | |
| download | the-abstraction-engine-java-d6a294e14604aecd9046cbc19dc1837ca694fbb0.tar.gz the-abstraction-engine-java-d6a294e14604aecd9046cbc19dc1837ca694fbb0.zip | |
feat: Adding ValueEmitter, LambdaEvaluatorSystem
Diffstat (limited to 'core/src/test/java/coffee/liz/abstractionengine')
6 files changed, 121 insertions, 9 deletions
diff --git a/core/src/test/java/coffee/liz/abstractionengine/app/ui/editor/vim/VimEngineTest.java b/core/src/test/java/coffee/liz/abstractionengine/app/ui/editor/vim/VimEngineTest.java index d87204d..ca1ee9c 100644 --- a/core/src/test/java/coffee/liz/abstractionengine/app/ui/editor/vim/VimEngineTest.java +++ b/core/src/test/java/coffee/liz/abstractionengine/app/ui/editor/vim/VimEngineTest.java @@ -351,6 +351,17 @@ public class VimEngineTest { } @Test + public void characterPasteOnEmptyLineInsertsIntoThatLine() { + final FakeBuffer buffer = new FakeBuffer("cat\n\ndog", 0); + final VimEngine controller = new VimEngine(buffer, status -> { + }); + + type(controller, 'y', 'w', 'j', 'p'); + + assertEquals("cat\ncat\ndog", buffer.getText()); + } + + @Test public void dwDeletesWord() { final FakeBuffer buffer = new FakeBuffer("one two", 0); final VimEngine controller = new VimEngine(buffer, status -> { diff --git a/core/src/test/java/coffee/liz/abstractionengine/grid/system/GridCollisionPropagatationSystemTest.java b/core/src/test/java/coffee/liz/abstractionengine/grid/system/GridCollisionPropagatationSystemTest.java index 9f1ff41..ffee701 100644 --- a/core/src/test/java/coffee/liz/abstractionengine/grid/system/GridCollisionPropagatationSystemTest.java +++ b/core/src/test/java/coffee/liz/abstractionengine/grid/system/GridCollisionPropagatationSystemTest.java @@ -15,6 +15,7 @@ import coffee.liz.abstractionengine.grid.component.GridPosition; import coffee.liz.ecs.math.Vec2i; import coffee.liz.ecs.model.Entity; import coffee.liz.ecs.model.World; +import coffee.liz.ecs.model.Query; import lombok.Getter; import org.junit.jupiter.api.Test; @@ -59,7 +60,7 @@ final class GridCollisionPropagatationSystemTest { final Entity wall = Entity.builder().id(3).build().add(WALL_COLLIDABLE).add(new GridPosition(Vec2i.EAST)); // Propagation takes priority because priority(0) is lower - when(world.query(Set.of(GridMomentum.class, GridPosition.class, GridCollidable.class))) + when(world.resolve(Query.allOf(GridMomentum.class, GridPosition.class, GridCollidable.class))) .thenReturn(Set.of(pusher)); when(indexSystem.entitiesAt(Vec2i.ZERO)).thenReturn(List.of(pusher)); @@ -86,7 +87,7 @@ final class GridCollisionPropagatationSystemTest { final Entity wall = Entity.builder().id(3).build().add(WALL_COLLIDABLE) .add(new GridPosition(Vec2i.EAST.scale(2, 0))); - when(world.query(Set.of(GridMomentum.class, GridPosition.class, GridCollidable.class))) + when(world.resolve(Query.allOf(GridMomentum.class, GridPosition.class, GridCollidable.class))) .thenReturn(Set.of(pusher, toPropagate)); when(indexSystem.entitiesAt(Vec2i.ZERO)).thenReturn(List.of(pusher)); @@ -111,7 +112,7 @@ final class GridCollisionPropagatationSystemTest { final Entity pusher = Entity.builder().id(1).build().add(PROPAGATE_COLLIDABLE).add(new GridMomentum(Vec2i.EAST)) .add(new GridPosition(Vec2i.ZERO)); - when(world.query(Set.of(GridMomentum.class, GridPosition.class, GridCollidable.class))) + when(world.resolve(Query.allOf(GridMomentum.class, GridPosition.class, GridCollidable.class))) .thenReturn(Set.of(pusher)); when(indexSystem.entitiesAt(Vec2i.ZERO)).thenReturn(List.of(pusher)); @@ -133,7 +134,7 @@ final class GridCollisionPropagatationSystemTest { final Entity pusher = Entity.builder().id(1).build().add(PROPAGATE_COLLIDABLE).add(new GridMomentum(Vec2i.ZERO)) .add(new GridPosition(Vec2i.ZERO)); - when(world.query(Set.of(GridMomentum.class, GridPosition.class, GridCollidable.class))) + when(world.resolve(Query.allOf(GridMomentum.class, GridPosition.class, GridCollidable.class))) .thenReturn(Set.of(pusher)); when(indexSystem.entitiesAt(Vec2i.ZERO)).thenReturn(List.of(pusher)); @@ -160,7 +161,7 @@ final class GridCollisionPropagatationSystemTest { final Entity swallower = Entity.builder().id(2).build().add(swallowCollidable) .add(new GridPosition(Vec2i.EAST)); - when(world.query(Set.of(GridMomentum.class, GridPosition.class, GridCollidable.class))) + when(world.resolve(Query.allOf(GridMomentum.class, GridPosition.class, GridCollidable.class))) .thenReturn(Set.of(pusher)); when(indexSystem.entitiesAt(Vec2i.ZERO)).thenReturn(List.of(pusher)); diff --git a/core/src/test/java/coffee/liz/abstractionengine/grid/system/GridIndexSystemTest.java b/core/src/test/java/coffee/liz/abstractionengine/grid/system/GridIndexSystemTest.java index f751927..9fd1a7c 100644 --- a/core/src/test/java/coffee/liz/abstractionengine/grid/system/GridIndexSystemTest.java +++ b/core/src/test/java/coffee/liz/abstractionengine/grid/system/GridIndexSystemTest.java @@ -9,6 +9,7 @@ import coffee.liz.abstractionengine.grid.component.GridPosition; import coffee.liz.ecs.math.Vec2i; import coffee.liz.ecs.model.Entity; import coffee.liz.ecs.model.World; +import coffee.liz.ecs.model.Query; import org.junit.jupiter.api.Test; import org.mockito.Mockito; @@ -25,7 +26,7 @@ class GridIndexSystemTest { alpha.add(new GridPosition(new Vec2i(1, 2))); final Entity beta = Entity.builder().id(12).build(); beta.add(new GridPosition(new Vec2i(0, 0))); - when(world.query(Set.of(GridPosition.class))).thenReturn(Set.of(alpha, beta)); + when(world.resolve(Query.allOf(GridPosition.class))).thenReturn(Set.of(alpha, beta)); system.update(world, GridInputState.builder().movement(Vec2i.NORTH).build(), Duration.ZERO); @@ -40,7 +41,7 @@ class GridIndexSystemTest { final World<GridInputState> world = mockWorld(); final Entity moving = Entity.builder().id(77).build(); moving.add(new GridPosition(Vec2i.ZERO)); - when(world.query(Set.of(GridPosition.class))).thenReturn(Set.of(moving)).thenReturn(Set.of()); + when(world.resolve(Query.allOf(GridPosition.class))).thenReturn(Set.of(moving)).thenReturn(Set.of()); system.update(world, GridInputState.builder().movement(Vec2i.EAST).build(), Duration.ZERO); assertTrue(system.entitiesAt(Vec2i.ZERO).contains(moving)); diff --git a/core/src/test/java/coffee/liz/abstractionengine/grid/system/GridMovementSystemTest.java b/core/src/test/java/coffee/liz/abstractionengine/grid/system/GridMovementSystemTest.java index 2731a7b..0c4ad80 100644 --- a/core/src/test/java/coffee/liz/abstractionengine/grid/system/GridMovementSystemTest.java +++ b/core/src/test/java/coffee/liz/abstractionengine/grid/system/GridMovementSystemTest.java @@ -10,6 +10,7 @@ import coffee.liz.abstractionengine.grid.component.GridPosition; import coffee.liz.ecs.math.Vec2i; import coffee.liz.ecs.model.Entity; import coffee.liz.ecs.model.World; +import coffee.liz.ecs.model.Query; import org.junit.jupiter.api.Test; import org.mockito.Mockito; @@ -25,7 +26,7 @@ final class GridMovementSystemTest { subject.add(new GridControllable()); subject.add(new GridPosition(Vec2i.ZERO)); final Set<Entity> controllableEntities = Set.of(subject); - when(world.query(Set.of(GridControllable.class, GridPosition.class))).thenReturn(controllableEntities); + when(world.resolve(Query.allOf(GridControllable.class, GridPosition.class))).thenReturn(controllableEntities); final GridInputState inputState = GridInputState.builder().movement(Vec2i.SOUTH).build(); final GridMovementSystem system = new GridMovementSystem(); diff --git a/core/src/test/java/coffee/liz/abstractionengine/grid/system/GridPhysicsSystemTest.java b/core/src/test/java/coffee/liz/abstractionengine/grid/system/GridPhysicsSystemTest.java index c6a0cfe..b8b2d1c 100644 --- a/core/src/test/java/coffee/liz/abstractionengine/grid/system/GridPhysicsSystemTest.java +++ b/core/src/test/java/coffee/liz/abstractionengine/grid/system/GridPhysicsSystemTest.java @@ -10,6 +10,7 @@ import coffee.liz.ecs.math.Vec2; import coffee.liz.ecs.math.Vec2i; import coffee.liz.ecs.model.Entity; import coffee.liz.ecs.model.World; +import coffee.liz.ecs.model.Query; import org.junit.jupiter.api.Test; import org.mockito.Mockito; @@ -24,7 +25,7 @@ final class GridPhysicsSystemTest { final Entity body = Entity.builder().id(3).build(); body.add(new GridPosition(Vec2i.ZERO)); body.add(new GridMomentum(Vec2i.EAST)); - when(world.query(Set.of(GridMomentum.class, GridPosition.class))).thenReturn(Set.of(body)); + when(world.resolve(Query.allOf(GridMomentum.class, GridPosition.class))).thenReturn(Set.of(body)); final GridPhysicsSystem system = new GridPhysicsSystem(); system.update(world, GridInputState.builder().movement(Vec2i.NORTH).build(), Duration.ZERO); diff --git a/core/src/test/java/coffee/liz/abstractionengine/grid/system/LambdaEvaluatorSystemTest.java b/core/src/test/java/coffee/liz/abstractionengine/grid/system/LambdaEvaluatorSystemTest.java new file mode 100644 index 0000000..6829417 --- /dev/null +++ b/core/src/test/java/coffee/liz/abstractionengine/grid/system/LambdaEvaluatorSystemTest.java @@ -0,0 +1,97 @@ +package coffee.liz.abstractionengine.grid.system; + +import coffee.liz.abstractionengine.grid.component.GridInputState; +import coffee.liz.abstractionengine.grid.component.GridMomentum; +import coffee.liz.abstractionengine.grid.component.GridPosition; +import coffee.liz.abstractionengine.grid.component.LambdaTerm; +import coffee.liz.abstractionengine.grid.component.Substitution; +import coffee.liz.ecs.DAGWorld; +import coffee.liz.ecs.math.Vec2; +import coffee.liz.ecs.math.Vec2i; +import coffee.liz.ecs.model.Entity; +import coffee.liz.ecs.model.World; +import coffee.liz.ecs.model.Query; +import coffee.liz.lambda.ast.SourceCode; +import org.junit.jupiter.api.Test; + +import java.time.Duration; +import java.util.Map; +import java.util.Set; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertInstanceOf; + +public class LambdaEvaluatorSystemTest { + private static final Vec2<Integer> GRID_DIMENSIONS = Vec2i.builder().x(3).y(3).build(); + private static final SourceCode IDENTITY = SourceCode.ofArrow("(x -> x)(y)"); + private static final SourceCode FREE = SourceCode.ofArrow("z"); + + @Test + public void testDependenciesSatisfied() { + final World<GridInputState> world = new DAGWorld<>(new GridIndexSystem(GRID_DIMENSIONS), + new LambdaEvaluatorSystem(SourceCode.Syntax.ARROW)); + + world.createEntity().add(new GridPosition(Vec2i.builder().x(1).y(1).build())).add(new LambdaTerm(IDENTITY)) + .add(new Substitution(Vec2i.EAST, Map.of("y", Vec2i.builder().x(0).y(0).build()))); + world.createEntity().add(new GridPosition(Vec2i.builder().x(0).y(0).build())).add(new LambdaTerm(FREE)); + + world.update(GridInputState.builder().build(), Duration.ZERO); + + assertEquals(3, world.resolve(Query.allOf()).size()); + final Set<Entity> emittedTerms = world.resolve(Query.allOf(GridMomentum.class, LambdaTerm.class)); + assertEquals(1, emittedTerms.size()); + final SourceCode emitted = emittedTerms.iterator().next().get(LambdaTerm.class).getTerm(); + final SourceCode.Arrow arrow = assertInstanceOf(SourceCode.Arrow.class, emitted); + assertEquals("z", arrow.source()); + } + + @Test + public void testEmitsLambdaSyntax() { + final World<GridInputState> world = new DAGWorld<>(new GridIndexSystem(GRID_DIMENSIONS), + new LambdaEvaluatorSystem(SourceCode.Syntax.LAMBDA)); + + world.createEntity().add(new GridPosition(Vec2i.builder().x(1).y(1).build())).add(new LambdaTerm(IDENTITY)) + .add(new Substitution(Vec2i.EAST, Map.of("y", Vec2i.builder().x(0).y(0).build()))); + world.createEntity().add(new GridPosition(Vec2i.builder().x(0).y(0).build())).add(new LambdaTerm(FREE)); + + world.update(GridInputState.builder().build(), Duration.ZERO); + + final Set<Entity> emittedTerms = world.resolve(Query.allOf(GridMomentum.class, LambdaTerm.class)); + assertEquals(1, emittedTerms.size()); + final SourceCode emitted = emittedTerms.iterator().next().get(LambdaTerm.class).getTerm(); + final SourceCode.Lambda lambda = assertInstanceOf(SourceCode.Lambda.class, emitted); + assertEquals("z", lambda.source()); + } + + @Test + public void testDependenciesUnsatisfied() { + final World<GridInputState> world = new DAGWorld<>(new GridIndexSystem(GRID_DIMENSIONS), + new LambdaEvaluatorSystem(SourceCode.Syntax.ARROW)); + + world.createEntity().add(new GridPosition(Vec2i.builder().x(1).y(1).build())).add(new LambdaTerm(IDENTITY)) + .add(new Substitution(Vec2i.EAST, Map.of("y", Vec2i.builder().x(0).y(0).build()))); + + world.update(GridInputState.builder().build(), Duration.ZERO); + + assertEquals(1, world.resolve(Query.allOf()).size()); + assertEquals(0, world.resolve(Query.allOf(GridMomentum.class, LambdaTerm.class)).size()); + } + + @Test + public void testSpawnsInSubstitutionDirection() { + final Vec2<Integer> spawnMomentum = Vec2i.builder().x(0).y(-1).build(); + final World<GridInputState> world = new DAGWorld<>(new GridIndexSystem(GRID_DIMENSIONS), + new LambdaEvaluatorSystem(SourceCode.Syntax.ARROW)); + + world.createEntity().add(new GridPosition(Vec2i.builder().x(1).y(1).build())).add(new LambdaTerm(IDENTITY)) + .add(new Substitution(spawnMomentum, Map.of("y", Vec2i.builder().x(0).y(0).build()))); + world.createEntity().add(new GridPosition(Vec2i.builder().x(0).y(0).build())).add(new LambdaTerm(FREE)); + + world.update(GridInputState.builder().build(), Duration.ZERO); + + final Set<Entity> emittedTerms = world.resolve(Query.allOf(GridMomentum.class, LambdaTerm.class)); + assertEquals(1, emittedTerms.size()); + final GridMomentum momentum = emittedTerms.iterator().next().get(GridMomentum.class); + assertEquals(new GridMomentum(spawnMomentum), momentum); + } +} |
