From 4896f5d3509fee16a398c0b245843b0b6beb040e Mon Sep 17 00:00:00 2001 From: Fernando Dodino Date: Sun, 15 Sep 2019 23:37:20 -0300 Subject: [PATCH 001/133] Fix #1794 - add elements processing --- .../formatter/TestingFormatterTestCase.xtend | 18 ++++++++++++++++++ .../META-INF/MANIFEST.MF | 1 + .../formatting2/WollokDslFormatter.xtend | 9 ++++++++- 3 files changed, 27 insertions(+), 1 deletion(-) diff --git a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/formatter/TestingFormatterTestCase.xtend b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/formatter/TestingFormatterTestCase.xtend index a7d0ef1efc..da1e0bb7ba 100644 --- a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/formatter/TestingFormatterTestCase.xtend +++ b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/formatter/TestingFormatterTestCase.xtend @@ -16,6 +16,24 @@ import org.uqbar.project.wollok.tests.injectors.WollokTestInjectorProvider class TestingFormatterTestCase extends AbstractWollokFormatterTestCase { // TEST METHODS + @Test + def void testConstantsFormatting() throws Exception { + assertFormatting( + '''const a = new Sobreviviente() + + + const b = new Sobreviviente() + test "aSimpleTest"{ assert.that(true) }''', ''' + const a = new Sobreviviente() + const b = new Sobreviviente() + + test "aSimpleTest" { + assert.that(true) + } + ''') + } + + @Test def void testSimpleTestFormatting() throws Exception { assertFormatting( diff --git a/org.uqbar.project.wollok.typeSystem/META-INF/MANIFEST.MF b/org.uqbar.project.wollok.typeSystem/META-INF/MANIFEST.MF index bf00294236..e7b3a9039c 100644 --- a/org.uqbar.project.wollok.typeSystem/META-INF/MANIFEST.MF +++ b/org.uqbar.project.wollok.typeSystem/META-INF/MANIFEST.MF @@ -9,6 +9,7 @@ Require-Bundle: org.uqbar.project.wollok, org.eclipse.xtext.ui;bundle-version="2.11.0" Export-Package: org.uqbar.project.wollok.typesystem, org.uqbar.project.wollok.typesystem.constraints, + org.uqbar.project.wollok.typesystem.constraints.variables, org.uqbar.project.wollok.typesystem.preferences Bundle-Activator: org.uqbar.project.wollok.typesystem.WollokTypeSystemActivator Bundle-ActivationPolicy: lazy diff --git a/org.uqbar.project.wollok/src/org/uqbar/project/wollok/formatting2/WollokDslFormatter.xtend b/org.uqbar.project.wollok/src/org/uqbar/project/wollok/formatting2/WollokDslFormatter.xtend index dad302ae86..bcbf8fb6ff 100644 --- a/org.uqbar.project.wollok/src/org/uqbar/project/wollok/formatting2/WollokDslFormatter.xtend +++ b/org.uqbar.project.wollok/src/org/uqbar/project/wollok/formatting2/WollokDslFormatter.xtend @@ -63,7 +63,14 @@ class WollokDslFormatter extends AbstractFormatter2 { ^import.append [ newLine ] } ] - elements.forEach [ format ] + elements.forEach [ element, i | + element.format + if (elements.size - 1 == i) { + element.append [ setNewLines(2) ] + } else { + element.append [ newLine ] + } + ] main.format tests.formatTests(document) suite.format From 2b4dbf35462dddd8f399216c3ac9dfb329165a48 Mon Sep 17 00:00:00 2001 From: ivan Date: Thu, 19 Sep 2019 16:29:33 -0300 Subject: [PATCH 002/133] Added cellSize in game --- .../project/wollok/game/gameboard/Gameboard.xtend | 2 +- org.uqbar.project.wollok.lib/src/wollok/game.wlk | 14 ++++++++++++++ .../src/wollok/game/GameObject.xtend | 2 ++ 3 files changed, 17 insertions(+), 1 deletion(-) diff --git a/org.uqbar.project.wollok.game/src/org/uqbar/project/wollok/game/gameboard/Gameboard.xtend b/org.uqbar.project.wollok.game/src/org/uqbar/project/wollok/game/gameboard/Gameboard.xtend index 7fbcaee662..a3bcdd9910 100644 --- a/org.uqbar.project.wollok.game/src/org/uqbar/project/wollok/game/gameboard/Gameboard.xtend +++ b/org.uqbar.project.wollok.game/src/org/uqbar/project/wollok/game/gameboard/Gameboard.xtend @@ -23,7 +23,7 @@ import static org.uqbar.project.wollok.sdk.WollokSDK.* @Accessors class Gameboard { public static Gameboard instance - public static final int CELLZISE = 50 + public static int CELLZISE = 50 val Logger log = Logger.getLogger(this.class) diff --git a/org.uqbar.project.wollok.lib/src/wollok/game.wlk b/org.uqbar.project.wollok.lib/src/wollok/game.wlk index 613d910f59..40a345f22c 100644 --- a/org.uqbar.project.wollok.lib/src/wollok/game.wlk +++ b/org.uqbar.project.wollok.lib/src/wollok/game.wlk @@ -217,6 +217,20 @@ object game { */ method ground(image) native + /** + * Sets cells size. + */ + method cellSize(size){ + if(size<=0) + throw new Exception(message = "Cell size can't be 0 or lower") + self.doCellSize(size) + } + + /** + * @private + */ + method doCellSize(size) native + /** * Sets full background image. */ diff --git a/org.uqbar.project.wollok.lib/src/wollok/game/GameObject.xtend b/org.uqbar.project.wollok.lib/src/wollok/game/GameObject.xtend index eef1e25750..cbab02936f 100644 --- a/org.uqbar.project.wollok.lib/src/wollok/game/GameObject.xtend +++ b/org.uqbar.project.wollok.lib/src/wollok/game/GameObject.xtend @@ -207,4 +207,6 @@ class GameObject { def ground(String image) { board.ground = image } def boardGround(String image) { board.boardGround = image } + def doCellSize(WollokObject size) {Gameboard.CELLZISE=size.coerceToInteger } + } From 91f9942cccaddb21a7bd83e11f75038ba824d8ee Mon Sep 17 00:00:00 2001 From: ivan Date: Thu, 19 Sep 2019 16:53:24 -0300 Subject: [PATCH 003/133] cellSize tests --- .../project/wollok/tests/sdk/GameTest.xtend | 205 ++++++++++-------- 1 file changed, 114 insertions(+), 91 deletions(-) diff --git a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/sdk/GameTest.xtend b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/sdk/GameTest.xtend index bec46b7e0b..55da59710c 100644 --- a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/sdk/GameTest.xtend +++ b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/sdk/GameTest.xtend @@ -6,204 +6,227 @@ import org.uqbar.project.wollok.game.gameboard.Gameboard import org.uqbar.project.wollok.tests.interpreter.AbstractWollokInterpreterTestCase class GameTest extends AbstractWollokInterpreterTestCase { - + var gameboard = Gameboard.getInstance - + @Before def void init() { gameboard.clear } - + @Test def void canInstanceNewPosition() { ''' - assert.equals(«position(1,2)», game.at(1,2)) + assert.equals(«position(1,2)», game.at(1,2)) '''.test } - + @Test def void originShouldReturnOriginCoordinatePosition() { ''' - assert.equals(«position(0,0)», game.origin()) + assert.equals(«position(0,0)», game.origin()) '''.test } - + @Test def void centerShouldReturnCenteredCoordinatePosition() { ''' - game.width(2) - game.height(5) - assert.equals(«position(1,2)», game.center()) + game.width(2) + game.height(5) + assert.equals(«position(1,2)», game.center()) '''.test } - + @Test def void shouldReturnVisualColliders() { ''' - «position(0,0)».drawElement(myVisual) - 2.times{ i => «position(0,0)».drawElement(new Visual()) } - «position(0,1)».drawElement(new Visual()) - - assert.equals(2, game.colliders(myVisual).size()) + «position(0,0)».drawElement(myVisual) + 2.times{ i => «position(0,0)».drawElement(new Visual()) } + «position(0,1)».drawElement(new Visual()) + + assert.equals(2, game.colliders(myVisual).size()) '''.gameTest } - + @Test def void shouldReturnUniqueCollider() { ''' - «position(0,0)».drawElement(myVisual) - const otherVisual = new Visual() - «position(0,0)».drawElement(otherVisual) - - assert.equals(otherVisual, game.uniqueCollider(myVisual)) + «position(0,0)».drawElement(myVisual) + const otherVisual = new Visual() + «position(0,0)».drawElement(otherVisual) + + assert.equals(otherVisual, game.uniqueCollider(myVisual)) '''.gameTest } - + @Test def void movingCharacterShouldSetObjectPosition() { ''' - game.addVisualCharacter(pepita) + game.addVisualCharacter(pepita) '''.gameTest gameboard.components.head.up ''' - assert.equals(1, game.at(0,1).allElements().size()) + assert.equals(1, game.at(0,1).allElements().size()) '''.test } - + @Test def void addSameObjectToGameShouldFail() { ''' - «position(0,0)».drawElement(myVisual) - assert.throwsExceptionWithMessage("myVisual[] is already in the game.", { «position(1,1)».drawElement(myVisual) }) + «position(0,0)».drawElement(myVisual) + assert.throwsExceptionWithMessage("myVisual[] is already in the game.", { «position(1,1)».drawElement(myVisual) }) '''.gameTest } - + @Test def void addVisualUsingNullMustFail() { ''' - assert.throwsExceptionWithMessage("Operation addVisual doesn't support null parameters", { => game.addVisual(null) }) + assert.throwsExceptionWithMessage("Operation addVisual doesn't support null parameters", { => game.addVisual(null) }) '''.test } @Test def void addVisualInUsingNullMustFail() { ''' - assert.throwsExceptionWithMessage("Operation addVisualIn doesn't support null parameters", { => game.addVisualIn(null, null) }) + assert.throwsExceptionWithMessage("Operation addVisualIn doesn't support null parameters", { => game.addVisualIn(null, null) }) '''.test } @Test def void collidersUsingNullMustFail() { ''' - assert.throwsExceptionWithMessage("Operation colliders doesn't support null parameters", { => game.colliders(null) }) + assert.throwsExceptionWithMessage("Operation colliders doesn't support null parameters", { => game.colliders(null) }) '''.test } @Test def void onTickUsingNullMustFail() { ''' - assert.throwsExceptionWithMessage("Operation onTick doesn't support null parameters", { => game.onTick(null, null, null) }) + assert.throwsExceptionWithMessage("Operation onTick doesn't support null parameters", { => game.onTick(null, null, null) }) '''.test } @Test def void whenKeyPressedDoUsingNullMustFail() { ''' - assert.throwsExceptionWithMessage("Operation whenKeyPressedDo doesn't support null parameters", { => game.whenKeyPressedDo(null, null) }) + assert.throwsExceptionWithMessage("Operation whenKeyPressedDo doesn't support null parameters", { => game.whenKeyPressedDo(null, null) }) '''.test } @Test def void whenAddingAnObjectAndCheckingIfItIsInTheBoardItReturnsTrue() { ''' - import wollok.game.* - - object myVisual { } - - program a { - game.addVisualIn(myVisual, game.at(0, 0)) - assert.that(game.hasVisual(myVisual)) - } + import wollok.game.* + + object myVisual { } + + program a { + game.addVisualIn(myVisual, game.at(0, 0)) + assert.that(game.hasVisual(myVisual)) + } '''.interpretPropagatingErrors } @Test def void whenAddingAnObjectAndCheckingIfOtherIsInTheBoardItReturnsFalse() { ''' - import wollok.game.* - - object myVisual { } - object myVisual2 { } - - program a { - game.addVisualIn(myVisual, game.at(0, 0)) - assert.notThat(game.hasVisual(myVisual2)) - } + import wollok.game.* + + object myVisual { } + object myVisual2 { } + + program a { + game.addVisualIn(myVisual, game.at(0, 0)) + assert.notThat(game.hasVisual(myVisual2)) + } '''.interpretPropagatingErrors } @Test def void whenNoObjectIsAddedAndGetAllVisualsItReturnsNoElement() { ''' - import wollok.game.* - - program a { - assert.equals(0, game.allVisuals().size()) - } + import wollok.game.* + + program a { + assert.equals(0, game.allVisuals().size()) + } '''.interpretPropagatingErrors } @Test def void whenAddingAnObjectAndGettingAllVisualsItReturnsOneElement() { ''' - import wollok.game.* - - object myVisual { } - - program a { - game.addVisualIn(myVisual, game.at(0, 0)) - assert.equals(1, game.allVisuals().size()) - assert.equals(myVisual, game.allVisuals().get(0)) - } + import wollok.game.* + + object myVisual { } + + program a { + game.addVisualIn(myVisual, game.at(0, 0)) + assert.equals(1, game.allVisuals().size()) + assert.equals(myVisual, game.allVisuals().get(0)) + } '''.interpretPropagatingErrors } @Test def void whenAddingSomeObjectAndGettingAllVisualsItReturnsAllTheAddedElements() { ''' - import wollok.game.* - - object myVisual { } - object myVisual2 { } - object myVisual3 { } - - program a { - game.addVisualIn(myVisual, game.at(0, 0)) - game.addVisualIn(myVisual2, game.at(0, 0)) - game.addVisualIn(myVisual3, game.at(0, 0)) - assert.equals(3, game.allVisuals().size()) - assert.equals([myVisual, myVisual2, myVisual3].asSet(), game.allVisuals().asSet()) - } + import wollok.game.* + + object myVisual { } + object myVisual2 { } + object myVisual3 { } + + program a { + game.addVisualIn(myVisual, game.at(0, 0)) + game.addVisualIn(myVisual2, game.at(0, 0)) + game.addVisualIn(myVisual3, game.at(0, 0)) + assert.equals(3, game.allVisuals().size()) + assert.equals([myVisual, myVisual2, myVisual3].asSet(), game.allVisuals().asSet()) + } '''.interpretPropagatingErrors } + + @Test + def void cellSize_works_correctly() { + ''' + game.cellSize(10) + '''.gameTest + assertEquals(10, Gameboard.CELLZISE) + } + @Test + def void cellSize_throws_exception_limit(){ + ''' + assert.throwsExceptionWithMessage("Cell size can't be 0 or lower", {=>game.cellSize(0)}) + + '''.gameTest + } + + @Test + def void cellSize_throws_exception(){ + ''' + assert.throwsExceptionWithMessage("Cell size can't be 0 or lower", {=>game.cellSize(-10)}) + '''.gameTest + } + def gameTest(CharSequence test) { ''' - import wollok.game.* - - object myVisual { } - class Visual { } - - object pepita { - var property position = game.origin() - } - - program a { - «test» - } + import wollok.game.* + + object myVisual { } + class Visual { } + + object pepita { + var property position = game.origin() + } + + program a { + «test» + } '''.interpretPropagatingErrors } - + private def position(int x, int y) { '''new Position(x = «x», y = «y»)''' } From e1aa658ec855a2d75bd0d6d548ee592eb71aff2f Mon Sep 17 00:00:00 2001 From: ivan Date: Thu, 19 Sep 2019 18:23:03 -0300 Subject: [PATCH 004/133] CELLSIZE is no loger static --- .../src/org/uqbar/project/wollok/game/Position.xtend | 4 ++-- .../uqbar/project/wollok/game/VisualComponent.xtend | 4 ++-- .../org/uqbar/project/wollok/game/gameboard/Cell.xtend | 2 +- .../project/wollok/game/gameboard/Gameboard.xtend | 10 +++++++--- .../game/gameboard/GameboardInputProcessor.xtend | 2 +- .../src/wollok/game/GameObject.xtend | 2 +- .../org/uqbar/project/wollok/tests/sdk/GameTest.xtend | 8 +++++++- .../tests/typesystem/CoreInferenceTestCase.xtend | 5 ----- 8 files changed, 21 insertions(+), 16 deletions(-) diff --git a/org.uqbar.project.wollok.game/src/org/uqbar/project/wollok/game/Position.xtend b/org.uqbar.project.wollok.game/src/org/uqbar/project/wollok/game/Position.xtend index f63c286970..20555da5fd 100644 --- a/org.uqbar.project.wollok.game/src/org/uqbar/project/wollok/game/Position.xtend +++ b/org.uqbar.project.wollok.game/src/org/uqbar/project/wollok/game/Position.xtend @@ -49,9 +49,9 @@ abstract class Position { def abstract int getX() def abstract int getY() - def getXinPixels() { x * Gameboard.CELLZISE } + def getXinPixels() { x * Gameboard.instance.CELLZISE } - def getYinPixels() { y * Gameboard.CELLZISE } + def getYinPixels() { y * Gameboard.instance.CELLZISE } override public int hashCode() { val prime = 31 diff --git a/org.uqbar.project.wollok.game/src/org/uqbar/project/wollok/game/VisualComponent.xtend b/org.uqbar.project.wollok.game/src/org/uqbar/project/wollok/game/VisualComponent.xtend index 56e9624290..27afcd3bb0 100644 --- a/org.uqbar.project.wollok.game/src/org/uqbar/project/wollok/game/VisualComponent.xtend +++ b/org.uqbar.project.wollok.game/src/org/uqbar/project/wollok/game/VisualComponent.xtend @@ -105,8 +105,8 @@ class VisualComponent { val yMouse = Gdx.input.y val bottomX = position.xinPixels val bottomY = Gameboard.getInstance().pixelHeight - position.yinPixels - val topX = bottomX + Gameboard.CELLZISE - val topY = bottomY - Gameboard.CELLZISE + val topX = bottomX + Gameboard.instance.CELLZISE + val topY = bottomY - Gameboard.instance.CELLZISE return (xMouse > bottomX && xMouse < topX) && (yMouse < bottomY && yMouse > topY) } diff --git a/org.uqbar.project.wollok.game/src/org/uqbar/project/wollok/game/gameboard/Cell.xtend b/org.uqbar.project.wollok.game/src/org/uqbar/project/wollok/game/gameboard/Cell.xtend index 8080dfa2ee..98ff7360df 100644 --- a/org.uqbar.project.wollok.game/src/org/uqbar/project/wollok/game/gameboard/Cell.xtend +++ b/org.uqbar.project.wollok.game/src/org/uqbar/project/wollok/game/gameboard/Cell.xtend @@ -12,7 +12,7 @@ class Cell { new(Position position, Image image) { this.position = position - this.image = image => [ size = new CellSize(Gameboard.CELLZISE) ] + this.image = image => [ size = new CellSize(Gameboard.instance.CELLZISE) ] } def draw(Window window) { diff --git a/org.uqbar.project.wollok.game/src/org/uqbar/project/wollok/game/gameboard/Gameboard.xtend b/org.uqbar.project.wollok.game/src/org/uqbar/project/wollok/game/gameboard/Gameboard.xtend index a3bcdd9910..aaec82d201 100644 --- a/org.uqbar.project.wollok.game/src/org/uqbar/project/wollok/game/gameboard/Gameboard.xtend +++ b/org.uqbar.project.wollok.game/src/org/uqbar/project/wollok/game/gameboard/Gameboard.xtend @@ -22,8 +22,8 @@ import static org.uqbar.project.wollok.sdk.WollokSDK.* @Accessors class Gameboard { - public static Gameboard instance - public static int CELLZISE = 50 + static Gameboard instance + public int CELLZISE = 50 val Logger log = Logger.getLogger(this.class) @@ -41,10 +41,14 @@ class Gameboard { def static getInstance() { if (instance === null) { - instance = new Gameboard() + resetInstance } instance } + + def static resetInstance() { + instance = new Gameboard() + } new() { title = "Wollok Game" diff --git a/org.uqbar.project.wollok.game/src/org/uqbar/project/wollok/game/gameboard/GameboardInputProcessor.xtend b/org.uqbar.project.wollok.game/src/org/uqbar/project/wollok/game/gameboard/GameboardInputProcessor.xtend index 74aa6c8eb5..4f7dafe3ca 100644 --- a/org.uqbar.project.wollok.game/src/org/uqbar/project/wollok/game/gameboard/GameboardInputProcessor.xtend +++ b/org.uqbar.project.wollok.game/src/org/uqbar/project/wollok/game/gameboard/GameboardInputProcessor.xtend @@ -26,7 +26,7 @@ class GameboardInputProcessor implements InputProcessor { override boolean touchDown(int x, int y, int pointer, int button) { val inverseY = Gameboard.getInstance().pixelHeight() - y - val position = new WGPosition(x / Gameboard.CELLZISE, inverseY / Gameboard.CELLZISE ) + val position = new WGPosition(x / Gameboard.instance.CELLZISE, inverseY / Gameboard.instance.CELLZISE ) val Iterable lista = Gameboard.getInstance.getComponentsInPosition(position) diff --git a/org.uqbar.project.wollok.lib/src/wollok/game/GameObject.xtend b/org.uqbar.project.wollok.lib/src/wollok/game/GameObject.xtend index cbab02936f..8a7ea39506 100644 --- a/org.uqbar.project.wollok.lib/src/wollok/game/GameObject.xtend +++ b/org.uqbar.project.wollok.lib/src/wollok/game/GameObject.xtend @@ -207,6 +207,6 @@ class GameObject { def ground(String image) { board.ground = image } def boardGround(String image) { board.boardGround = image } - def doCellSize(WollokObject size) {Gameboard.CELLZISE=size.coerceToInteger } + def doCellSize(WollokObject size) { board.CELLZISE = size.coerceToInteger } } diff --git a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/sdk/GameTest.xtend b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/sdk/GameTest.xtend index 55da59710c..106adea92b 100644 --- a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/sdk/GameTest.xtend +++ b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/sdk/GameTest.xtend @@ -4,6 +4,7 @@ import org.junit.Before import org.junit.Test import org.uqbar.project.wollok.game.gameboard.Gameboard import org.uqbar.project.wollok.tests.interpreter.AbstractWollokInterpreterTestCase +import org.junit.After class GameTest extends AbstractWollokInterpreterTestCase { @@ -13,6 +14,11 @@ class GameTest extends AbstractWollokInterpreterTestCase { def void init() { gameboard.clear } + + @After + def void finish() { + Gameboard.resetInstance + } @Test def void canInstanceNewPosition() { @@ -192,7 +198,7 @@ class GameTest extends AbstractWollokInterpreterTestCase { ''' game.cellSize(10) '''.gameTest - assertEquals(10, Gameboard.CELLZISE) + assertEquals(10, gameboard.CELLZISE) } @Test diff --git a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/typesystem/CoreInferenceTestCase.xtend b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/typesystem/CoreInferenceTestCase.xtend index 6665733655..3da5fbadf9 100644 --- a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/typesystem/CoreInferenceTestCase.xtend +++ b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/typesystem/CoreInferenceTestCase.xtend @@ -12,11 +12,6 @@ import static org.uqbar.project.wollok.sdk.WollokSDK.* import static extension org.uqbar.project.wollok.model.WMethodContainerExtensions.* import static extension org.uqbar.project.wollok.model.WollokModelExtensions.* -/** - * Test cases for type inference related to the console object. - * - * @author npasserini - */ class CoreInferenceTestCase extends AbstractWollokTypeSystemTestCase { @Parameters(name="{index}: {0}") From 76b8f3e0519b64e47d75746bdf238257f0490091 Mon Sep 17 00:00:00 2001 From: ivan Date: Thu, 19 Sep 2019 18:30:25 -0300 Subject: [PATCH 005/133] fix typo CELLZISE --- .../src/org/uqbar/project/wollok/game/Position.xtend | 4 ++-- .../src/org/uqbar/project/wollok/game/VisualComponent.xtend | 4 ++-- .../src/org/uqbar/project/wollok/game/gameboard/Cell.xtend | 2 +- .../org/uqbar/project/wollok/game/gameboard/Gameboard.xtend | 6 +++--- .../wollok/game/gameboard/GameboardInputProcessor.xtend | 2 +- .../src/wollok/game/GameObject.xtend | 2 +- .../src/org/uqbar/project/wollok/tests/sdk/GameTest.xtend | 2 +- 7 files changed, 11 insertions(+), 11 deletions(-) diff --git a/org.uqbar.project.wollok.game/src/org/uqbar/project/wollok/game/Position.xtend b/org.uqbar.project.wollok.game/src/org/uqbar/project/wollok/game/Position.xtend index 20555da5fd..c291f553c0 100644 --- a/org.uqbar.project.wollok.game/src/org/uqbar/project/wollok/game/Position.xtend +++ b/org.uqbar.project.wollok.game/src/org/uqbar/project/wollok/game/Position.xtend @@ -49,9 +49,9 @@ abstract class Position { def abstract int getX() def abstract int getY() - def getXinPixels() { x * Gameboard.instance.CELLZISE } + def getXinPixels() { x * Gameboard.instance.cellsize } - def getYinPixels() { y * Gameboard.instance.CELLZISE } + def getYinPixels() { y * Gameboard.instance.cellsize } override public int hashCode() { val prime = 31 diff --git a/org.uqbar.project.wollok.game/src/org/uqbar/project/wollok/game/VisualComponent.xtend b/org.uqbar.project.wollok.game/src/org/uqbar/project/wollok/game/VisualComponent.xtend index 27afcd3bb0..1604f1a620 100644 --- a/org.uqbar.project.wollok.game/src/org/uqbar/project/wollok/game/VisualComponent.xtend +++ b/org.uqbar.project.wollok.game/src/org/uqbar/project/wollok/game/VisualComponent.xtend @@ -105,8 +105,8 @@ class VisualComponent { val yMouse = Gdx.input.y val bottomX = position.xinPixels val bottomY = Gameboard.getInstance().pixelHeight - position.yinPixels - val topX = bottomX + Gameboard.instance.CELLZISE - val topY = bottomY - Gameboard.instance.CELLZISE + val topX = bottomX + Gameboard.instance.cellsize + val topY = bottomY - Gameboard.instance.cellsize return (xMouse > bottomX && xMouse < topX) && (yMouse < bottomY && yMouse > topY) } diff --git a/org.uqbar.project.wollok.game/src/org/uqbar/project/wollok/game/gameboard/Cell.xtend b/org.uqbar.project.wollok.game/src/org/uqbar/project/wollok/game/gameboard/Cell.xtend index 98ff7360df..d05774a85e 100644 --- a/org.uqbar.project.wollok.game/src/org/uqbar/project/wollok/game/gameboard/Cell.xtend +++ b/org.uqbar.project.wollok.game/src/org/uqbar/project/wollok/game/gameboard/Cell.xtend @@ -12,7 +12,7 @@ class Cell { new(Position position, Image image) { this.position = position - this.image = image => [ size = new CellSize(Gameboard.instance.CELLZISE) ] + this.image = image => [ size = new CellSize(Gameboard.instance.cellsize) ] } def draw(Window window) { diff --git a/org.uqbar.project.wollok.game/src/org/uqbar/project/wollok/game/gameboard/Gameboard.xtend b/org.uqbar.project.wollok.game/src/org/uqbar/project/wollok/game/gameboard/Gameboard.xtend index aaec82d201..27681fe51b 100644 --- a/org.uqbar.project.wollok.game/src/org/uqbar/project/wollok/game/gameboard/Gameboard.xtend +++ b/org.uqbar.project.wollok.game/src/org/uqbar/project/wollok/game/gameboard/Gameboard.xtend @@ -23,7 +23,6 @@ import static org.uqbar.project.wollok.sdk.WollokSDK.* @Accessors class Gameboard { static Gameboard instance - public int CELLZISE = 50 val Logger log = Logger.getLogger(this.class) @@ -32,6 +31,7 @@ class Gameboard { String boardGround int height int width + @Accessors int cellsize = 50 Background background List components = newArrayList List listeners = newArrayList @@ -106,9 +106,9 @@ class Gameboard { null } - def pixelHeight() { height * CELLZISE } + def pixelHeight() { height * cellsize } - def pixelWidth() { width * CELLZISE } + def pixelWidth() { width * cellsize } def clear() { components.clear() diff --git a/org.uqbar.project.wollok.game/src/org/uqbar/project/wollok/game/gameboard/GameboardInputProcessor.xtend b/org.uqbar.project.wollok.game/src/org/uqbar/project/wollok/game/gameboard/GameboardInputProcessor.xtend index 4f7dafe3ca..2f261d0661 100644 --- a/org.uqbar.project.wollok.game/src/org/uqbar/project/wollok/game/gameboard/GameboardInputProcessor.xtend +++ b/org.uqbar.project.wollok.game/src/org/uqbar/project/wollok/game/gameboard/GameboardInputProcessor.xtend @@ -26,7 +26,7 @@ class GameboardInputProcessor implements InputProcessor { override boolean touchDown(int x, int y, int pointer, int button) { val inverseY = Gameboard.getInstance().pixelHeight() - y - val position = new WGPosition(x / Gameboard.instance.CELLZISE, inverseY / Gameboard.instance.CELLZISE ) + val position = new WGPosition(x / Gameboard.instance.cellsize, inverseY / Gameboard.instance.cellsize ) val Iterable lista = Gameboard.getInstance.getComponentsInPosition(position) diff --git a/org.uqbar.project.wollok.lib/src/wollok/game/GameObject.xtend b/org.uqbar.project.wollok.lib/src/wollok/game/GameObject.xtend index 8a7ea39506..48ad9c482c 100644 --- a/org.uqbar.project.wollok.lib/src/wollok/game/GameObject.xtend +++ b/org.uqbar.project.wollok.lib/src/wollok/game/GameObject.xtend @@ -207,6 +207,6 @@ class GameObject { def ground(String image) { board.ground = image } def boardGround(String image) { board.boardGround = image } - def doCellSize(WollokObject size) { board.CELLZISE = size.coerceToInteger } + def doCellSize(WollokObject size) { board.cellsize = size.coerceToInteger } } diff --git a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/sdk/GameTest.xtend b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/sdk/GameTest.xtend index 106adea92b..b8282fb197 100644 --- a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/sdk/GameTest.xtend +++ b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/sdk/GameTest.xtend @@ -198,7 +198,7 @@ class GameTest extends AbstractWollokInterpreterTestCase { ''' game.cellSize(10) '''.gameTest - assertEquals(10, gameboard.CELLZISE) + assertEquals(10, gameboard.cellsize) } @Test From 7eb86449ee7c8f5fea30dfea3301b8ad135263e9 Mon Sep 17 00:00:00 2001 From: ivan Date: Thu, 19 Sep 2019 18:41:56 -0300 Subject: [PATCH 006/133] cellSize type declaration --- .../typesystem/annotations/WollokGameTypeDeclarations.xtend | 2 ++ 1 file changed, 2 insertions(+) diff --git a/org.uqbar.project.wollok.typeSystem/src/org/uqbar/project/wollok/typesystem/annotations/WollokGameTypeDeclarations.xtend b/org.uqbar.project.wollok.typeSystem/src/org/uqbar/project/wollok/typesystem/annotations/WollokGameTypeDeclarations.xtend index 3a3dbb2e77..21ab175c6a 100644 --- a/org.uqbar.project.wollok.typeSystem/src/org/uqbar/project/wollok/typesystem/annotations/WollokGameTypeDeclarations.xtend +++ b/org.uqbar.project.wollok.typeSystem/src/org/uqbar/project/wollok/typesystem/annotations/WollokGameTypeDeclarations.xtend @@ -52,6 +52,8 @@ class WollokGameTypeDeclarations extends TypeDeclarations { game >> "center" === #[] => Position game >> "ground" === #[String] => Void game >> "boardGround" === #[String] => Void + game >> "cellSize" === #[Number] => Void + game >> "doCellSize" === #[Number] => Void game >> "hideAttributes" === #[T] => Void game >> "showAttributes" === #[T] => Void game >> "errorReporter" === #[T] => Void From b6eec8be7f21cd9ea58d9ceb39a107aad069c727 Mon Sep 17 00:00:00 2001 From: Fernando Dodino Date: Tue, 1 Oct 2019 23:52:31 -0300 Subject: [PATCH 007/133] Number - changes in odd, even and div definition --- org.uqbar.project.wollok.lib/src/wollok/lang.wlk | 16 ++++++++-------- .../tests/interpreter/NumberTestCase.xtend | 2 +- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/org.uqbar.project.wollok.lib/src/wollok/lang.wlk b/org.uqbar.project.wollok.lib/src/wollok/lang.wlk index 03157f3655..6978b6edea 100644 --- a/org.uqbar.project.wollok.lib/src/wollok/lang.wlk +++ b/org.uqbar.project.wollok.lib/src/wollok/lang.wlk @@ -1684,7 +1684,10 @@ class Number { * 15.div(5) ==> Answers 3 * 8.2.div(3.3) ==> Answers 2 */ - method div(other) native + method div(other) { + self.checkNotNull(other, "div") + return (self / other).truncate(0) + } /** * raisedTo operation @@ -1816,10 +1819,7 @@ class Number { * * Self must be an integer value */ - method even() { - const intValue = self.coerceToInteger() - return intValue % 2 == 0 - } + method even() = self % 2 == 0 /** * Answers whether self is an odd number @@ -1827,9 +1827,9 @@ class Number { * * Self must be an integer value */ - method odd() { - const intValue = self.coerceToInteger() - return intValue.even().negate() + method odd() { + if (!self.isInteger()) return false + return !self.even() } /** Answers remainder between self and other diff --git a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/NumberTestCase.xtend b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/NumberTestCase.xtend index 61eacfdc39..f9432d10c6 100644 --- a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/NumberTestCase.xtend +++ b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/NumberTestCase.xtend @@ -556,7 +556,7 @@ class NumberTestCase extends AbstractWollokInterpreterTestCase { @Test def void integerDivisionFail() { ''' - assert.throwsExceptionWithMessage("Cannot convert parameter \"a\" to type wollok.lang.Number", { 8.div("a") }) + assert.throwsExceptionWithMessage("Operation doesn't support parameter a", { 8.div("a") }) '''.test } From 42b11be2690fe909567ad2d9a4c9b3317e21f859 Mon Sep 17 00:00:00 2001 From: Fernando Dodino Date: Tue, 1 Oct 2019 23:57:45 -0300 Subject: [PATCH 008/133] Deleting div native method in Number --- org.uqbar.project.wollok.lib/src/wollok/lang/WNumber.xtend | 5 ----- 1 file changed, 5 deletions(-) diff --git a/org.uqbar.project.wollok.lib/src/wollok/lang/WNumber.xtend b/org.uqbar.project.wollok.lib/src/wollok/lang/WNumber.xtend index 6fd8a6cf02..b4c60a0efb 100644 --- a/org.uqbar.project.wollok.lib/src/wollok/lang/WNumber.xtend +++ b/org.uqbar.project.wollok.lib/src/wollok/lang/WNumber.xtend @@ -32,11 +32,6 @@ class WNumber extends AbstractJavaWrapper { * BASIC MATHEMATICAL OPERATIONS * ********************************************************** */ - def div(BigDecimal other) { - other.checkNotNull("div") - wrapped.divide(other, RoundingMode.HALF_UP).intValue - } - @NativeMessage("+") def plus(WollokObject other) { other.checkNotNull("+") From 784a4e27f7c6411cbd9d249c9b1392469fd5f527 Mon Sep 17 00:00:00 2001 From: Fernando Dodino Date: Wed, 2 Oct 2019 00:19:02 -0300 Subject: [PATCH 009/133] String methods: charAt + concat --- .../src/wollok/lang.wlk | 17 ++++++++++++++--- .../src/wollok/lang/WString.xtend | 11 +++-------- .../tests/interpreter/StringTestCase.xtend | 16 +++++++++++++++- 3 files changed, 32 insertions(+), 12 deletions(-) diff --git a/org.uqbar.project.wollok.lib/src/wollok/lang.wlk b/org.uqbar.project.wollok.lib/src/wollok/lang.wlk index 6978b6edea..027f8b63dc 100644 --- a/org.uqbar.project.wollok.lib/src/wollok/lang.wlk +++ b/org.uqbar.project.wollok.lib/src/wollok/lang.wlk @@ -1993,15 +1993,26 @@ class String { * at index 0, the next at index 1, and so on, as for array indexing. * Parameter index must be a positive integer value. */ - method charAt(index) native + method charAt(index) { + self.checkNotNull(index, "charAt") + if (!index.isInteger()) throw new DomainException(message = "charAt expects an integer instead of " + index) + return self.substring(index, index + 1) + } /** * Concatenates the specified string to the end of this string. * Example: * "cares" + "s" => Answers "caress" */ - method +(other) native - + method +(other) = self.concat(other.toString()) + + /** + * Concatenates the specified string to the end of this string. Same as +. + * Example: + * "cares".concat("s") => Answers "caress" + */ + method concat(other) native + /** * Tests if this string starts with the specified prefix. * It is case sensitive. diff --git a/org.uqbar.project.wollok.lib/src/wollok/lang/WString.xtend b/org.uqbar.project.wollok.lib/src/wollok/lang/WString.xtend index d99aec27a9..a628e48d57 100644 --- a/org.uqbar.project.wollok.lib/src/wollok/lang/WString.xtend +++ b/org.uqbar.project.wollok.lib/src/wollok/lang/WString.xtend @@ -23,15 +23,10 @@ class WString extends AbstractJavaWrapper { def length() { wrapped.length } - def charAt(BigDecimal index) { - index.checkNotNull("charAt") - wrapped.charAt(index.coerceToPositiveInteger).toString - } - - @NativeMessage("+") def concat(Object other) { doConcatWith(other) } - def dispatch WollokObject doConcatWith(WString o) { newInstanceWithWrapped(this.wrapped + o.wrapped) } - def dispatch WollokObject doConcatWith(WollokObject it) { convertToWString.asWString.doConcatWith } + + def dispatch WollokObject doConcatWith(WString o) { newInstanceWithWrapped(this.wrapped + o.wrapped) } + def dispatch WollokObject doConcatWith(WollokObject it) { convertToWString.asWString.doConcatWith } def startsWith(String other) { other.checkNotNull("startsWith") diff --git a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/StringTestCase.xtend b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/StringTestCase.xtend index 106a30f695..acb8d24632 100644 --- a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/StringTestCase.xtend +++ b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/StringTestCase.xtend @@ -224,7 +224,7 @@ class StringTestCase extends AbstractWollokInterpreterTestCase { @Test def void charAtFail() { ''' - assert.throwsExceptionWithMessage("Cannot convert parameter \"a\" to type wollok.lang.Number", { "hola".charAt("a") }) + assert.throwsExceptionWithMessage("a does not understand isInteger()", { "hola".charAt("a") }) '''.test } @@ -235,6 +235,20 @@ class StringTestCase extends AbstractWollokInterpreterTestCase { '''.test } + @Test + def void concatHappyPath() { + ''' + assert.equals("hey".concat("jude"), "heyjude") + '''.test + } + + @Test + def void concatWithNumbers() { + ''' + assert.equals("u".concat(2), "u2") + '''.test + } + @Test def void reverse() { ''' From 27f10ff3fc9b08086d09a1eb20d4683427f93b82 Mon Sep 17 00:00:00 2001 From: Fernando Dodino Date: Fri, 4 Oct 2019 16:53:42 -0300 Subject: [PATCH 010/133] Renaming variables with one letter --- .../src/wollok/lang.wlk | 21 +++++++++++-------- .../src/wollok/lang/Closure.xtend | 3 ++- .../tests/xpect/ConstructorDelegation.wlk.xt | 2 +- .../model/WMethodContainerExtensions.xtend | 6 ------ .../wollok/model/WollokModelExtensions.xtend | 13 ++++++++++-- 5 files changed, 26 insertions(+), 19 deletions(-) diff --git a/org.uqbar.project.wollok.lib/src/wollok/lang.wlk b/org.uqbar.project.wollok.lib/src/wollok/lang.wlk index 027f8b63dc..a4621a681c 100644 --- a/org.uqbar.project.wollok.lib/src/wollok/lang.wlk +++ b/org.uqbar.project.wollok.lib/src/wollok/lang.wlk @@ -112,6 +112,7 @@ class StackTraceElement { * since 1.0 */ class Object { + /** * Answers object identity of a Wollok object, represented by * a unique number in Wollok environment @@ -2392,10 +2393,10 @@ class Range { */ method map(closure) { self.checkNotNull(closure, "map") - const l = [] - self.forEach { e => l.add(closure.apply(e)) } - return l - } + const list = [] + self.forEach { element => list.add(closure.apply(element)) } + return list + } /** * Map + flatten operation @@ -2407,15 +2408,15 @@ class Range { */ method flatMap(closure) { self.checkNotNull(closure, "flatMap") - return self.fold([], { acc, e => - acc.addAll(closure.apply(e)) - acc + return self.fold([], { seed, element => + seed.addAll(closure.apply(element)) + seed }) } /** @private */ method asList() { - return self.map({ elem => return elem }) + return self.map({ elem => elem }) } /** @@ -2469,7 +2470,7 @@ class Range { * new Range(start = 2, end = 5).contains(4) ==> Answers true * new Range(start = 2, end = 5).contains(0) ==> Answers false */ - method contains(e) = self.asList().contains(e) + method contains(element) = self.asList().contains(element) /** @see List#sum() */ method sum() = self.asList().sum() @@ -2518,6 +2519,8 @@ class Range { */ class Closure { + method initialize() native + /** Evaluates this closure passing its parameters * * Example: diff --git a/org.uqbar.project.wollok.lib/src/wollok/lang/Closure.xtend b/org.uqbar.project.wollok.lib/src/wollok/lang/Closure.xtend index 69baa17594..79dd698b05 100644 --- a/org.uqbar.project.wollok.lib/src/wollok/lang/Closure.xtend +++ b/org.uqbar.project.wollok.lib/src/wollok/lang/Closure.xtend @@ -36,7 +36,8 @@ class Closure implements NodeAware, Function1 { EObject } - // REVIEW: all the convertions between list, array, etc + // Wollok unification + def initialize() {} override Object apply(WollokObject args) { val list = (args.wollokToJava(List) as List) diff --git a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/xpect/ConstructorDelegation.wlk.xt b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/xpect/ConstructorDelegation.wlk.xt index ca68349e99..85db12e525 100644 --- a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/xpect/ConstructorDelegation.wlk.xt +++ b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/xpect/ConstructorDelegation.wlk.xt @@ -124,5 +124,5 @@ class Cyclic { class Cyclic2 { // XPECT errors --> "Invalid super constructor call. Superclass has no explicit constructors." at "super(_param)" - constructor(_param) = super(_param) + constructor(_param) = super(_param) } \ No newline at end of file diff --git a/org.uqbar.project.wollok/src/org/uqbar/project/wollok/model/WMethodContainerExtensions.xtend b/org.uqbar.project.wollok/src/org/uqbar/project/wollok/model/WMethodContainerExtensions.xtend index 3654c1afa6..eb6bab52a6 100644 --- a/org.uqbar.project.wollok/src/org/uqbar/project/wollok/model/WMethodContainerExtensions.xtend +++ b/org.uqbar.project.wollok/src/org/uqbar/project/wollok/model/WMethodContainerExtensions.xtend @@ -674,12 +674,6 @@ class WMethodContainerExtensions extends WollokModelExtensions { ] } - def static WMethodDeclaration getInitMethod(WMethodContainer it) { - methods.findFirst [ m | - m.name.equals(INITIALIZE_METHOD) && m.arguments.isEmpty - ] - } - def static hasMethodWithSignature(WMethodContainer it, WMethodDeclaration method) { methods.exists[m | m.hasSameSignatureThan(method) ] } diff --git a/org.uqbar.project.wollok/src/org/uqbar/project/wollok/model/WollokModelExtensions.xtend b/org.uqbar.project.wollok/src/org/uqbar/project/wollok/model/WollokModelExtensions.xtend index b6688c9659..c5661752c7 100644 --- a/org.uqbar.project.wollok/src/org/uqbar/project/wollok/model/WollokModelExtensions.xtend +++ b/org.uqbar.project.wollok/src/org/uqbar/project/wollok/model/WollokModelExtensions.xtend @@ -68,14 +68,15 @@ import org.uqbar.project.wollok.wollokDsl.WVariableDeclaration import org.uqbar.project.wollok.wollokDsl.WVariableReference import org.uqbar.project.wollok.wollokDsl.WollokDslPackage import wollok.lang.Exception +import org.uqbar.project.wollok.sdk.WollokSDK +import org.eclipse.xtext.resource.IEObjectDescription import static org.uqbar.project.wollok.WollokConstants.* import static extension org.uqbar.project.wollok.model.ResourceUtils.* import static extension org.uqbar.project.wollok.model.WMethodContainerExtensions.* import static extension org.uqbar.project.wollok.visitors.ReturnFinderVisitor.containsReturnExpression -import org.uqbar.project.wollok.sdk.WollokSDK -import org.eclipse.xtext.resource.IEObjectDescription +import static extension org.uqbar.project.wollok.sdk.WollokSDK.* /** * Extension methods to Wollok semantic model. @@ -105,6 +106,14 @@ class WollokModelExtensions { def static dispatch String fqn(WMixin it) { nameWithPackage } def static dispatch String fqn(WSuite it) { nameWithPackage } + + def static WMethodDeclaration getInitMethod(WMethodContainer it) { + methods.findFirst [ m | + m.name.equals(INITIALIZE_METHOD) && m.arguments.isEmpty + ] + } + + /** * This method is intended to univocally identify every WMethodContainer * (original requirement for static diagram), so it can be decoupled From b5232be438a731b6f06604e835edd00f3e246f25 Mon Sep 17 00:00:00 2001 From: Fernando Dodino Date: Tue, 8 Oct 2019 22:52:08 -0300 Subject: [PATCH 011/133] Fix subList sanity test --- org.uqbar.project.wollok.lib/src/wollok/lang.wlk | 4 ++-- .../project/wollok/tests/interpreter/ListTestCase.xtend | 6 +++++- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/org.uqbar.project.wollok.lib/src/wollok/lang.wlk b/org.uqbar.project.wollok.lib/src/wollok/lang.wlk index 55ff3020db..5d4a7e0ce2 100644 --- a/org.uqbar.project.wollok.lib/src/wollok/lang.wlk +++ b/org.uqbar.project.wollok.lib/src/wollok/lang.wlk @@ -1241,7 +1241,7 @@ class List inherits Collection { */ method subList(start) { if (self.isEmpty()) return [] - if (start > self.size()) return [] + if (start >= self.size()) return [] return self.subList(start, self.size() - 1) } @@ -1259,7 +1259,7 @@ class List inherits Collection { method subList(start, end) { self.checkNotNull(start, "subList") self.checkNotNull(end, "subList") - if (self.isEmpty()) + if (self.isEmpty() || start >= self.size()) return self.newInstance() const newList = self.newInstance() diff --git a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/ListTestCase.xtend b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/ListTestCase.xtend index 47c7efaaaf..f8f2e1cd5e 100644 --- a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/ListTestCase.xtend +++ b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/ListTestCase.xtend @@ -6,7 +6,7 @@ import org.junit.Test * @author jfernandes */ class ListTestCase extends CollectionTestCase { - + @Test def void subList() { ''' @@ -15,6 +15,10 @@ class ListTestCase extends CollectionTestCase { assert.equals([22,2,10], numbers.subList(0,2)) assert.equals([2,10], numbers.subList(1,2)) assert.equals([2], numbers.subList(1,1)) + assert.equals([], numbers.subList(5)) + assert.equals([], numbers.subList(3)) + assert.equals([], numbers.subList(5,6)) + assert.equals([], [].subList(1, 2)) '''.test } From 8beb8906595a25a8d40dde49973390bd2e431482 Mon Sep 17 00:00:00 2001 From: ivan Date: Wed, 9 Oct 2019 01:01:22 -0300 Subject: [PATCH 012/133] sound class, sound adapter and type declarations --- .../wollok/game/gameboard/Gameboard.xtend | 31 +--------- .../wollok/game/gameboard/SoundAdapter.xtend | 57 +++++++++++++++++++ .../src/wollok/game.wlk | 54 +++++++++++++++++- .../src/wollok/game/GameObject.xtend | 9 ++- .../src/wollok/game/Sound.xtend | 47 +++++++++++++++ .../annotations/TypeDeclarations.xtend | 4 +- .../WollokGameTypeDeclarations.xtend | 12 +++- .../uqbar/project/wollok/sdk/WollokSDK.xtend | 1 + 8 files changed, 179 insertions(+), 36 deletions(-) create mode 100644 org.uqbar.project.wollok.game/src/org/uqbar/project/wollok/game/gameboard/SoundAdapter.xtend create mode 100644 org.uqbar.project.wollok.lib/src/wollok/game/Sound.xtend diff --git a/org.uqbar.project.wollok.game/src/org/uqbar/project/wollok/game/gameboard/Gameboard.xtend b/org.uqbar.project.wollok.game/src/org/uqbar/project/wollok/game/gameboard/Gameboard.xtend index 7fbcaee662..aff58b9814 100644 --- a/org.uqbar.project.wollok.game/src/org/uqbar/project/wollok/game/gameboard/Gameboard.xtend +++ b/org.uqbar.project.wollok.game/src/org/uqbar/project/wollok/game/gameboard/Gameboard.xtend @@ -1,10 +1,7 @@ package org.uqbar.project.wollok.game.gameboard; -import com.badlogic.gdx.Gdx -import com.badlogic.gdx.audio.Sound import java.util.Collection import java.util.List -import java.util.Map import org.apache.log4j.Logger import org.eclipse.osgi.util.NLS import org.eclipse.xtend.lib.annotations.Accessors @@ -26,7 +23,6 @@ class Gameboard { public static final int CELLZISE = 50 val Logger log = Logger.getLogger(this.class) - String title String ground String boardGround @@ -37,7 +33,7 @@ class Gameboard { List listeners = newArrayList VisualComponent character @Accessors(NONE) VisualComponent errorReporter - Map audioFiles = newHashMap + SoundAdapter soundAdapter def static getInstance() { if (instance === null) { @@ -51,6 +47,7 @@ class Gameboard { height = 5 width = 5 ground = "ground.png" + soundAdapter = SoundAdapter.getInstance } def void start() { @@ -178,28 +175,4 @@ class Gameboard { def VisualComponent errorReporter() { errorReporter ?: somebody } - - def sound(String audioFile) { - val sound = audioFile.fetchSound - if (sound !== null) { - sound.play(1.0f) - } - } - - def fetchSound(String audioFile) { - if (Gdx.app === null) - throw new RuntimeException(Messages.WollokGame_SoundGameNotStarted) - - var sound = audioFiles.get(audioFile) - if (sound === null) { - try { - val soundFile = Gdx.files.internal(audioFile) - sound = Gdx.audio.newSound(soundFile) - audioFiles.put(audioFile, sound) - } catch (Exception e) { - println(NLS.bind(Messages.WollokGame_AudioNotFound, audioFile)) - } - } - sound - } } diff --git a/org.uqbar.project.wollok.game/src/org/uqbar/project/wollok/game/gameboard/SoundAdapter.xtend b/org.uqbar.project.wollok.game/src/org/uqbar/project/wollok/game/gameboard/SoundAdapter.xtend new file mode 100644 index 0000000000..1419712778 --- /dev/null +++ b/org.uqbar.project.wollok.game/src/org/uqbar/project/wollok/game/gameboard/SoundAdapter.xtend @@ -0,0 +1,57 @@ +package org.uqbar.project.wollok.game.gameboard + +import org.eclipse.xtend.lib.annotations.Accessors +import com.badlogic.gdx.Gdx +import com.badlogic.gdx.audio.Sound +import java.util.Map +import org.uqbar.project.wollok.game.Messages +import org.eclipse.osgi.util.NLS + + +@Accessors +class SoundAdapter { + Map audioFiles = newHashMap + public static SoundAdapter instance + + def static getInstance() { + if (instance === null) { + instance = new SoundAdapter() + } + instance + } + + def fetchSound(String audioFile) { + if (Gdx.app === null) + throw new RuntimeException(Messages.WollokGame_SoundGameNotStarted) + + var sound = audioFiles.get(audioFile) + if (sound === null) { + try { + val soundFile = Gdx.files.internal(audioFile) + sound = Gdx.audio.newSound(soundFile) + audioFiles.put(audioFile, sound) + } catch (Exception e) { + println(NLS.bind(Messages.WollokGame_AudioNotFound, audioFile)) + } + } + sound + } + + def play(String file){ + file.fetchSound.play() + } + + def loop(String file,long id,boolean looping){ + file.fetchSound.setLooping(id,looping) + } + def stop(String file){ + file.fetchSound.stop() + } + def volume(String file,long id,float newVolume){ + file.fetchSound.setVolume(id,newVolume) + } + def pause(String file){ + file.fetchSound.pause() + } + +} \ No newline at end of file diff --git a/org.uqbar.project.wollok.lib/src/wollok/game.wlk b/org.uqbar.project.wollok.lib/src/wollok/game.wlk index 8dc20d4bfb..49012d07be 100644 --- a/org.uqbar.project.wollok.lib/src/wollok/game.wlk +++ b/org.uqbar.project.wollok.lib/src/wollok/game.wlk @@ -242,10 +242,12 @@ object game { method errorReporter(visual) native /** - * Plays once a .mp3, .ogg or .wav audio file + * Returns a sound object */ - method sound(audioFile) native - + method sound(audioFile) { + return new Sound(file=audioFile) + } + /** * @private */ @@ -469,3 +471,49 @@ class Key { keyCodes.forEach{ key => game.whenKeyPressedDo(key, action) } //TODO: Implement native } } + + +class Sound { + constructor(file){ + self.setFile(file) + } + + + /** + * @private + */ + method setFile(file) native + + /** + * Plays the file's sound + */ + method play() native + + /** + * Stops playing the sound without saving the state + */ + method stop() native + + /** + * Pauses the sound + */ + method pause() native + + /** Changes absolute volume, values should be between 0 and 1 + * + * Examples: + * mySound.volume(0.5) New volume is half of the original sound's volume + * mySound.volume(mySound.volume()*0.5) New volume is half of the current volume + */ + method volume(newVolume) native + + /** + * Returns current sound volume + */ + method volume() native + + /** + * Now plays as a loop + */ + method loop() native +} \ No newline at end of file diff --git a/org.uqbar.project.wollok.lib/src/wollok/game/GameObject.xtend b/org.uqbar.project.wollok.lib/src/wollok/game/GameObject.xtend index eef1e25750..26bb52c2ce 100644 --- a/org.uqbar.project.wollok.lib/src/wollok/game/GameObject.xtend +++ b/org.uqbar.project.wollok.lib/src/wollok/game/GameObject.xtend @@ -20,6 +20,7 @@ import static extension org.uqbar.project.wollok.interpreter.nativeobj.WollokJav import static extension org.uqbar.project.wollok.lib.WollokSDKExtensions.* import static extension org.uqbar.project.wollok.utils.WollokObjectUtils.checkNotNull + /** * * @author ? @@ -184,9 +185,13 @@ class GameObject { .findFirst[ WObject.equals(visual)] } - def sound(String audioFile) { - board.sound(audioFile) + def WollokObject sound(String audioFile) { + var newSound = new Sound() + newSound.initialize(audioFile) + return newSound.wObject() } + + // ACCESSORS def title() { board.title } diff --git a/org.uqbar.project.wollok.lib/src/wollok/game/Sound.xtend b/org.uqbar.project.wollok.lib/src/wollok/game/Sound.xtend new file mode 100644 index 0000000000..bb19148ad3 --- /dev/null +++ b/org.uqbar.project.wollok.lib/src/wollok/game/Sound.xtend @@ -0,0 +1,47 @@ +package wollok.game + +import org.eclipse.xtend.lib.annotations.Accessors +import org.uqbar.project.wollok.interpreter.WollokInterpreter +import org.uqbar.project.wollok.interpreter.WollokInterpreterEvaluator +import org.uqbar.project.wollok.game.gameboard.SoundAdapter + +import static org.uqbar.project.wollok.sdk.WollokSDK.* + +import static extension org.uqbar.project.wollok.interpreter.nativeobj.WollokJavaConversions.* +import org.uqbar.project.wollok.interpreter.core.WollokObject + +@Accessors +class Sound { + String file + long soundID + float volume + + def initialize(String _file){ + file=_file + } + + def wObject() { + return (WollokInterpreter.getInstance().getEvaluator() as WollokInterpreterEvaluator).newInstance(SOUND) => [] + } + + def volume(float newVolume) { + volume=newVolume + SoundAdapter.getInstance.volume(file,soundID,volume) + } + def pause() { + SoundAdapter.getInstance.pause(file) + } + + def void play() { + soundID=SoundAdapter.getInstance.play(file) + } + + def stop() { + SoundAdapter.getInstance.stop(file) + } + + def loop(boolean looping) { + SoundAdapter.getInstance.loop(file,soundID,looping) + } + +} diff --git a/org.uqbar.project.wollok.typeSystem/src/org/uqbar/project/wollok/typesystem/annotations/TypeDeclarations.xtend b/org.uqbar.project.wollok.typeSystem/src/org/uqbar/project/wollok/typesystem/annotations/TypeDeclarations.xtend index 385037d2ad..ff52f09128 100644 --- a/org.uqbar.project.wollok.typeSystem/src/org/uqbar/project/wollok/typesystem/annotations/TypeDeclarations.xtend +++ b/org.uqbar.project.wollok.typeSystem/src/org/uqbar/project/wollok/typesystem/annotations/TypeDeclarations.xtend @@ -197,6 +197,8 @@ abstract class TypeDeclarations { def Key() { classTypeAnnotation(KEY) } + def Sound() {classTypeAnnotation(SOUND)} + def ExceptionType() { classTypeAnnotation(EXCEPTION) } def StackTraceElement() { classTypeAnnotation(STACK_TRACE_ELEMENT) } @@ -215,7 +217,7 @@ abstract class TypeDeclarations { def runtime() { objectTypeAnnotation(RUNTIME) } - def keyboard() { objectTypeAnnotation(KEYBOARD) } + def keyboard() { objectTypeAnnotation(KEYBOARD) } def PKEY() { PairType.param(GenericTypeInfo.KEY) } diff --git a/org.uqbar.project.wollok.typeSystem/src/org/uqbar/project/wollok/typesystem/annotations/WollokGameTypeDeclarations.xtend b/org.uqbar.project.wollok.typeSystem/src/org/uqbar/project/wollok/typesystem/annotations/WollokGameTypeDeclarations.xtend index 3a3dbb2e77..57eedab2b1 100644 --- a/org.uqbar.project.wollok.typeSystem/src/org/uqbar/project/wollok/typesystem/annotations/WollokGameTypeDeclarations.xtend +++ b/org.uqbar.project.wollok.typeSystem/src/org/uqbar/project/wollok/typesystem/annotations/WollokGameTypeDeclarations.xtend @@ -1,6 +1,8 @@ package org.uqbar.project.wollok.typesystem.annotations class WollokGameTypeDeclarations extends TypeDeclarations { + + override declarations() { Position.variable("x", Number) Position.variable("y", Number) @@ -55,11 +57,19 @@ class WollokGameTypeDeclarations extends TypeDeclarations { game >> "hideAttributes" === #[T] => Void game >> "showAttributes" === #[T] => Void game >> "errorReporter" === #[T] => Void - game >> "sound" === #[String] => Void + game >> "sound" === #[String] => Sound keyboard.allMethods.except("num") === #[] => Key keyboard >> "num" === #[Number] => Key + + Sound.variable("file",String) + Sound.fakeProperty("volume",Number) + Sound >> "play" === #[] => Void + Sound >> "stop" === #[] => Void + Sound >> "pause" === #[] => Void + Sound >> "loop" === #[] => Void + Key >> "onPressDo" === #[closure(#[], Void)] => Void } } \ No newline at end of file diff --git a/org.uqbar.project.wollok/src/org/uqbar/project/wollok/sdk/WollokSDK.xtend b/org.uqbar.project.wollok/src/org/uqbar/project/wollok/sdk/WollokSDK.xtend index 1c915a288b..994cae23fc 100644 --- a/org.uqbar.project.wollok/src/org/uqbar/project/wollok/sdk/WollokSDK.xtend +++ b/org.uqbar.project.wollok/src/org/uqbar/project/wollok/sdk/WollokSDK.xtend @@ -48,6 +48,7 @@ class WollokSDK { public static val INSTANCE_VARIABLE_MIRROR = "wollok.mirror.InstanceVariableMirror" public static val POSITION = "wollok.game.Position" + public static val SOUND = "wollok.game.Sound" public static val ASSERTION_EXCEPTION_FQN = "wollok.lib.AssertionException" public static val STRING_PRINTER = "wollok.lib.StringPrinter" From 65b7b306aa3d761d2a3b4c6670b37bf728b2d269 Mon Sep 17 00:00:00 2001 From: Fernando Dodino Date: Wed, 9 Oct 2019 08:54:18 -0300 Subject: [PATCH 013/133] Fix #1820 Position message instead of attribute --- .../src/org/uqbar/project/wollok/messages.properties | 2 +- .../src/org/uqbar/project/wollok/messages_es.properties | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/org.uqbar.project.wollok/src/org/uqbar/project/wollok/messages.properties b/org.uqbar.project.wollok/src/org/uqbar/project/wollok/messages.properties index 41aca174ad..84f9df6c71 100644 --- a/org.uqbar.project.wollok/src/org/uqbar/project/wollok/messages.properties +++ b/org.uqbar.project.wollok/src/org/uqbar/project/wollok/messages.properties @@ -26,7 +26,7 @@ WollokInterpreter_operationNotSupported = Operation "{0}" not supported by inter WollokInterpreter_operatorNotSupported = Operator "{0}" not supported for {1} WollokInterpreter_constructorCallNotAllowed = Impossible to call a constructor on anything besides a class WollokInterpreter_binaryOperationNotCompoundAssignment = Binary operation is not a compound assignment -WollokInterpreter_visualObjectWithoutPosition = Visual object doesn't have any position attribute: {0} +WollokInterpreter_visualObjectWithoutPosition = Object doesn't understand 'position' message: {0} WollokInterpreter_illegalOperationEmptyCollection = Illegal operation ''{0}'' on empty collection WollokInterpreter_referenceAlreadyDefined=Reference "{0}" has already been defined WollokDslInterpreter_native_class_not_found = You declared a native method but there is no native definition for {0} (maybe it is a pure Wollok definition) diff --git a/org.uqbar.project.wollok/src/org/uqbar/project/wollok/messages_es.properties b/org.uqbar.project.wollok/src/org/uqbar/project/wollok/messages_es.properties index 5a15177278..8bf3a1ead0 100644 --- a/org.uqbar.project.wollok/src/org/uqbar/project/wollok/messages_es.properties +++ b/org.uqbar.project.wollok/src/org/uqbar/project/wollok/messages_es.properties @@ -25,7 +25,7 @@ WollokInterpreter_operationNotSupported = Operaci\u00F3n '{0}' no soportada por WollokInterpreter_operatorNotSupported = {1} no soporta el operador {0} WollokInterpreter_constructorCallNotAllowed = No puede llamar a un constructor de algo que no sea una clase WollokInterpreter_binaryOperationNotCompoundAssignment = La operaci\u00F3n binaria no es una asignaci\u00F3n compuesta -WollokInterpreter_visualObjectWithoutPosition = El objeto visual no tiene un atributo 'position': {0} +WollokInterpreter_visualObjectWithoutPosition = El objeto no entiende el mensaje 'position': {0} WollokInterpreter_illegalOperationEmptyCollection = Operaci\u00F3n '{0}' no permitida en colecciones vac\u00EDas WollokInterpreter_referenceAlreadyDefined = La referencia "{0}" fue definida previamente WollokDslInterpreter_native_class_not_found = Declar\u00F3 un \u00E9todo nativo pero no se encontr\u00F3 la definici\u00F3n nativa de {0} (posiblemente se trate de un elemento definido s\u00F3lo en Wollok) From a81bc8862f9de91861c78ced524d37252e5da6ac Mon Sep 17 00:00:00 2001 From: Fernando Dodino Date: Wed, 9 Oct 2019 09:04:16 -0300 Subject: [PATCH 014/133] Changing referenciable to reference - haven't tested it --- .../uqbar/project/wollok/errorHandling/HumanReadableUtils.xtend | 2 ++ 1 file changed, 2 insertions(+) diff --git a/org.uqbar.project.wollok/src/org/uqbar/project/wollok/errorHandling/HumanReadableUtils.xtend b/org.uqbar.project.wollok/src/org/uqbar/project/wollok/errorHandling/HumanReadableUtils.xtend index 939385cb45..ec3ce52cb6 100644 --- a/org.uqbar.project.wollok/src/org/uqbar/project/wollok/errorHandling/HumanReadableUtils.xtend +++ b/org.uqbar.project.wollok/src/org/uqbar/project/wollok/errorHandling/HumanReadableUtils.xtend @@ -13,6 +13,7 @@ import org.uqbar.project.wollok.wollokDsl.WMethodContainer import org.uqbar.project.wollok.wollokDsl.WMethodDeclaration import org.uqbar.project.wollok.wollokDsl.WNamedObject import org.uqbar.project.wollok.wollokDsl.WObjectLiteral +import org.uqbar.project.wollok.wollokDsl.WReferenciable import org.uqbar.project.wollok.wollokDsl.WVariableDeclaration import static extension org.uqbar.project.wollok.model.WMethodContainerExtensions.* @@ -34,6 +35,7 @@ class HumanReadableUtils { def static dispatch modelTypeDescription(WMethodDeclaration it) { "Method" } def static dispatch modelTypeDescription(WVariableDeclaration it) { if (writeable) "Variable" else "Constant" } + def static modelTypeName(WReferenciable it) { "reference " + name } def static modelTypeName(EClass it) { if(name.startsWith("W")) name.substring(1) else name } From 10f0351ef73af325ef14b60467f9db5e59f2dfdf Mon Sep 17 00:00:00 2001 From: ivan Date: Thu, 10 Oct 2019 17:42:13 -0300 Subject: [PATCH 015/133] New sounds for wollok game --- .../wollok/game/gameboard/GameSound.xtend | 58 +++++++++ .../wollok/game/gameboard/Gameboard.xtend | 3 +- .../wollok/game/gameboard/SoundAdapter.xtend | 57 --------- .../src/wollok/game.wlk | 22 ++-- .../src/wollok/game/GameObject.xtend | 113 ++++++++---------- .../src/wollok/game/Sound.xtend | 47 -------- .../src/wollok/game/WSound.xtend | 45 +++++++ org.uqbar.project.wollok.tests/.classpath | 18 ++- .../natives/DefaultNativeObjectFactory.xtend | 3 +- 9 files changed, 178 insertions(+), 188 deletions(-) create mode 100644 org.uqbar.project.wollok.game/src/org/uqbar/project/wollok/game/gameboard/GameSound.xtend delete mode 100644 org.uqbar.project.wollok.game/src/org/uqbar/project/wollok/game/gameboard/SoundAdapter.xtend delete mode 100644 org.uqbar.project.wollok.lib/src/wollok/game/Sound.xtend create mode 100644 org.uqbar.project.wollok.lib/src/wollok/game/WSound.xtend diff --git a/org.uqbar.project.wollok.game/src/org/uqbar/project/wollok/game/gameboard/GameSound.xtend b/org.uqbar.project.wollok.game/src/org/uqbar/project/wollok/game/gameboard/GameSound.xtend new file mode 100644 index 0000000000..d0fdc6239d --- /dev/null +++ b/org.uqbar.project.wollok.game/src/org/uqbar/project/wollok/game/gameboard/GameSound.xtend @@ -0,0 +1,58 @@ +package org.uqbar.project.wollok.game.gameboard + +import com.badlogic.gdx.Gdx +import com.badlogic.gdx.audio.Sound +import org.eclipse.osgi.util.NLS +import org.eclipse.xtend.lib.annotations.Accessors +import org.uqbar.project.wollok.game.Messages + +@Accessors +class GameSound { + String file + long soundID + float volume + Sound sound + + def play() { + soundID = fetchSound.play() + } + + def stop() { + fetchSound.stop() + } + + def pause() { + fetchSound.pause() + } + + def resume() { + fetchSound.resume() + } + + def volume(float newVolume) { + fetchSound.setVolume(soundID, newVolume) + } + +// def volume(){ +// } + + def loop(boolean looping) { + fetchSound.setLooping(soundID, looping) + } + + def fetchSound() { + if (Gdx.app === null) + throw new RuntimeException(Messages.WollokGame_SoundGameNotStarted) + + if (sound === null) { + try { + val soundFile = Gdx.files.internal(file) + sound = Gdx.audio.newSound(soundFile) + } catch (Exception e) { + println(NLS.bind(Messages.WollokGame_AudioNotFound, file)) + } + } + sound + } + +} diff --git a/org.uqbar.project.wollok.game/src/org/uqbar/project/wollok/game/gameboard/Gameboard.xtend b/org.uqbar.project.wollok.game/src/org/uqbar/project/wollok/game/gameboard/Gameboard.xtend index aff58b9814..350e8ab1db 100644 --- a/org.uqbar.project.wollok.game/src/org/uqbar/project/wollok/game/gameboard/Gameboard.xtend +++ b/org.uqbar.project.wollok.game/src/org/uqbar/project/wollok/game/gameboard/Gameboard.xtend @@ -33,7 +33,7 @@ class Gameboard { List listeners = newArrayList VisualComponent character @Accessors(NONE) VisualComponent errorReporter - SoundAdapter soundAdapter + def static getInstance() { if (instance === null) { @@ -47,7 +47,6 @@ class Gameboard { height = 5 width = 5 ground = "ground.png" - soundAdapter = SoundAdapter.getInstance } def void start() { diff --git a/org.uqbar.project.wollok.game/src/org/uqbar/project/wollok/game/gameboard/SoundAdapter.xtend b/org.uqbar.project.wollok.game/src/org/uqbar/project/wollok/game/gameboard/SoundAdapter.xtend deleted file mode 100644 index 1419712778..0000000000 --- a/org.uqbar.project.wollok.game/src/org/uqbar/project/wollok/game/gameboard/SoundAdapter.xtend +++ /dev/null @@ -1,57 +0,0 @@ -package org.uqbar.project.wollok.game.gameboard - -import org.eclipse.xtend.lib.annotations.Accessors -import com.badlogic.gdx.Gdx -import com.badlogic.gdx.audio.Sound -import java.util.Map -import org.uqbar.project.wollok.game.Messages -import org.eclipse.osgi.util.NLS - - -@Accessors -class SoundAdapter { - Map audioFiles = newHashMap - public static SoundAdapter instance - - def static getInstance() { - if (instance === null) { - instance = new SoundAdapter() - } - instance - } - - def fetchSound(String audioFile) { - if (Gdx.app === null) - throw new RuntimeException(Messages.WollokGame_SoundGameNotStarted) - - var sound = audioFiles.get(audioFile) - if (sound === null) { - try { - val soundFile = Gdx.files.internal(audioFile) - sound = Gdx.audio.newSound(soundFile) - audioFiles.put(audioFile, sound) - } catch (Exception e) { - println(NLS.bind(Messages.WollokGame_AudioNotFound, audioFile)) - } - } - sound - } - - def play(String file){ - file.fetchSound.play() - } - - def loop(String file,long id,boolean looping){ - file.fetchSound.setLooping(id,looping) - } - def stop(String file){ - file.fetchSound.stop() - } - def volume(String file,long id,float newVolume){ - file.fetchSound.setVolume(id,newVolume) - } - def pause(String file){ - file.fetchSound.pause() - } - -} \ No newline at end of file diff --git a/org.uqbar.project.wollok.lib/src/wollok/game.wlk b/org.uqbar.project.wollok.lib/src/wollok/game.wlk index 49012d07be..b26ce26021 100644 --- a/org.uqbar.project.wollok.lib/src/wollok/game.wlk +++ b/org.uqbar.project.wollok.lib/src/wollok/game.wlk @@ -474,15 +474,7 @@ class Key { class Sound { - constructor(file){ - self.setFile(file) - } - - - /** - * @private - */ - method setFile(file) native + const property file /** * Plays the file's sound @@ -499,6 +491,11 @@ class Sound { */ method pause() native + /** + * Resumes the sound + */ + method resume() native + /** Changes absolute volume, values should be between 0 and 1 * * Examples: @@ -507,13 +504,8 @@ class Sound { */ method volume(newVolume) native - /** - * Returns current sound volume - */ - method volume() native - /** * Now plays as a loop */ - method loop() native + method loop(looping) native } \ No newline at end of file diff --git a/org.uqbar.project.wollok.lib/src/wollok/game/GameObject.xtend b/org.uqbar.project.wollok.lib/src/wollok/game/GameObject.xtend index 26bb52c2ce..f1bc7b46a8 100644 --- a/org.uqbar.project.wollok.lib/src/wollok/game/GameObject.xtend +++ b/org.uqbar.project.wollok.lib/src/wollok/game/GameObject.xtend @@ -20,35 +20,34 @@ import static extension org.uqbar.project.wollok.interpreter.nativeobj.WollokJav import static extension org.uqbar.project.wollok.lib.WollokSDKExtensions.* import static extension org.uqbar.project.wollok.utils.WollokObjectUtils.checkNotNull - /** * * @author ? */ class GameObject { - + def addVisual(WollokObject it) { - checkNotNull("addVisual") + checkNotNull("addVisual") board.addComponent(asVisual) } def addVisualIn(WollokObject it, WollokObject position) { checkNotNull("addVisualIn") - position.checkNotNull("addVisualIn") + position.checkNotNull("addVisualIn") board.addComponent(asVisualIn(position)) } - + def addVisualCharacter(WollokObject it) { - checkNotNull("addVisualCharacter") + checkNotNull("addVisualCharacter") board.addCharacter(asVisual) } - + def addVisualCharacterIn(WollokObject it, WollokObject position) { checkNotNull("addVisualCharacterIn") - position.checkNotNull("addVisualCharacterIn") + position.checkNotNull("addVisualCharacterIn") board.addCharacter(asVisualIn(position)) } - + def removeVisual(WollokObject it) { checkNotNull("removeVisual") var visual = board.findVisual(it) @@ -61,155 +60,143 @@ class GameObject { } def allVisuals() { - return board.components - .map [ it.WObject ] - .toList.javaToWollok + return board.components.map[it.WObject].toList.javaToWollok } - + def onTick(WollokObject milliseconds, WollokObject name, WollokObject action) { milliseconds.checkNotNull("onTick") name.checkNotNull("onTick") action.checkNotNull("onTick") val function = action.asClosure - addListener(new TimeListener(name.asString, milliseconds.coerceToInteger, [ function.doApply ])) + addListener(new TimeListener(name.asString, milliseconds.coerceToInteger, [function.doApply])) } - + def schedule(WollokObject milliseconds, WollokObject action) { milliseconds.checkNotNull("schedule") action.checkNotNull("schedule") val function = action.asClosure - addListener(new ScheduleListener(milliseconds.coerceToInteger, [ function.doApply ])) + addListener(new ScheduleListener(milliseconds.coerceToInteger, [function.doApply])) } - + def removeTickEvent(WollokObject name) { name.checkNotNull("removeTickEvent") board.removeListener(name.asString) } - + def whenKeyPressedDo(WollokObject key, WollokObject action) { key.checkNotNull("whenKeyPressedDo") action.checkNotNull("whenKeyPressedDo") var num = key.coerceToInteger val function = action.asClosure - addListener(new KeyboardListener(num, [ function.doApply ])) + addListener(new KeyboardListener(num, [function.doApply])) } def whenKeyPressedSay(WollokObject key, WollokObject functionObj) { val num = key.coerceToInteger val function = functionObj.asClosure - addListener(new KeyboardListener(num, [ board.characterSay(function.doApply.asString) ])) + addListener(new KeyboardListener(num, [board.characterSay(function.doApply.asString)])) } - + def whenCollideDo(WollokObject visual, WollokObject action) { visual.checkNotNull("whenCollideDo") action.checkNotNull("whenCollideDo") var visualObject = board.findVisual(visual) val function = action.asClosure - addListener(new CollisionListener(visualObject, [ function.doApply(it.WObject) ])) + addListener(new CollisionListener(visualObject, [function.doApply(it.WObject)])) } - + def onCollideDo(WollokObject visual, WollokObject action) { visual.checkNotNull("onCollideDo") action.checkNotNull("onCollideDo") var visualObject = board.findVisual(visual) val function = action.asClosure - addListener(new InstantCollisionListener(visualObject, [ function.doApply(it.WObject) ])) + addListener(new InstantCollisionListener(visualObject, [function.doApply(it.WObject)])) } - + def getObjectsIn(WollokObject position) { position.checkNotNull("getObjectsIn") - board - .getComponentsInPosition(new WPosition(position)) - .map [ it.WObject ] - .toList.javaToWollok + board.getComponentsInPosition(new WPosition(position)).map[it.WObject].toList.javaToWollok } - + def colliders(WollokObject visual) { visual.checkNotNull("colliders") val visualObject = board.findVisual(visual) - board.getComponentsInPosition(visualObject.position) - .filter [ !it.equals(visualObject)] - .map [ it.WObject ] - .toList.javaToWollok + board.getComponentsInPosition(visualObject.position).filter[!it.equals(visualObject)].map[it.WObject].toList. + javaToWollok } - + def say(WollokObject visual, String message) { visual.checkNotNull("say") board.findVisual(visual).say(message ?: "") } - + def hideAttributes(WollokObject visual) { visual.checkNotNull("hideAttributes") board.findVisual(visual).hideAttributes() } - + def void errorReporter(WollokObject visual) { visual.checkNotNull("errorReporter") board.errorReporter(board.findVisual(visual)) } - + def showAttributes(WollokObject visual) { visual.checkNotNull("showAttributes") board.findVisual(visual).showAttributes() } - + def clear() { board.clear } - + def doStart(Boolean isRepl) { - isRepl.checkNotNull("doStart") + isRepl.checkNotNull("doStart") board.start(isRepl) } - + def stop() { board.stop } - + def board() { Gameboard.getInstance } - + def addListener(GameboardListener listener) { listener.checkNotNull("addListener") board.addListener(listener) } - + def findVisual(Gameboard it, WollokObject visual) { val result = findIfExistsVisual(it, visual) - + if (result === null) throw new WollokProgramExceptionWrapper(evaluator.newInstance(EXCEPTION) => [ - setReference("message", NLS.bind(Messages.WollokGame_VisualComponentNotFound, visual).javaToWollok) + setReference("message", NLS.bind(Messages.WollokGame_VisualComponentNotFound, visual).javaToWollok) ]) - + result } - + def findIfExistsVisual(Gameboard it, WollokObject visual) { - return components - .findFirst[ WObject.equals(visual)] + return components.findFirst[WObject.equals(visual)] } - def WollokObject sound(String audioFile) { - var newSound = new Sound() - newSound.initialize(audioFile) - return newSound.wObject() - } - - - // ACCESSORS def title() { board.title } + def title(String title) { board.title = title ?: "" } - + def width() { board.width.javaToWollok } + def width(WollokObject cant) { cant.checkNotNull("width") board.width = cant.coerceToInteger } - + def height() { board.height.javaToWollok } + def height(WollokObject cant) { cant.checkNotNull("height") board.height = cant.coerceToInteger } - + def ground(String image) { board.ground = image } + def boardGround(String image) { board.boardGround = image } - + } diff --git a/org.uqbar.project.wollok.lib/src/wollok/game/Sound.xtend b/org.uqbar.project.wollok.lib/src/wollok/game/Sound.xtend deleted file mode 100644 index bb19148ad3..0000000000 --- a/org.uqbar.project.wollok.lib/src/wollok/game/Sound.xtend +++ /dev/null @@ -1,47 +0,0 @@ -package wollok.game - -import org.eclipse.xtend.lib.annotations.Accessors -import org.uqbar.project.wollok.interpreter.WollokInterpreter -import org.uqbar.project.wollok.interpreter.WollokInterpreterEvaluator -import org.uqbar.project.wollok.game.gameboard.SoundAdapter - -import static org.uqbar.project.wollok.sdk.WollokSDK.* - -import static extension org.uqbar.project.wollok.interpreter.nativeobj.WollokJavaConversions.* -import org.uqbar.project.wollok.interpreter.core.WollokObject - -@Accessors -class Sound { - String file - long soundID - float volume - - def initialize(String _file){ - file=_file - } - - def wObject() { - return (WollokInterpreter.getInstance().getEvaluator() as WollokInterpreterEvaluator).newInstance(SOUND) => [] - } - - def volume(float newVolume) { - volume=newVolume - SoundAdapter.getInstance.volume(file,soundID,volume) - } - def pause() { - SoundAdapter.getInstance.pause(file) - } - - def void play() { - soundID=SoundAdapter.getInstance.play(file) - } - - def stop() { - SoundAdapter.getInstance.stop(file) - } - - def loop(boolean looping) { - SoundAdapter.getInstance.loop(file,soundID,looping) - } - -} diff --git a/org.uqbar.project.wollok.lib/src/wollok/game/WSound.xtend b/org.uqbar.project.wollok.lib/src/wollok/game/WSound.xtend new file mode 100644 index 0000000000..b664934618 --- /dev/null +++ b/org.uqbar.project.wollok.lib/src/wollok/game/WSound.xtend @@ -0,0 +1,45 @@ +package wollok.game + +import org.eclipse.xtend.lib.annotations.Accessors +import org.uqbar.project.wollok.game.gameboard.GameSound +import org.uqbar.project.wollok.interpreter.core.WollokObject +import wollok.lang.AbstractJavaWrapper + +import static extension org.uqbar.project.wollok.interpreter.nativeobj.WollokJavaConversions.* + +@Accessors +class WSound extends AbstractJavaWrapper { + + def void play() { + getWrapped.play() + } + + def void stop() { + getWrapped.stop() + } + + def void pause() { + getWrapped.pause() + } + + def void resume() { + getWrapped.resume() + } + + def void volume(WollokObject newVolume) { + getWrapped.volume(newVolume.asNumber.floatValue) + } + + def void loop(boolean looping) { + getWrapped.loop(looping) + } + + override getWrapped() { + if (wrapped === null) { + val _file = obj.resolve("file").toWollokString + wrapped = new GameSound => [file = _file] + } + wrapped + } + +} diff --git a/org.uqbar.project.wollok.tests/.classpath b/org.uqbar.project.wollok.tests/.classpath index 1671c20fb7..8f2dea7b03 100644 --- a/org.uqbar.project.wollok.tests/.classpath +++ b/org.uqbar.project.wollok.tests/.classpath @@ -4,8 +4,20 @@ - - - + + + + + + + + + + + + + + + diff --git a/org.uqbar.project.wollok/src/org/uqbar/project/wollok/interpreter/natives/DefaultNativeObjectFactory.xtend b/org.uqbar.project.wollok/src/org/uqbar/project/wollok/interpreter/natives/DefaultNativeObjectFactory.xtend index 0daecf45d9..1c793e7783 100644 --- a/org.uqbar.project.wollok/src/org/uqbar/project/wollok/interpreter/natives/DefaultNativeObjectFactory.xtend +++ b/org.uqbar.project.wollok/src/org/uqbar/project/wollok/interpreter/natives/DefaultNativeObjectFactory.xtend @@ -34,7 +34,8 @@ class DefaultNativeObjectFactory implements NativeObjectFactory { NUMBER -> "wollok.lang.WNumber", STRING -> "wollok.lang.WString", BOOLEAN -> "wollok.lang.WBoolean", - DATE -> "wollok.lang.WDate" + DATE -> "wollok.lang.WDate", + SOUND -> "wollok.game.WSound" } override createNativeObject(WClass it, WollokObject obj, WollokInterpreter interpreter) { From 9537eee679a1c0aecf05782fc7d990689c7c0b72 Mon Sep 17 00:00:00 2001 From: ivan Date: Thu, 10 Oct 2019 17:53:13 -0300 Subject: [PATCH 016/133] remove unused variable volume --- .../org/uqbar/project/wollok/game/gameboard/GameSound.xtend | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/org.uqbar.project.wollok.game/src/org/uqbar/project/wollok/game/gameboard/GameSound.xtend b/org.uqbar.project.wollok.game/src/org/uqbar/project/wollok/game/gameboard/GameSound.xtend index d0fdc6239d..ef518d1bf8 100644 --- a/org.uqbar.project.wollok.game/src/org/uqbar/project/wollok/game/gameboard/GameSound.xtend +++ b/org.uqbar.project.wollok.game/src/org/uqbar/project/wollok/game/gameboard/GameSound.xtend @@ -10,7 +10,6 @@ import org.uqbar.project.wollok.game.Messages class GameSound { String file long soundID - float volume Sound sound def play() { @@ -32,10 +31,9 @@ class GameSound { def volume(float newVolume) { fetchSound.setVolume(soundID, newVolume) } - + // def volume(){ // } - def loop(boolean looping) { fetchSound.setLooping(soundID, looping) } From 882222fbba8cfae2a747330f33147cf2d3abf09c Mon Sep 17 00:00:00 2001 From: Fernando Dodino Date: Sat, 12 Oct 2019 10:40:29 -0300 Subject: [PATCH 017/133] Fix #1841 - fixing test runner if an error occurs in initialization or fixture --- .../launch/tests/DefaultWollokTestsReporter.xtend | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/org.uqbar.project.wollok.launch/src/org/uqbar/project/wollok/launch/tests/DefaultWollokTestsReporter.xtend b/org.uqbar.project.wollok.launch/src/org/uqbar/project/wollok/launch/tests/DefaultWollokTestsReporter.xtend index 4d40ccb899..8be248feec 100644 --- a/org.uqbar.project.wollok.launch/src/org/uqbar/project/wollok/launch/tests/DefaultWollokTestsReporter.xtend +++ b/org.uqbar.project.wollok.launch/src/org/uqbar/project/wollok/launch/tests/DefaultWollokTestsReporter.xtend @@ -83,11 +83,20 @@ class DefaultWollokTestsReporter implements WollokTestsReporter { } def testFinished(WTest test) { - testTimeElapsed.get(test).to = System.currentTimeMillis + if (test.hasTimeElapsedRecord) { + testTimeElapsed.get(test).to = System.currentTimeMillis + } } def getTotalTime(WTest test) { - testTimeElapsed.get(test).totalTime + if (test.hasTimeElapsedRecord) testTimeElapsed.get(test).totalTime else 0 + } + + /** + * If there was an error in the fixture, or in variable initialization, we won't be able to get the test in the map + */ + def hasTimeElapsedRecord(WTest test) { + testTimeElapsed.get(test) !== null } } From b971b6bae22068bd895526f1edab2047faafda1f Mon Sep 17 00:00:00 2001 From: Fernando Dodino Date: Sat, 12 Oct 2019 11:38:37 -0300 Subject: [PATCH 018/133] Printing all errors in final step --- .../tests/WollokConsoleTestsReporter.xtend | 98 ++++++++++++++++--- 1 file changed, 83 insertions(+), 15 deletions(-) diff --git a/org.uqbar.project.wollok.launch/src/org/uqbar/project/wollok/launch/tests/WollokConsoleTestsReporter.xtend b/org.uqbar.project.wollok.launch/src/org/uqbar/project/wollok/launch/tests/WollokConsoleTestsReporter.xtend index cf0a929059..0736b1dc5f 100644 --- a/org.uqbar.project.wollok.launch/src/org/uqbar/project/wollok/launch/tests/WollokConsoleTestsReporter.xtend +++ b/org.uqbar.project.wollok.launch/src/org/uqbar/project/wollok/launch/tests/WollokConsoleTestsReporter.xtend @@ -2,6 +2,8 @@ package org.uqbar.project.wollok.launch.tests import java.util.List import org.eclipse.emf.common.util.URI +import org.eclipse.xtend.lib.annotations.Accessors +import org.eclipse.xtend.lib.annotations.Data import org.fusesource.jansi.AnsiConsole import org.uqbar.project.wollok.interpreter.WollokTestsFailedException import org.uqbar.project.wollok.wollokDsl.WFile @@ -34,7 +36,10 @@ class WollokConsoleTestsReporter extends DefaultWollokTestsReporter { int testsFailed = 0 int testsErrored = 0 int testsRun = 0 - + List reportTestsFailed = newArrayList + + public static String FINAL_SEPARATOR = "=====================================================================================================" + override testsToRun(String suiteName, WFile file, List tests) { AnsiConsole.systemInstall if (suiteName ?: '' !== '') { @@ -50,14 +55,8 @@ class WollokConsoleTestsReporter extends DefaultWollokTestsReporter { override reportTestAssertError(WTest test, AssertionException assertionError, int lineNumber, URI resource) { test.testFinished incrementTestsFailed - println(ansi - .a(" ").fg(YELLOW).a(test.name).a(": ✗ FAILED (").a(test.totalTime).a("ms) => ").reset - .fg(YELLOW).a(assertionError.message).reset - .fg(YELLOW).a(" (").a(resource.trimFragment).a(":").a(lineNumber).a(")").reset - .a("\n ") - .fg(YELLOW).a(assertionError.wollokException?.convertStackTrace.join("\n ")).reset - .a("\n") - ) + test.printAssertionException(assertionError, lineNumber, resource) + reportTestsFailed.add(new WTestFailed(test, assertionError, null, lineNumber, resource)) } override reportTestOk(WTest test) { @@ -68,17 +67,30 @@ class WollokConsoleTestsReporter extends DefaultWollokTestsReporter { override reportTestError(WTest test, Exception exception, int lineNumber, URI resource) { test.testFinished incrementTestsErrored - println(ansi.a(" ").fg(RED).a(test.name).a(": ✗ ERRORED (").a(test.totalTime).a("ms) => ").reset - .fg(RED).a(exception.convertToString).reset - .a("\n ").fg(RED).a(exception.convertStackTrace.join("\n ")).reset - .a("\n") - ) + test.printException(exception, lineNumber, resource) + reportTestsFailed.add(new WTestFailed(test, null, exception, lineNumber, resource)) } override finished() { super.finished - printTestsResults(totalTestsRun, totalTestsFailed, totalTestsErrored, overallTimeElapsedInMilliseconds) + val ok = overallProcessWasOK + ok.printSeparator + val STATUS = if (ok) GREEN else RED + println(ansi + .fg(STATUS) + .bold + .a("FINAL REPORT") + .reset + ) + if (!ok) { + printTestsFailed + } + println() + printTestsResults(totalTestsRun, totalTestsFailed, totalTestsErrored, overallTimeElapsedInMilliseconds) + println() + ok.printSeparator + resetGroupTestsCount if (!ok) throw new WollokTestsFailedException } @@ -137,4 +149,60 @@ class WollokConsoleTestsReporter extends DefaultWollokTestsReporter { ) AnsiConsole.systemUninstall } + + private def printAssertionException(WTest test, AssertionException assertionError, int lineNumber, URI resource) { + println(ansi + .a(" ").fg(YELLOW).a(test.name).a(": ✗ FAILED (").a(test.totalTime).a("ms) => ").reset + .fg(YELLOW).a(assertionError.message).reset + .fg(YELLOW).a(" (").a(resource.trimFragment).a(":").a(lineNumber).a(")").reset + .a("\n ") + .fg(YELLOW).a(assertionError.wollokException?.convertStackTrace.join("\n ")).reset + .a("\n") + ) + } + + private def printException(WTest test, Exception exception, int lineNumber, URI resource) { + println(ansi.a(" ").fg(RED).a(test.name).a(": ✗ ERRORED (").a(test.totalTime).a("ms) => ").reset + .fg(RED).a(exception.convertToString).reset + .a("\n ").fg(RED).a(exception.convertStackTrace.join("\n ")).reset + .a("\n") + ) + } + + private def printSeparator(boolean ok) { + val STATUS = if (ok) GREEN else RED + println(ansi + .fg(STATUS) + .bold + .a(FINAL_SEPARATOR) + .a("\n") + .reset + ) + } + + private def printTestsFailed() { + println(ansi + .fg(RED) + .a("\n") + ) + reportTestsFailed.forEach [ + if (assertionOrigin) test.printAssertionException(assertionException, lineNumber, resource) + else test.printException(exception, lineNumber, resource) + ] + } + } + +@Accessors +@Data +class WTestFailed { + WTest test + AssertionException assertionException + Exception exception + int lineNumber + URI resource + + def isAssertionOrigin() { + assertionException !== null + } +} \ No newline at end of file From 98a707739e93dfe6e0931814e957f52ba34e945d Mon Sep 17 00:00:00 2001 From: Fernando Dodino Date: Sun, 13 Oct 2019 00:44:25 -0300 Subject: [PATCH 019/133] Deleting Referenciable from message errors --- .../interpreter/namedobjects/NamedObjectTestCase.xtend | 2 +- .../wollok/tests/xpect/CheckVarReferences.wpgm.xt | 8 ++++---- .../wollok/tests/xpect/ConstructorAndConsts.wlk.xt | 2 +- .../project/wollok/tests/xpect/NamedParameters.wlk.xt | 6 +++--- .../xpect/parserErrors/MisplacedInstanceVariable.wlk.xt | 2 +- .../wollok/errorHandling/HumanReadableUtils.xtend | 9 +++++---- .../linking/WollokLinkingDiagnosticMessageProvider.xtend | 4 +++- 7 files changed, 18 insertions(+), 15 deletions(-) diff --git a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/namedobjects/NamedObjectTestCase.xtend b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/namedobjects/NamedObjectTestCase.xtend index 9a97787e75..7e31ecaf8e 100644 --- a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/namedobjects/NamedObjectTestCase.xtend +++ b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/namedobjects/NamedObjectTestCase.xtend @@ -51,7 +51,7 @@ class NamedObjectTestCase extends AbstractWollokInterpreterTestCase { fail("Linking should have failed, 'n' from class Pepe shouldn't have been resolved !") } catch (AssertionError e) { - assertTrue(e.message.startsWith("Expected no errors, but got :ERROR (org.eclipse.xtext.diagnostics.Diagnostic.Linking) 'Couldn't resolve reference to Referenciable 'n'.' on WVariableReference")) + assertTrue(e.message.startsWith("Expected no errors, but got :ERROR (org.eclipse.xtext.diagnostics.Diagnostic.Linking) 'Couldn't resolve reference to 'n'.' on WVariableReference")) } } diff --git a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/xpect/CheckVarReferences.wpgm.xt b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/xpect/CheckVarReferences.wpgm.xt index 5f32d14e61..7d8ea79a11 100644 --- a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/xpect/CheckVarReferences.wpgm.xt +++ b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/xpect/CheckVarReferences.wpgm.xt @@ -4,19 +4,19 @@ program p { // XPECT warnings --> "Unused variable" at "a" const a = 23 - // XPECT errors --> "Couldn't resolve reference to Referenciable 'x'." at "x" + // XPECT errors --> "Couldn't resolve reference to 'x'." at "x" console.println(x) // XPECT warnings --> "Unused variable" at "objetin" const objetin = object { var l = "ele" method algoConLYZNoExiste() { - // XPECT errors --> "Couldn't resolve reference to Referenciable 'z'." at "z" + // XPECT errors --> "Couldn't resolve reference to 'z'." at "z" l = l + z /* XPECT errors --- - "Couldn't resolve reference to Referenciable 'z'." at "z" - "Couldn't resolve reference to Referenciable 'z'." at "z" + "Couldn't resolve reference to 'z'." at "z" + "Couldn't resolve reference to 'z'." at "z" --- */ z = z + 1 // z no existe ! } diff --git a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/xpect/ConstructorAndConsts.wlk.xt b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/xpect/ConstructorAndConsts.wlk.xt index 0528770314..cfcde2f05a 100644 --- a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/xpect/ConstructorAndConsts.wlk.xt +++ b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/xpect/ConstructorAndConsts.wlk.xt @@ -48,7 +48,7 @@ class A { constructor(e) { energia = e } method energia() = energia - // XPECT errors --> "Couldn't resolve reference to Referenciable 'e'." at "e" + // XPECT errors --> "Couldn't resolve reference to 'e'." at "e" method setEnergia() { energia = e } } diff --git a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/xpect/NamedParameters.wlk.xt b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/xpect/NamedParameters.wlk.xt index a67511da26..dff0fc2418 100644 --- a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/xpect/NamedParameters.wlk.xt +++ b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/xpect/NamedParameters.wlk.xt @@ -88,7 +88,7 @@ class Villano inherits AntiHeroe { class ReVillano inherits AntiHeroe { var nivelMaldad /* XPECT errors --- - "Couldn't resolve reference to Referenciable 'ciudadesQueAma'." at "ciudadesQueAma" + "Couldn't resolve reference to 'ciudadesQueAma'." at "ciudadesQueAma" "Named parameters are not allowed here" at "ciudadesQueAma = ["New York"]" --- */ constructor(_fraseCabecera) = super(ciudadesQueAma = ["New York"]) { @@ -106,14 +106,14 @@ class A { a = _a } /* XPECT errors --- - "Couldn't resolve reference to Referenciable '_a'." at "_a" + "Couldn't resolve reference to '_a'." at "_a" "Named parameters are not allowed here" at "_a = x" --- */ constructor(x, y) = self(_a = x) { b = y } /* XPECT errors --- - "Couldn't resolve reference to Referenciable 'inexistente'." at "inexistente" + "Couldn't resolve reference to 'inexistente'." at "inexistente" "Named parameters are not allowed here" at "x = y, inexistente = 3" --- */ constructor(x, y, z) = self(x = y, inexistente = 3) { diff --git a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/xpect/parserErrors/MisplacedInstanceVariable.wlk.xt b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/xpect/parserErrors/MisplacedInstanceVariable.wlk.xt index 2ca94dadbb..69996a5e93 100644 --- a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/xpect/parserErrors/MisplacedInstanceVariable.wlk.xt +++ b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/xpect/parserErrors/MisplacedInstanceVariable.wlk.xt @@ -1,6 +1,6 @@ /* XPECT_SETUP org.uqbar.project.wollok.tests.xpect.WollokXPectTest END_SETUP */ class Golondrina { - // XPECT errors --> "Couldn't resolve reference to Referenciable 'energia'." at "energia" + // XPECT errors --> "Couldn't resolve reference to 'energia'." at "energia" method energia() = energia // XPECT! errors --> "You should declare references before constructors, methods and tests." at "var" diff --git a/org.uqbar.project.wollok/src/org/uqbar/project/wollok/errorHandling/HumanReadableUtils.xtend b/org.uqbar.project.wollok/src/org/uqbar/project/wollok/errorHandling/HumanReadableUtils.xtend index ec3ce52cb6..ad2c4a9df6 100644 --- a/org.uqbar.project.wollok/src/org/uqbar/project/wollok/errorHandling/HumanReadableUtils.xtend +++ b/org.uqbar.project.wollok/src/org/uqbar/project/wollok/errorHandling/HumanReadableUtils.xtend @@ -13,7 +13,6 @@ import org.uqbar.project.wollok.wollokDsl.WMethodContainer import org.uqbar.project.wollok.wollokDsl.WMethodDeclaration import org.uqbar.project.wollok.wollokDsl.WNamedObject import org.uqbar.project.wollok.wollokDsl.WObjectLiteral -import org.uqbar.project.wollok.wollokDsl.WReferenciable import org.uqbar.project.wollok.wollokDsl.WVariableDeclaration import static extension org.uqbar.project.wollok.model.WMethodContainerExtensions.* @@ -29,14 +28,16 @@ class HumanReadableUtils { // ************************************************************************ // default: removes the "W" prefix and uses the class name - def static dispatch modelTypeDescription(EObject it) { eClass.modelTypeName } def static dispatch modelTypeDescription(WNamedObject it) { "Object" } def static dispatch modelTypeDescription(WObjectLiteral it) { "Object" } def static dispatch modelTypeDescription(WMethodDeclaration it) { "Method" } def static dispatch modelTypeDescription(WVariableDeclaration it) { if (writeable) "Variable" else "Constant" } + def static dispatch modelTypeDescription(EObject it) { eClass.modelTypeName } - def static modelTypeName(WReferenciable it) { "reference " + name } - def static modelTypeName(EClass it) { if(name.startsWith("W")) name.substring(1) else name } + def static modelTypeName(EClass it) { + if (name.equals("WReferenciable")) return "" + if (name.startsWith("W")) name.substring(1) else name + } // ************************************************************************ diff --git a/org.uqbar.project.wollok/src/org/uqbar/project/wollok/linking/WollokLinkingDiagnosticMessageProvider.xtend b/org.uqbar.project.wollok/src/org/uqbar/project/wollok/linking/WollokLinkingDiagnosticMessageProvider.xtend index 1664872de8..13ede7826a 100644 --- a/org.uqbar.project.wollok/src/org/uqbar/project/wollok/linking/WollokLinkingDiagnosticMessageProvider.xtend +++ b/org.uqbar.project.wollok/src/org/uqbar/project/wollok/linking/WollokLinkingDiagnosticMessageProvider.xtend @@ -37,7 +37,9 @@ class WollokLinkingDiagnosticMessageProvider extends LinkingDiagnosticMessagePro } } if (msg.equals("")) { - msg = LINKING_COULD_NOT_RESOLVE_REFERENCE + referenceType.modelTypeName + " '" + linkText + "'." + val modelTypeName = referenceType.modelTypeName + val separator = if (modelTypeName === "") "" else " " + msg = LINKING_COULD_NOT_RESOLVE_REFERENCE + modelTypeName + separator + "'" + linkText + "'." } new DiagnosticMessage(msg, Severity.ERROR, Diagnostic.LINKING_DIAGNOSTIC) } From 102b1700493715e4d18f6ef30473e456f7bc2850 Mon Sep 17 00:00:00 2001 From: Fernando Dodino Date: Tue, 15 Oct 2019 01:47:11 -0300 Subject: [PATCH 020/133] First step : refactoring WollokQualifiedName -> 3 TS tests failing --- .../project/wollok/launch/WollokChecker.xtend | 2 +- .../wollok/wollokDoc/WollokDocParser.xtend | 2 +- .../tests/interpreter/WollokParseHelper.xtend | 22 ++++++++++++++----- .../interpreter/imports/ImportsTest.xtend | 22 +++++++++++++++++-- .../AbstractWollokTypeSystemTestCase.xtend | 4 +++- .../classes/StaticDiagramConfiguration.xtend | 7 +++--- .../wollok/ui/console/WollokReplConsole.xtend | 2 +- .../AddNewElementQuickFixDialog.xtend | 11 +++++----- .../objects/NewWollokObjectsWizardPage.xtend | 6 ++--- .../project/wollok/WollokConstants.xtend | 2 +- .../project/wollok/model/ResourceUtils.xtend | 20 +++++++++++++++-- .../wollok/model/WollokModelExtensions.xtend | 6 +++-- .../scoping/WollokGlobalScopeProvider.xtend | 21 +++++++++++------- ...rtedNamespaceAwareLocalScopeProvider.xtend | 7 ++---- .../scoping/WollokQualifiedNameProvider.xtend | 6 +++-- .../project/wollok/utils/StringUtils.xtend | 5 ++++- .../project/wollok/utils/WEclipseUtils.xtend | 2 +- 17 files changed, 101 insertions(+), 46 deletions(-) diff --git a/org.uqbar.project.wollok.launch/src/org/uqbar/project/wollok/launch/WollokChecker.xtend b/org.uqbar.project.wollok.launch/src/org/uqbar/project/wollok/launch/WollokChecker.xtend index 9c3d28c456..e5da98abde 100644 --- a/org.uqbar.project.wollok.launch/src/org/uqbar/project/wollok/launch/WollokChecker.xtend +++ b/org.uqbar.project.wollok.launch/src/org/uqbar/project/wollok/launch/WollokChecker.xtend @@ -140,7 +140,7 @@ class WollokChecker { def void collectWollokFiles(File folder, List classpath) { classpath.addAll( folder.listFiles [ dir, name | - name.endsWith("." + WollokConstants.CLASS_OBJECTS_EXTENSION) || + name.endsWith("." + WollokConstants.WOLLOK_DEFINITION_EXTENSION) || name.endsWith("." + WollokConstants.PROGRAM_EXTENSION) || name.endsWith("." + WollokConstants.TEST_EXTENSION) ]) diff --git a/org.uqbar.project.wollok.launch/src/org/uqbar/project/wollok/wollokDoc/WollokDocParser.xtend b/org.uqbar.project.wollok.launch/src/org/uqbar/project/wollok/wollokDoc/WollokDocParser.xtend index a6eb4b5840..01250b286a 100644 --- a/org.uqbar.project.wollok.launch/src/org/uqbar/project/wollok/wollokDoc/WollokDocParser.xtend +++ b/org.uqbar.project.wollok.launch/src/org/uqbar/project/wollok/wollokDoc/WollokDocParser.xtend @@ -156,7 +156,7 @@ class WollokDocParser extends WollokChecker { } def String toHtmlFile(String fileName) { - fileName.replace(WollokConstants.CLASS_OBJECTS_EXTENSION, "html") + fileName.replace(WollokConstants.WOLLOK_DEFINITION_EXTENSION, "html") } def String libraryName(String fileName) { diff --git a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/WollokParseHelper.xtend b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/WollokParseHelper.xtend index 8c8c202340..3c08c228ed 100644 --- a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/WollokParseHelper.xtend +++ b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/WollokParseHelper.xtend @@ -20,13 +20,23 @@ class WollokParseHelper extends ParseHelper{ parse(file, resourceSetToUse, false) } + override def parse(CharSequence text, ResourceSet resourceSetToUse) throws Exception { + text.toString.computeFileExtension + return super.parse(getAsStream(text), computeUnusedUri(resourceSetToUse), null, resourceSetToUse); + } + + def void computeFileExtension(String fileContent) { + this.fileExtension = + if (fileContent.toString.contains("program ")) + WollokConstants.PROGRAM_EXTENSION + else if (fileContent.toString.contains("test ")) + WollokConstants.TEST_EXTENSION + else + WollokConstants.WOLLOK_DEFINITION_EXTENSION + } + def WFile parse(Pair file, ResourceSet resourceSetToUse, boolean createFilesOnDisk) throws Exception { - this.fileExtension = if (file.value.toString.contains("program ")) - WollokConstants.PROGRAM_EXTENSION - else if (file.value.toString.contains("test ")) - WollokConstants.TEST_EXTENSION - else - WollokConstants.CLASS_OBJECTS_EXTENSION + file.value.computeFileExtension val uri = resourceSetToUse.calculateUriFor(file).trimFileExtension.appendFileExtension(fileExtension) if (createFilesOnDisk) { diff --git a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/imports/ImportsTest.xtend b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/imports/ImportsTest.xtend index 5204c5b86f..42fc2dc9a6 100644 --- a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/imports/ImportsTest.xtend +++ b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/imports/ImportsTest.xtend @@ -1,8 +1,8 @@ package org.uqbar.project.wollok.tests.interpreter.imports -import org.uqbar.project.wollok.tests.interpreter.AbstractWollokInterpreterTestCase -import org.junit.Test import org.junit.Ignore +import org.junit.Test +import org.uqbar.project.wollok.tests.interpreter.AbstractWollokInterpreterTestCase /** * Test the different combinations and functionality of imports. @@ -126,6 +126,24 @@ class ImportsTest extends AbstractWollokInterpreterTestCase { ].interpretAsFilesPropagatingErrors } + @Test + def void testSameNameTestAndWlk() { + try { + #['aves' -> ''' + object pepita { + method energia() = 1 + } + ''', + 'aves' -> ''' + test "pepita energia" { + assert.equals(pepita.energia(), 1) + } + ''' + ].interpretAsFilesPropagatingErrors + fail("Should have failed missing import to pepita") + } catch (AssertionError e) { + } + } @Test def void testMultipleObjectsImports() { diff --git a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/typesystem/AbstractWollokTypeSystemTestCase.xtend b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/typesystem/AbstractWollokTypeSystemTestCase.xtend index 126c5e289b..8cc454fddf 100644 --- a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/typesystem/AbstractWollokTypeSystemTestCase.xtend +++ b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/typesystem/AbstractWollokTypeSystemTestCase.xtend @@ -71,7 +71,9 @@ abstract class AbstractWollokTypeSystemTestCase extends AbstractWollokParameteri } def parseAndInferAll(CharSequence... files) { - (files.map[parse(resourceSet)].clone => [ + (files.map[ + parse(resourceSet) + ].clone => [ forEach[validate] forEach[analyse] inferTypes diff --git a/org.uqbar.project.wollok.ui.diagrams/src/org/uqbar/project/wollok/ui/diagrams/classes/StaticDiagramConfiguration.xtend b/org.uqbar.project.wollok.ui.diagrams/src/org/uqbar/project/wollok/ui/diagrams/classes/StaticDiagramConfiguration.xtend index 419cba99e3..da41b34ce5 100644 --- a/org.uqbar.project.wollok.ui.diagrams/src/org/uqbar/project/wollok/ui/diagrams/classes/StaticDiagramConfiguration.xtend +++ b/org.uqbar.project.wollok.ui.diagrams/src/org/uqbar/project/wollok/ui/diagrams/classes/StaticDiagramConfiguration.xtend @@ -27,6 +27,7 @@ import org.uqbar.project.wollok.wollokDsl.WMethodContainer import static extension org.uqbar.project.wollok.model.WMethodContainerExtensions.* import static extension org.uqbar.project.wollok.model.WollokModelExtensions.* +import static extension org.uqbar.project.wollok.utils.StringUtils.* @Accessors abstract class AbstractDiagramConfiguration extends Observable { @@ -400,11 +401,11 @@ class StaticDiagramConfiguration extends AbstractDiagramConfiguration implements } def getStaticDiagramFileName() { - originalFileName.replace(WollokConstants.CLASS_OBJECTS_EXTENSION, WollokConstants.STATIC_DIAGRAM_EXTENSION) + originalFileName.replace(WollokConstants.WOLLOK_DEFINITION_EXTENSION, WollokConstants.STATIC_DIAGRAM_EXTENSION) } def resourceCanBeUsed() { - fullPath !== null && !fullPath.equals("") && originalFileName !== null && !originalFileName.equals("") && originalFileName.endsWith(WollokConstants.CLASS_OBJECTS_EXTENSION) + fullPath.notEmpty && originalFileName.notEmpty && originalFileName.endsWith(WollokConstants.WOLLOK_DEFINITION_EXTENSION) } /** @@ -443,7 +444,7 @@ class StaticDiagramConfiguration extends AbstractDiagramConfiguration implements } def resourceIsForStaticDiagram() { - originalFileName.endsWith(WollokConstants.CLASS_OBJECTS_EXTENSION) + originalFileName.endsWith(WollokConstants.WOLLOK_DEFINITION_EXTENSION) } } diff --git a/org.uqbar.project.wollok.ui.launch/src/org/uqbar/project/wollok/ui/console/WollokReplConsole.xtend b/org.uqbar.project.wollok.ui.launch/src/org/uqbar/project/wollok/ui/console/WollokReplConsole.xtend index d8697c5ffc..92f3b259d7 100644 --- a/org.uqbar.project.wollok.ui.launch/src/org/uqbar/project/wollok/ui/console/WollokReplConsole.xtend +++ b/org.uqbar.project.wollok.ui.launch/src/org/uqbar/project/wollok/ui/console/WollokReplConsole.xtend @@ -130,7 +130,7 @@ class WollokReplConsole extends TextConsole { } def hasMainFile() { - return fileName() !== null && fileName.endsWith("." + WollokConstants.CLASS_OBJECTS_EXTENSION) + return fileName() !== null && fileName.endsWith("." + WollokConstants.WOLLOK_DEFINITION_EXTENSION) } def fileName() { diff --git a/org.uqbar.project.wollok.ui/src/org/uqbar/project/wollok/ui/quickfix/AddNewElementQuickFixDialog.xtend b/org.uqbar.project.wollok.ui/src/org/uqbar/project/wollok/ui/quickfix/AddNewElementQuickFixDialog.xtend index fe32e2db69..146814e0c5 100644 --- a/org.uqbar.project.wollok.ui/src/org/uqbar/project/wollok/ui/quickfix/AddNewElementQuickFixDialog.xtend +++ b/org.uqbar.project.wollok.ui/src/org/uqbar/project/wollok/ui/quickfix/AddNewElementQuickFixDialog.xtend @@ -37,7 +37,6 @@ import org.eclipse.swt.widgets.Shell import org.eclipse.swt.widgets.Text import org.eclipse.xtext.resource.XtextResource import org.eclipse.xtext.ui.editor.model.edit.IModificationContext -import org.uqbar.project.wollok.WollokConstants import org.uqbar.project.wollok.ui.Messages import org.uqbar.project.wollok.ui.WollokActivator import org.uqbar.project.wollok.validation.ElementNameValidation @@ -189,7 +188,7 @@ class AddNewElementQuickFixDialog extends Dialog { ] new Label(fileNameComposite, SWT.LEFT) => [ - text = "." + WollokConstants.CLASS_OBJECTS_EXTENSION + text = "." + WOLLOK_DEFINITION_EXTENSION ] errorMessage = new Label(composite,SWT.CENTER.bitwiseOr(SWT.BORDER)) => [ @@ -237,7 +236,7 @@ class AddNewElementQuickFixDialog extends Dialog { ] treeWollokElements => [ // Show wollok files that have any valid method container - wollokFiles = project.allWollokFiles.filter [ it.fileExtension.equals(WollokConstants.CLASS_OBJECTS_EXTENSION) ].toList + wollokFiles = project.allWollokFiles.filter [ fileExtension.equals(WOLLOK_DEFINITION_EXTENSION) ].toList control.layoutData = new GridData(SWT.FILL, SWT.FILL, true, true, 1, 0) => [ heightHint = 220 widthHint = 250 @@ -295,7 +294,7 @@ class AddNewElementQuickFixDialog extends Dialog { } def getFullNewFileName() { - newFileName + "." + CLASS_OBJECTS_EXTENSION + newFileName + "." + WOLLOK_DEFINITION_EXTENSION } def getInputFileNameValidationMessage() { @@ -433,10 +432,10 @@ class WollokMethodContainerLabelProvider extends LabelProvider { def dispatch getImage(URI uri) { val fileExtension = uri.fileExtension - if (fileExtension.equals(WollokConstants.TEST_EXTENSION)) { + if (fileExtension.equals(TEST_EXTENSION)) { return showImage("wollok-icon-test_16.png") } - if (fileExtension.equals(WollokConstants.PROGRAM_EXTENSION)) { + if (fileExtension.equals(PROGRAM_EXTENSION)) { return showImage("wollok-icon-program_16.png") } return showImage("w.png") diff --git a/org.uqbar.project.wollok.ui/src/org/uqbar/project/wollok/ui/wizard/objects/NewWollokObjectsWizardPage.xtend b/org.uqbar.project.wollok.ui/src/org/uqbar/project/wollok/ui/wizard/objects/NewWollokObjectsWizardPage.xtend index 7cd2bf99ff..64c02ec739 100644 --- a/org.uqbar.project.wollok.ui/src/org/uqbar/project/wollok/ui/wizard/objects/NewWollokObjectsWizardPage.xtend +++ b/org.uqbar.project.wollok.ui/src/org/uqbar/project/wollok/ui/wizard/objects/NewWollokObjectsWizardPage.xtend @@ -8,11 +8,11 @@ import org.eclipse.swt.widgets.Composite import org.eclipse.swt.widgets.Label import org.eclipse.swt.widgets.Text import org.eclipse.xtend.lib.annotations.Accessors -import org.uqbar.project.wollok.WollokConstants import org.uqbar.project.wollok.ui.Messages import org.uqbar.project.wollok.ui.wizard.abstractWizards.AbstractNewWollokFileWizardPage import static extension org.uqbar.project.wollok.validation.ElementNameValidation.* +import static extension org.uqbar.project.wollok.WollokConstants.* class NewWollokObjectsWizardPage extends AbstractNewWollokFileWizardPage { Text elementNameText @@ -25,8 +25,8 @@ class NewWollokObjectsWizardPage extends AbstractNewWollokFileWizardPage { } override doInit() { - this.extension = WollokConstants.CLASS_OBJECTS_EXTENSION - this.initialFileName = "objects." + WollokConstants.CLASS_OBJECTS_EXTENSION //$NON-NLS-1$ + this.extension = WOLLOK_DEFINITION_EXTENSION + this.initialFileName = "objects." + WOLLOK_DEFINITION_EXTENSION //$NON-NLS-1$ this.title = Messages.NewWollokObjectsWizardPage_title this.description = Messages.NewWollokObjectsWizardPage_description } diff --git a/org.uqbar.project.wollok/src/org/uqbar/project/wollok/WollokConstants.xtend b/org.uqbar.project.wollok/src/org/uqbar/project/wollok/WollokConstants.xtend index 6fc5fe0bc7..950f2ddf72 100644 --- a/org.uqbar.project.wollok/src/org/uqbar/project/wollok/WollokConstants.xtend +++ b/org.uqbar.project.wollok/src/org/uqbar/project/wollok/WollokConstants.xtend @@ -17,7 +17,7 @@ class WollokConstants { public static val SOURCE_FOLDER = "src" public static val NATURE_ID = "org.uqbar.project.wollok.wollokNature" - public static val CLASS_OBJECTS_EXTENSION = "wlk" + public static val WOLLOK_DEFINITION_EXTENSION = "wlk" public static val PROGRAM_EXTENSION = "wpgm" public static val TEST_EXTENSION = "wtest" public static val STATIC_DIAGRAM_EXTENSION = "wsdi" diff --git a/org.uqbar.project.wollok/src/org/uqbar/project/wollok/model/ResourceUtils.xtend b/org.uqbar.project.wollok/src/org/uqbar/project/wollok/model/ResourceUtils.xtend index 54cf1375e8..5dd2ed061b 100644 --- a/org.uqbar.project.wollok/src/org/uqbar/project/wollok/model/ResourceUtils.xtend +++ b/org.uqbar.project.wollok/src/org/uqbar/project/wollok/model/ResourceUtils.xtend @@ -1,5 +1,6 @@ package org.uqbar.project.wollok.model +import java.util.Map import org.eclipse.core.resources.IFile import org.eclipse.core.resources.IResource import org.eclipse.core.resources.IWorkspace @@ -8,14 +9,20 @@ import org.eclipse.core.runtime.Path import org.eclipse.emf.ecore.EObject import org.eclipse.emf.ecore.resource.Resource -import static org.uqbar.project.wollok.scoping.root.WollokRootLocator.* import static org.uqbar.project.wollok.WollokConstants.* +import static org.uqbar.project.wollok.scoping.root.WollokRootLocator.* /** * Extension methods to Wollok semantic model related to files, resources and the Eclipse platform. */ class ResourceUtils { + public static Map implicitPackagePreffixes = #{ + WOLLOK_DEFINITION_EXTENSION -> "", + TEST_EXTENSION -> "t_", + PROGRAM_EXTENSION -> "p_" + } + def static getProject(EObject obj) { obj.IFile.project } def static IFile getIFile(EObject obj) { obj.eResource.IFile } @@ -52,7 +59,7 @@ class ResourceUtils { } def static implicitPackage(Resource it) { - if(it === null || it.URI === null || it.URI.toString === null) { + if(it === null || URI === null || URI.toString === null) { return null } if(URI.toString.startsWith(CLASSPATH)) @@ -60,4 +67,13 @@ class ResourceUtils { else fullPackageName(it) } + + def static implicitPackageForImport(Resource it) { + preffixPackage + implicitPackage + } + + def static preffixPackage(Resource it) { + (implicitPackagePreffixes.get(URI.fileExtension) ?: "") + } + } diff --git a/org.uqbar.project.wollok/src/org/uqbar/project/wollok/model/WollokModelExtensions.xtend b/org.uqbar.project.wollok/src/org/uqbar/project/wollok/model/WollokModelExtensions.xtend index bb2778c30b..64968138f5 100644 --- a/org.uqbar.project.wollok/src/org/uqbar/project/wollok/model/WollokModelExtensions.xtend +++ b/org.uqbar.project.wollok/src/org/uqbar/project/wollok/model/WollokModelExtensions.xtend @@ -88,8 +88,10 @@ import static extension org.uqbar.project.wollok.visitors.ReturnFinderVisitor.co */ class WollokModelExtensions { - def static implicitPackage(EObject it) { file.implicitPackage } - + def static implicitPackage(EObject it) { + file.implicitPackage + } + def static file(EObject it) { eResource } def static boolean isException(WClass it) { fqn == Exception.name || (parent !== null && parent.exception) } diff --git a/org.uqbar.project.wollok/src/org/uqbar/project/wollok/scoping/WollokGlobalScopeProvider.xtend b/org.uqbar.project.wollok/src/org/uqbar/project/wollok/scoping/WollokGlobalScopeProvider.xtend index 18e9579cd3..4b607fe91d 100644 --- a/org.uqbar.project.wollok/src/org/uqbar/project/wollok/scoping/WollokGlobalScopeProvider.xtend +++ b/org.uqbar.project.wollok/src/org/uqbar/project/wollok/scoping/WollokGlobalScopeProvider.xtend @@ -92,18 +92,23 @@ class WollokGlobalScopeProvider extends DefaultGlobalScopeProvider { def synchronized objectsFromLocalImport(Resource context, Iterable importsEntry, Iterable objectsFromManifests) { - val imports = (importsEntry.map[#[it] + localScopeProvider.allRelativeImports(it, context.implicitPackage)]. - flatten).toSet + val imports = (importsEntry + .map[ + #[it] + localScopeProvider.allRelativeImports(it, context.implicitPackage) + ] + .flatten + ).toSet val importedObjects = imports.filter [ it !== null && !objectsFromManifests.exists[o|o.matchesImport(it)] ].map [ toResource(context) - ].filter[it !== null].map [ r | + ].filter[ + it !== null + ].map [ r | resourceDescriptionManager.getResourceDescription(r).exportedObjects ].flatten + objectsFromManifests importedObjects - } def matchesImport(IEObjectDescription o, String importedNamespace) { @@ -111,7 +116,7 @@ class WollokGlobalScopeProvider extends DefaultGlobalScopeProvider { val pattern = importedNamespace.substring(0, importedNamespace.length - 2) o.qualifiedName.toString.startsWith(pattern) } else { - o.qualifiedName.toString == importedNamespace + o.qualifiedName.toString === importedNamespace } } @@ -123,7 +128,6 @@ class WollokGlobalScopeProvider extends DefaultGlobalScopeProvider { try { var uri = generateUri(resource, importedNamespace) if(uri === null) return null - EcoreUtil2.getResource(resource, uri) } catch (RuntimeException e) { throw new WollokRuntimeException(NLS.bind(Messages.WollokScopeProvider_unresolvedImport, importedNamespace), e) @@ -146,7 +150,7 @@ class WollokGlobalScopeProvider extends DefaultGlobalScopeProvider { var newUri = uri while (newUri.segmentCount >= 1) { - val fileURI = newUri.appendFileExtension(CLASS_OBJECTS_EXTENSION) + val fileURI = newUri.appendFileExtension(WOLLOK_DEFINITION_EXTENSION) if (fileURI.exists(context)) { return fileURI.toString @@ -155,7 +159,7 @@ class WollokGlobalScopeProvider extends DefaultGlobalScopeProvider { newUri = newUri.trimSegments(1) } - uri.appendFileExtension(CLASS_OBJECTS_EXTENSION).toString + uri.appendFileExtension(WOLLOK_DEFINITION_EXTENSION).toString } def static Boolean exists(URI fileURI, Resource context) { @@ -167,4 +171,5 @@ class WollokGlobalScopeProvider extends DefaultGlobalScopeProvider { false } } + } diff --git a/org.uqbar.project.wollok/src/org/uqbar/project/wollok/scoping/WollokImportedNamespaceAwareLocalScopeProvider.xtend b/org.uqbar.project.wollok/src/org/uqbar/project/wollok/scoping/WollokImportedNamespaceAwareLocalScopeProvider.xtend index 564468585a..9a0b5efc52 100644 --- a/org.uqbar.project.wollok/src/org/uqbar/project/wollok/scoping/WollokImportedNamespaceAwareLocalScopeProvider.xtend +++ b/org.uqbar.project.wollok/src/org/uqbar/project/wollok/scoping/WollokImportedNamespaceAwareLocalScopeProvider.xtend @@ -21,13 +21,12 @@ import org.eclipse.xtext.scoping.impl.MultimapBasedSelectable import org.eclipse.xtext.util.OnChangeEvictingCache import static java.util.Collections.singletonList +import static org.uqbar.project.wollok.libraries.WollokLibExtensions.* import static extension org.uqbar.project.wollok.model.WollokModelExtensions.* import static extension org.uqbar.project.wollok.scoping.WollokScopeExtensions.* import static extension org.uqbar.project.wollok.utils.XtendExtensions.* -import static extension org.uqbar.project.wollok.libraries.WollokLibExtensions.* - /** * @author tesonep * @author jfernandes @@ -50,7 +49,6 @@ class WollokImportedNamespaceAwareLocalScopeProvider extends AbstractGlobalScope synchronized(context.eResource) synchronized(context.eResource.resourceSet) context.computeScope(reference) - } def Iterable allRelativeImports(String importedNamespace, EObject context) { @@ -88,8 +86,7 @@ class WollokImportedNamespaceAwareLocalScopeProvider extends AbstractGlobalScope protected def localElementsScope(EObject context, IScope parent, EReference reference) { val name = qualifiedNameProvider.getFullyQualifiedName(context) - - if(name !== null) { + if (name !== null) { val localNormalizer = new ImportNormalizer(name, true, reference.isIgnoreCase) createImportScope(parent, singletonList(localNormalizer), null, reference.EReferenceType) } else diff --git a/org.uqbar.project.wollok/src/org/uqbar/project/wollok/scoping/WollokQualifiedNameProvider.xtend b/org.uqbar.project.wollok/src/org/uqbar/project/wollok/scoping/WollokQualifiedNameProvider.xtend index 4944ec870a..6ddbc23fac 100644 --- a/org.uqbar.project.wollok/src/org/uqbar/project/wollok/scoping/WollokQualifiedNameProvider.xtend +++ b/org.uqbar.project.wollok/src/org/uqbar/project/wollok/scoping/WollokQualifiedNameProvider.xtend @@ -9,7 +9,7 @@ import org.uqbar.project.wollok.wollokDsl.WConstructor import org.uqbar.project.wollok.wollokDsl.WFile import org.uqbar.project.wollok.wollokDsl.WObjectLiteral -import static extension org.uqbar.project.wollok.model.WollokModelExtensions.* +import static extension org.uqbar.project.wollok.model.ResourceUtils.* /** * Customizes FQN named provider for @@ -34,7 +34,9 @@ class WollokQualifiedNameProvider extends DefaultDeclarativeQualifiedNameProvide } def qualifiedName(WFile ele) { - QualifiedName.create(ele.implicitPackage.split("\\.")) + println("file " + ele.eResource.URI) + println(QualifiedName.create(ele.eResource.implicitPackageForImport.split("\\."))) + QualifiedName.create(ele.eResource.implicitPackageForImport.split("\\.")) } def qualifiedName(WConstructor c) { diff --git a/org.uqbar.project.wollok/src/org/uqbar/project/wollok/utils/StringUtils.xtend b/org.uqbar.project.wollok/src/org/uqbar/project/wollok/utils/StringUtils.xtend index 8f4f759351..7a8bffae0c 100644 --- a/org.uqbar.project.wollok/src/org/uqbar/project/wollok/utils/StringUtils.xtend +++ b/org.uqbar.project.wollok/src/org/uqbar/project/wollok/utils/StringUtils.xtend @@ -62,5 +62,8 @@ class StringUtils { static def singularOrPlural(int amount, String text, String pluralText) { if (amount === 1) text else pluralText } - + + static def boolean notEmpty(String value) { + value !== null && !value.equals("") + } } diff --git a/org.uqbar.project.wollok/src/org/uqbar/project/wollok/utils/WEclipseUtils.xtend b/org.uqbar.project.wollok/src/org/uqbar/project/wollok/utils/WEclipseUtils.xtend index 213d7633af..29433ab9a9 100644 --- a/org.uqbar.project.wollok/src/org/uqbar/project/wollok/utils/WEclipseUtils.xtend +++ b/org.uqbar.project.wollok/src/org/uqbar/project/wollok/utils/WEclipseUtils.xtend @@ -228,7 +228,7 @@ class WEclipseUtils { } def static isWollokExtension(IResource file) { - #[PROGRAM_EXTENSION, TEST_EXTENSION, CLASS_OBJECTS_EXTENSION].contains(file.fileExtension) + #[PROGRAM_EXTENSION, TEST_EXTENSION, WOLLOK_DEFINITION_EXTENSION].contains(file.fileExtension) } def static dispatch String getFullPath(Object o) { "" } From 1159eb13046bd441ba6ffd070f83fc702cef05fa Mon Sep 17 00:00:00 2001 From: Fernando Dodino Date: Tue, 15 Oct 2019 09:43:59 -0300 Subject: [PATCH 021/133] Fixing tests --- .../wollok/tests/interpreter/WollokParseHelper.xtend | 5 ++++- .../src/org/uqbar/project/wollok/model/ResourceUtils.xtend | 7 ++++++- .../wollok/scoping/WollokQualifiedNameProvider.xtend | 2 -- 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/WollokParseHelper.xtend b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/WollokParseHelper.xtend index 3c08c228ed..c39885701f 100644 --- a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/WollokParseHelper.xtend +++ b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/WollokParseHelper.xtend @@ -10,6 +10,8 @@ import org.uqbar.project.wollok.wollokDsl.WFile /** * * @author tesonep + * @author dodain ==> parse(CharSequence, ResourceSet) modified for issue #1815 (.wlk / .wtest / .wpgm same file name) + * */ class WollokParseHelper extends ParseHelper{ @@ -22,7 +24,8 @@ class WollokParseHelper extends ParseHelper{ override def parse(CharSequence text, ResourceSet resourceSetToUse) throws Exception { text.toString.computeFileExtension - return super.parse(getAsStream(text), computeUnusedUri(resourceSetToUse), null, resourceSetToUse); + val uri = computeUnusedUri(resourceSetToUse).trimFileExtension.appendFileExtension(fileExtension) + return super.parse(getAsStream(text), uri, null, resourceSetToUse) } def void computeFileExtension(String fileContent) { diff --git a/org.uqbar.project.wollok/src/org/uqbar/project/wollok/model/ResourceUtils.xtend b/org.uqbar.project.wollok/src/org/uqbar/project/wollok/model/ResourceUtils.xtend index 5dd2ed061b..dff6e77447 100644 --- a/org.uqbar.project.wollok/src/org/uqbar/project/wollok/model/ResourceUtils.xtend +++ b/org.uqbar.project.wollok/src/org/uqbar/project/wollok/model/ResourceUtils.xtend @@ -8,6 +8,7 @@ import org.eclipse.core.resources.ResourcesPlugin import org.eclipse.core.runtime.Path import org.eclipse.emf.ecore.EObject import org.eclipse.emf.ecore.resource.Resource +import org.eclipse.emf.common.util.URI import static org.uqbar.project.wollok.WollokConstants.* import static org.uqbar.project.wollok.scoping.root.WollokRootLocator.* @@ -73,7 +74,11 @@ class ResourceUtils { } def static preffixPackage(Resource it) { - (implicitPackagePreffixes.get(URI.fileExtension) ?: "") + URI.preffixForImport + } + + def static preffixForImport(URI uri) { + implicitPackagePreffixes.get(uri.fileExtension) ?: "" } } diff --git a/org.uqbar.project.wollok/src/org/uqbar/project/wollok/scoping/WollokQualifiedNameProvider.xtend b/org.uqbar.project.wollok/src/org/uqbar/project/wollok/scoping/WollokQualifiedNameProvider.xtend index 6ddbc23fac..79f8c1ba5f 100644 --- a/org.uqbar.project.wollok/src/org/uqbar/project/wollok/scoping/WollokQualifiedNameProvider.xtend +++ b/org.uqbar.project.wollok/src/org/uqbar/project/wollok/scoping/WollokQualifiedNameProvider.xtend @@ -34,8 +34,6 @@ class WollokQualifiedNameProvider extends DefaultDeclarativeQualifiedNameProvide } def qualifiedName(WFile ele) { - println("file " + ele.eResource.URI) - println(QualifiedName.create(ele.eResource.implicitPackageForImport.split("\\."))) QualifiedName.create(ele.eResource.implicitPackageForImport.split("\\.")) } From 6950388a8c4868330dee1731e3db3a8dd0820173 Mon Sep 17 00:00:00 2001 From: Fernando Dodino Date: Wed, 16 Oct 2019 09:14:37 -0300 Subject: [PATCH 022/133] Quick Fix => shouldn't allow to add existing classes/wkos from a test/program file --- .../org/uqbar/project/wollok/model/WollokModelExtensions.xtend | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/org.uqbar.project.wollok/src/org/uqbar/project/wollok/model/WollokModelExtensions.xtend b/org.uqbar.project.wollok/src/org/uqbar/project/wollok/model/WollokModelExtensions.xtend index 64968138f5..4fc500a722 100644 --- a/org.uqbar.project.wollok/src/org/uqbar/project/wollok/model/WollokModelExtensions.xtend +++ b/org.uqbar.project.wollok/src/org/uqbar/project/wollok/model/WollokModelExtensions.xtend @@ -771,7 +771,7 @@ class WollokModelExtensions { def static isValidImport(IEObjectDescription element) { val fqn = element.name.toString - fqn.importRequired && !NON_IMPLICIT_IMPORTS.exists[it.equals(fqn)] && element.EObjectOrProxy.container !== null + fqn.importRequired && !NON_IMPLICIT_IMPORTS.exists[it.equals(fqn)] && element.EObjectURI.fileExtension.equals(WOLLOK_DEFINITION_EXTENSION) && element.EObjectOrProxy.container !== null } // ******************************* From 97e3d72138f7b27745b16adcb43473779fa2dd8f Mon Sep 17 00:00:00 2001 From: Fernando Dodino Date: Fri, 18 Oct 2019 10:05:42 -0300 Subject: [PATCH 023/133] Fix #1830 - formatter conflicts --- .../formatters.launch | 23 +++++++++++++++++++ .../AbstractWollokFormatterTestCase.xtend | 2 +- .../formatter/TestingFormatterTestCase.xtend | 1 + .../formatting2/WollokDslFormatter.xtend | 12 ++-------- 4 files changed, 27 insertions(+), 11 deletions(-) create mode 100644 org.uqbar.project.wollok.tests/formatters.launch diff --git a/org.uqbar.project.wollok.tests/formatters.launch b/org.uqbar.project.wollok.tests/formatters.launch new file mode 100644 index 0000000000..45004a7cde --- /dev/null +++ b/org.uqbar.project.wollok.tests/formatters.launch @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + + + + + + + + diff --git a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/formatter/AbstractWollokFormatterTestCase.xtend b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/formatter/AbstractWollokFormatterTestCase.xtend index 38e6655b49..c10bad3d21 100644 --- a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/formatter/AbstractWollokFormatterTestCase.xtend +++ b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/formatter/AbstractWollokFormatterTestCase.xtend @@ -20,7 +20,7 @@ class AbstractWollokFormatterTestCase { @Inject protected extension ISerializer def assertFormatting(String program, String expected) { - //program.parse.eContents.show(1) + // program.parse.eContents.show(1) Assert.assertEquals(expected, program.parse.serialize(SaveOptions.newBuilder.format().getOptions())) } diff --git a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/formatter/TestingFormatterTestCase.xtend b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/formatter/TestingFormatterTestCase.xtend index da1e0bb7ba..c51f356345 100644 --- a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/formatter/TestingFormatterTestCase.xtend +++ b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/formatter/TestingFormatterTestCase.xtend @@ -25,6 +25,7 @@ class TestingFormatterTestCase extends AbstractWollokFormatterTestCase { const b = new Sobreviviente() test "aSimpleTest"{ assert.that(true) }''', ''' const a = new Sobreviviente() + const b = new Sobreviviente() test "aSimpleTest" { diff --git a/org.uqbar.project.wollok/src/org/uqbar/project/wollok/formatting2/WollokDslFormatter.xtend b/org.uqbar.project.wollok/src/org/uqbar/project/wollok/formatting2/WollokDslFormatter.xtend index 49a5420e14..7d173690a4 100644 --- a/org.uqbar.project.wollok/src/org/uqbar/project/wollok/formatting2/WollokDslFormatter.xtend +++ b/org.uqbar.project.wollok/src/org/uqbar/project/wollok/formatting2/WollokDslFormatter.xtend @@ -65,11 +65,7 @@ class WollokDslFormatter extends AbstractFormatter2 { ] elements.forEach [ element, i | element.format - if (elements.size - 1 == i) { - element.append [ setNewLines(2) ] - } else { - element.append [ newLine ] - } + element.append [ setNewLines(2) ] ] main.format tests.formatTests(document) @@ -566,11 +562,7 @@ class WollokDslFormatter extends AbstractFormatter2 { def void formatSuites(Iterable suites, extension IFormattableDocument document) { suites.forEach [ suite, i | suite.format - if (suites.size - 1 == i) { - suite.append [ newLine ] - } else { - suite.append [ setNewLines(2) ] - } + suite.append [ setNewLines(2) ] ] } From 2d9894eeb163a39cb547c506819124137fbd6be7 Mon Sep 17 00:00:00 2001 From: Fernando Dodino Date: Sat, 19 Oct 2019 20:29:24 -0300 Subject: [PATCH 024/133] Removing .wlk files from lib and adding virtual folder from wollok-language repo --- .gitmodules | 3 + org.uqbar.project.wollok.lib/.project | 27 + .../src/wollok/game.wlk | 471 --- .../src/wollok/lang.wlk | 2756 ----------------- .../src/wollok/lib.wlk | 253 -- .../src/wollok/mirror.wlk | 13 - .../src/wollok/vm.wlk | 3 - wollok-language | 1 + 8 files changed, 31 insertions(+), 3496 deletions(-) create mode 100644 .gitmodules delete mode 100644 org.uqbar.project.wollok.lib/src/wollok/game.wlk delete mode 100644 org.uqbar.project.wollok.lib/src/wollok/lang.wlk delete mode 100644 org.uqbar.project.wollok.lib/src/wollok/lib.wlk delete mode 100644 org.uqbar.project.wollok.lib/src/wollok/mirror.wlk delete mode 100644 org.uqbar.project.wollok.lib/src/wollok/vm.wlk create mode 160000 wollok-language diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000000..377c582d43 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "wollok-language"] + path = wollok-language + url = git@github.com:uqbar-project/wollok-language.git diff --git a/org.uqbar.project.wollok.lib/.project b/org.uqbar.project.wollok.lib/.project index 75f982934e..88ece7b342 100644 --- a/org.uqbar.project.wollok.lib/.project +++ b/org.uqbar.project.wollok.lib/.project @@ -37,4 +37,31 @@ org.eclipse.jdt.core.javanature org.eclipse.xtext.ui.shared.xtextNature + + + src/wollok/game.wlk + 1 + PARENT-1-PROJECT_LOC/wollok-language/src/wollok/game.wlk + + + src/wollok/lang.wlk + 1 + PARENT-1-PROJECT_LOC/wollok-language/src/wollok/lang.wlk + + + src/wollok/lib.wlk + 1 + PARENT-1-PROJECT_LOC/wollok-language/src/wollok/lib.wlk + + + src/wollok/mirror.wlk + 1 + PARENT-1-PROJECT_LOC/wollok-language/src/wollok/mirror.wlk + + + src/wollok/vm.wlk + 1 + PARENT-1-PROJECT_LOC/wollok-language/src/wollok/vm.wlk + + diff --git a/org.uqbar.project.wollok.lib/src/wollok/game.wlk b/org.uqbar.project.wollok.lib/src/wollok/game.wlk deleted file mode 100644 index dc00c52465..0000000000 --- a/org.uqbar.project.wollok.lib/src/wollok/game.wlk +++ /dev/null @@ -1,471 +0,0 @@ -import wollok.vm.runtime - -/** - * Wollok Game main object - */ -object game { - - /** - * Adds an object to the board for drawing it. - * Object should understand a position property - * (implemented by a reference or getter method). - * - * Example: - * game.addVisual(pepita) ==> pepita should have a position property - */ - method addVisual(positionable) native - - /** - * Adds an object to the board for drawing it on a specific position. - * - * Example: - * game.addVisualIn(pepita, game.origin()) ==> no need for pepita to have a position property - * game.addVisualIn(pepita, game.at(2, 2)) - */ - method addVisualIn(element, position) native - - - /** - * Adds an object to the board for drawing it. It can be moved with arrow keys. - * That object should understand a position property - * (implemented by a reference or getter method). - * - * Example: - * game.addVisualCharacter(pepita) ==> pepita should have a position property - */ - method addVisualCharacter(positionable) native - - /** - * Adds an object to the board for drawing it on a specific position. It can be moved with arrow keys. - * - * Example: - * game.addVisualCharacterIn(pepita, game.origin()) ==> no need for pepita to have a position property - */ - method addVisualCharacterIn(element, position) native - - /** - * Removes an object from the board for stop drawing it. - * - * Example: - * game.removeVisual(pepita) - */ - method removeVisual(visual) native - - /** - * Verifies if an object is currently in the board. - * - * Example: - * game.hasVisual(pepita) - */ - method hasVisual(visual) native - - /** - * Returns all visual objects added to the board. - * - * Example: - * game.allVisuals() - */ - method allVisuals() native - - /** - * Adds a block that will be executed each time a specific key is pressed - * @see keyboard.onPressDo() - */ - method whenKeyPressedDo(key, action) native - - /** - * Adds a block that will be executed while the given object collides with other. - * Two objects collide when are in the same position. - * - * The block should expect the other object as parameter. - * - * Example: - * game.whenCollideDo(pepita, { comida => pepita.comer(comida) }) - */ - method whenCollideDo(visual, action) native - - /** - * Adds a block that will be executed exactly when the given object collides with other. - * Two objects collide when are in the same position. - * - * The block should expect the other object as parameter. - * - * Example: - * game.onCollideDo(pepita, { comida => pepita.comer(comida) }) - */ - method onCollideDo(visual, action) native - - /** - * Adds a block with a specific name that will be executed every n milliseconds. - * Block expects no argument. - * Be careful not to set it too often :) - * - * Example: - * game.onTick(5000, "pepitaMoving", { => pepita.position().x(0.randomUpTo(4)) }) - */ - method onTick(milliseconds, name, action) native - - /** - * Adds a block that will be executed in n milliseconds. - * Block expects no argument. - * - * Example: - * game.schedule(5000, { => pepita.position().x(0.randomUpTo(4)) }) - */ - method schedule(milliseconds, action) native - - /** - * Remove a tick event created with onTick message - * - * Example: - * game.removeTickEvent("pepitaMoving") - */ - method removeTickEvent(name) native - - /** - * Returns all objects in given position. - * - * Example: - * game.getObjectsIn(game.origin()) - */ - method getObjectsIn(position) native - - /** - * Draws a dialog balloon with given message in given visual object position. - * - * Example: - * game.say(pepita, "hola!") - */ - method say(visual, message) native - - /** - * Removes all visual objects on board and configurations (colliders, keys, etc). - */ - method clear() native - - /** - * Returns all objects that are in same position of given object. - */ - method colliders(visual) native - - /** - * Returns the unique object that is in same position of given object. - */ - method uniqueCollider(visual) = self.colliders(visual).uniqueElement() - - /** - * Stops render the board and finish the game. - */ - method stop() native - - /** - * Starts render the board in a new windows. - */ - method start() { - self.doStart(runtime.isInteractive()) - } - - /** - * Returns a position for given coordinates. - */ - method at(x, y) { - return new Position(x = x, y = y) - } - - /** - * Returns the position (0,0). - */ - method origin() = self.at(0, 0) - - /** - * Returns the center board position (rounded down). - */ - method center() = self.at(self.width().div(2), self.height().div(2)) - - /** - * Sets game title. - */ - method title(title) native - - /** - * Returns game title. - */ - method title() native - - /** - * Sets board width (in cells). - */ - method width(width) native - - /** - * Returns board width (in cells). - */ - method width() native - - /** - * Sets board height (in cells). - */ - method height(height) native - - /** - * Returns board height (in cells). - */ - method height() native - - /** - * Sets cells background image. - */ - method ground(image) native - - /** - * Sets full background image. - */ - method boardGround(image) native - - /** - * Attributes will not show when user mouse over a visual component. - * Default behavior is to show them. - */ - method hideAttributes(visual) native - - /** - * Attributes will appear again when user mouse over a visual component. - * Default behavior is to show them, so this is not necessary. - */ - method showAttributes(visual) native - - /** - * Allows to configure a visual component as "error reporter". - * Then every error in game board will be reported by this visual component, - * in a balloon message form. - */ - method errorReporter(visual) native - - /** - * Plays once a .mp3, .ogg or .wav audio file - */ - method sound(audioFile) native - - /** - * @private - */ - method doStart(isRepl) native -} - -/** - * Represents a position in a two-dimensional gameboard. - * It is an immutable object since Wollok 1.8.0 - */ -class Position { - const property x = 0 - const property y = 0 - - /** - * Returns a new Position n steps right from this one. - */ - method right(n) = new Position(x = x + n, y = y) - - /** - * Returns a new Position n steps left from this one. - */ - method left(n) = new Position(x = x - n, y = y) - - /** - * Returns a new Position n steps up from this one. - */ - method up(n) = new Position(x = x, y = y + n) - - /** - * Returns a new Position, n steps down from this one. - */ - method down(n) = new Position(x = x, y = y - n) - - /** - * Adds an object to the board for drawing it in self. - */ - method drawElement(element) { game.addVisualIn(element, self) } //TODO: Implement native - - /** - * Adds an object to the board for drawing it in self. It can be moved with arrow keys. - */ - method drawCharacter(element) { game.addVisualCharacterIn(element, self) } //TODO: Implement native - - /** - * Draw a dialog balloon with given message in given visual object position. - */ - method say(element, message) { game.say(element, message) } //TODO: Implement native - - /** - * Returns all objects in self. - */ - method allElements() = game.getObjectsIn(self) //TODO: Implement native - - /** - * Returns a new position with same coordinates. - */ - method clone() = new Position(x = x, y = y) - - /** - * Returns the distance between given position and self. - */ - method distance(position) { - self.checkNotNull(position, "distance") - const deltaX = x - position.x() - const deltaY = y - position.y() - return (deltaX.square() + deltaY.square()).squareRoot() - } - - /** - * Removes all objects in self from the board for stop drawing it. - */ - method clear() { - self.allElements().forEach{it => game.removeVisual(it)} - } - - /** - * Two positions are equals if they have same coordinates. - */ - override method ==(other) = x == other.x() && y == other.y() - - /** - * String representation of a position - */ - override method toString() = "(" + x + "," + y + ")" - -} - -/** - * Keyboard object handles all keys movements. There is a method for each key. - * - * Examples: - * keyboard.i().onPressDo { game.say(pepita, "hola!") } - * => when user hits "i" key, pepita will say "hola!" - * - * keyboard.any().onPressDo { game.say(pepita, "you pressed a key!") } - * => any key pressed will activate its closure - */ -object keyboard { - - method any() = new Key(keyCodes = [-1]) - - method num(n) = new Key(keyCodes = [n + 7, n + 144]) - - method num0() = self.num(0) - - method num1() = self.num(1) - - method num2() = self.num(2) - - method num3() = self.num(3) - - method num4() = self.num(4) - - method num5() = self.num(5) - - method num6() = self.num(6) - - method num7() = self.num(7) - - method num8() = self.num(8) - - method num9() = self.num(9) - - method a() = new Key(keyCodes = [29]) - - method alt() = new Key(keyCodes = [57, 58]) - - method b() = new Key(keyCodes = [30]) - - method backspace() = new Key(keyCodes = [67]) - - method c() = new Key(keyCodes = [31]) - - method control() = new Key(keyCodes = [129, 130]) - - method d() = new Key(keyCodes = [32]) - - method del() = new Key(keyCodes = [67]) - - method center() = new Key(keyCodes = [23]) - - method down() = new Key(keyCodes = [20]) - - method left() = new Key(keyCodes = [21]) - - method right() = new Key(keyCodes = [22]) - - method up() = new Key(keyCodes = [19]) - - method e() = new Key(keyCodes = [33]) - - method enter() = new Key(keyCodes = [66]) - - method f() = new Key(keyCodes = [34]) - - method g() = new Key(keyCodes = [35]) - - method h() = new Key(keyCodes = [36]) - - method i() = new Key(keyCodes = [37]) - - method j() = new Key(keyCodes = [38]) - - method k() = new Key(keyCodes = [39]) - - method l() = new Key(keyCodes = [40]) - - method m() = new Key(keyCodes = [41]) - - method minusKey() = new Key(keyCodes = [69]) - - method n() = new Key(keyCodes = [42]) - - method o() = new Key(keyCodes = [43]) - - method p() = new Key(keyCodes = [44]) - - method plusKey() = new Key(keyCodes = [81]) - - method q() = new Key(keyCodes = [45]) - - method r() = new Key(keyCodes = [46]) - - method s() = new Key(keyCodes = [47]) - - method shift() = new Key(keyCodes = [59, 60]) - - method slash() = new Key(keyCodes = [76]) - - method space() = new Key(keyCodes = [62]) - - method t() = new Key(keyCodes = [48]) - - method u() = new Key(keyCodes = [49]) - - method v() = new Key(keyCodes = [50]) - - method w() = new Key(keyCodes = [51]) - - method x() = new Key(keyCodes = [52]) - - method y() = new Key(keyCodes = [53]) - - method z() = new Key(keyCodes = [54]) - -} - - -class Key { - const property keyCodes - - /** - * Adds a block that will be executed always self is pressed. - * - * Example: - * keyboard.i().onPressDo { game.say(pepita, "hola!") } - * => when user hits "i" key, pepita will say "hola!" - */ - method onPressDo(action) { - keyCodes.forEach{ key => game.whenKeyPressedDo(key, action) } //TODO: Implement native - } -} diff --git a/org.uqbar.project.wollok.lib/src/wollok/lang.wlk b/org.uqbar.project.wollok.lib/src/wollok/lang.wlk deleted file mode 100644 index 5d4a7e0ce2..0000000000 --- a/org.uqbar.project.wollok.lib/src/wollok/lang.wlk +++ /dev/null @@ -1,2756 +0,0 @@ -/** - * Base class for all Exceptions. Every exception and its subclasses - * indicates conditions that a reasonable application might want to catch. - * - * @author jfernandes - * @since 1.0 - */ -class Exception { - /** specified detail message. */ - const property message = null - - /** specified cause */ - const property cause = null - - /** Prints this exception and its backtrace to the console */ - method printStackTrace() { self.printStackTrace(console) } - - /** Prints this exception and its backtrace as a string value */ - method getStackTraceAsString() { - const printer = new StringPrinter() - self.printStackTrace(printer) - return printer.getBuffer() - } - - /** - * @private - * Prints this exception and its backtrace to the specified printer - */ - method printStackTrace(printer) { self.printStackTraceWithPrefix("", printer) } - - /** @private */ - method printStackTraceWithPrefix(prefix, printer) { - printer.println(prefix + self.className() + (if (message != null) (": " + message.toString()) else "")) - - // TODO: eventually we will need a stringbuffer or something to avoid memory consumption - self.getStackTrace().forEach { e => - printer.println("\tat " + e.contextDescription() + " [" + e.location() + "]") - } - - if (cause != null) - cause.printStackTraceWithPrefix("Caused by: ", printer) - } - - /** @private */ - method createStackTraceElement(contextDescription, location) = new StackTraceElement(contextDescription = contextDescription, location = location) - - /** Provides programmatic access to the stack trace information - * printed by printStackTrace() with full path files for linking - */ - method getFullStackTrace() native - - /** Provides programmatic access to the stack trace information - * printed by printStackTrace(). - */ - method getStackTrace() native - - /** Overrides the behavior to compare exceptions */ - override method equals(other) = other.className().equals(self.className()) && other.message() == self.message() -} - -/** - * Thrown when a stack overflow occurs because an application recurses too deeply. - * - * @author jfernandes - * @since 1.5.1 - */ -class StackOverflowException inherits Exception {} - -/** - * An exception that is thrown when a specified element cannot be found - */ -class ElementNotFoundException inherits Exception {} - -/** - * An exception that is thrown for domain purpose - */ -class DomainException inherits Exception { - const property source = null -} - -/** - * (added by wollok-ts) An exception thrown whenever the interpreter fails to evaluate an expression - */ -class EvaluationError inherits Exception {} - -/** - * An exception that is thrown when an object cannot understand a certain message - */ -class MessageNotUnderstoodException inherits Exception {} - -/** - * An element in a stack trace, represented by a context and a location - * of a method where a message was sent - */ -class StackTraceElement { - const property contextDescription - const property location -} - -/** - * - * Representation of Wollok Object - * - * Class Object is the root of the class hierarchy. - * Every class has Object as a superclass. - * - * @author jfernandes - * since 1.0 - */ -class Object { - - /** - * Answers object identity of a Wollok object, represented by - * a unique number in Wollok environment - */ - method identity() native - - /** - * Answers a list of instance variables for this Wollok object - * @private - needed by wollok-xtext implementation - */ - method instanceVariables() native - - /** - * Retrieves a specific variable. Expects a name - * @private - needed by wollok-xtext implementation - */ - method instanceVariableFor(name) native - - /** - * Accesses a variable by name, in a reflexive way. - * @private - needed by wollok-xtext implementation - */ - method resolve(name) native - - /** Object description in english/spanish/... (depending on i18n configuration) - * - * Examples: - * "2".kindName() => Answers "a String" - * 2.kindName() => Answers "a Integer" - * - * @private - */ - method kindName() native - - /** - * Full name of Wollok object class - * @private - */ - method className() native - - /** - * Tells whether self object is "equal" to the given object - * The default behavior compares them in terms of identity (===) - */ - method ==(other) = other != null && self === other - - /** Tells whether self object is not equal to the given one */ - method !=(other) = ! (self == other) - - /** - * Tells whether self object is identical (the same) to the given one. - * It does it by comparing their identities. - * So self basically relies on the wollok.lang.Integer equality (which is native) - */ - method ===(other) = self.identity() == other.identity() - - /** - * Tells whether self object is not identical (the same) to the given one. - * @See === message. - */ - method !==(other) = ! (self === other) - - /** - * o1.equals(o2) is a synonym for o1 == o2 - */ - method equals(other) = self == other - - /** - * Generates a Pair key-value association. @see Pair. - */ - method ->(other) { - return new Pair(x = self, y = other) - } - - /** - * String representation of Wollok object - */ - method toString() { - return self.toSmartString([]) - } - - /** - * Shows a short, internal representation - */ - method shortDescription() = self.toString() - - /** - * Provides a visual representation of Wollok Object - * By default, same as toString but can be overridden - * like in String - */ - method printString() = self.toString() - - /** @private */ - method toSmartString(alreadyShown) { - if (alreadyShown.any { e => e.identity() == self.identity() } ) { - return self.simplifiedToSmartString() - } - else { - alreadyShown.add(self) - return self.internalToSmartString(alreadyShown) - } - } - - /** @private */ - method simplifiedToSmartString() = self.kindName() - - /** @private */ - method internalToSmartString(alreadyShown) { - return self.kindName() + "[" - + self.instanceVariables().map { v => - v.name() + "=" + v.valueToSmartString(alreadyShown) - }.join(', ') - + "]" - } - - /** @private */ - method messageNotUnderstood(messageName, parameters) { - const target = if (messageName != "toString") - self.toString() - else - self.kindName() - const aMessage = self.generateDoesNotUnderstandMessage(target, messageName, parameters.size()) - throw new MessageNotUnderstoodException(message = aMessage) - } - - /** - * @private - * - * internal method: generates a does not understand message - * parametersSize must be an integer value - */ - method generateDoesNotUnderstandMessage(target, messageName, parametersSize) native - - /** Builds an exception with a message */ - method error(aMessage) { - throw new DomainException(message = aMessage, source = self) - } - - /** @private */ - method checkNotNull(value, message) native -} - -/** Representation for methods that only have side effects */ -object void { } - -/** - * Representation of a Key/Value Association. - * It is also useful if you want to model a Point. - */ -class Pair { - const property x - const property y - constructor (_x, _y) { - x = _x - y = _y - } - method key() = x - method value() = y - - /** - * Two pairs are equal if they have the same values - * - * Example: - * new Pair(1, 2).equals(new Pair(1, 2)) ==> Answers true - */ - override method equals(other) { - self.checkNotNull(other, "equals") - return x == other.x() && y == other.y() - } - - /** String representation of a Pair */ - override method toString() = x.toString() + " -> " + y.toString() -} - -/** - * The root class in the collection hierarchy. - * A collection represents a group of objects, known as its elements. - */ -class Collection { - /** - * Answers the element that is considered to be/have the maximum value. - * The criteria is given by a closure that receives a single element - * as input (one of the element). The closure must return a comparable - * value (something that understands the >, >= messages). - * If collection is empty, an ElementNotFound exception is thrown. - * - * Example: - * ["a", "ab", "abc", "d" ].max({ e => e.length() }) - * => Answers "abc" - * - * [].max({ e => e.length() }) - * => Throws error, list must not be empty - */ - method max(closure) { - self.checkNotNull(closure, "max") - return self.maxIfEmpty(closure, { throw new ElementNotFoundException(message = "collection is empty") }) - } - - /** - * Answers the element that represents the maximum value in the collection. - * The criteria is by direct comparison of the elements. - * If collection is empty, an ElementNotFound exception is thrown. - * - * Example: - * [11, 1, 4, 8, 3, 15, 6].max() => Answers 15 - * [].max() => Throws error, list must not be empty - */ - method max() = self.max({it => it}) - - /** - * Answers the element that is considered to be/have the maximum value, - * or applies a closure if the collection is empty. - * The criteria is given by a closure that receives a single element - * as input (one of the element). The closure must return a comparable - * value (something that understands the >, >= messages). - * The closure to execute when the collection is empty is given as a second - * argument. - * - * Example: - * ["a", "ab", "abc", "d" ].maxIfEmpty({ e => e.length() }, { "default" }) - * => Answers "abc" - * - * [].maxIfEmpty({ e => e.length() }, { "default" }) - * => Answers "default" - */ - method maxIfEmpty(toComparableClosure, emptyCaseClosure) { - self.checkNotNull(toComparableClosure, "maxIfEmpty") - self.checkNotNull(emptyCaseClosure, "maxIfEmpty") - return self.absolute(toComparableClosure, { a, b => a > b }, emptyCaseClosure) - } - - /** - * Answers the element that is considered to be/have the maximum value, - * or applies a closure if the collection is empty. - * The criteria is by direct comparison of the elements. - * The closure to execute when the collection is empty is given as a second - * argument. - * - * Example: - * [11, 1, 4, 8, 3, 15, 6].maxIfEmpty({ 99 }) => Answers 15 - * [].maxIfEmpty({ 99 }) => Answers 99 - */ - method maxIfEmpty(emptyCaseClosure) = self.maxIfEmpty({it => it}, emptyCaseClosure) - - /** - * Answers the element that is considered to be/have the minimum value. - * The criteria is given by a closure that receives a single element - * as input (one of the element). The closure must return a comparable - * value (something that understands the <, <= messages). - * - * Example: - * ["ab", "abc", "hello", "wollok world"].min({ e => e.length() }) - * => Answers "ab" - * - * [].min({ e => e.length() }) - * => Throws error, list must not be empty - */ - method min(closure) { - self.checkNotNull(closure, "min") - return self.absolute(closure, { a, b => a < b }, { throw new ElementNotFoundException(message = "collection is empty") }) - } - - /** - * Answers the element that represents the minimum value in the - * non-empty collection. - * The criteria is by direct comparison of the elements. - * - * Example: - * [11, 1, 4, 8, 3, 15, 6].min() => Answers 1 - * [].min() => Throws error, list must not be empty - */ - method min() = self.min({it => it}) - - /** - * Answers the element that is considered to be/have the minimum value, - * or applies a closure if the collection is empty. - * The criteria is given by a closure that receives a single element - * as input (one of the element). The closure must return a comparable - * value (something that understands the >, >= messages). - * The closure to execute when the collection is empty is given as a second - * argument. - * - * Example: - * ["ab", "abc", "hello", "wollok world"].minIfEmpty({ e => e.length() }, { "default" }) - * => Answers "ab" - * - * [].minIfEmpty({ e => e.length() }, { "default" }) - * => Answers "default" - */ - method minIfEmpty(toComparableClosure, emptyCaseClosure) { - self.checkNotNull(toComparableClosure, "minIfEmpty") - self.checkNotNull(emptyCaseClosure, "minIfEmpty") - return self.absolute(toComparableClosure, { a, b => a < b }, emptyCaseClosure) - } - - /** - * Answers the element that is considered to be/have the minimum value, - * or applies a closure if the collection is empty. - * The criteria is by direct comparison of the elements. - * The closure to execute when the collection is empty is given as a second - * argument. - * - * Example: - * [11, 1, 4, 8, 3, 15, 6].minIfEmpty({ 99 }) => Answers 1 - * [].minIfEmpty({ 99 }) => Answers 99 - */ - method minIfEmpty(emptyCaseClosure) { - self.checkNotNull(emptyCaseClosure, "minIfEmpty") - return self.minIfEmpty({it => it}, emptyCaseClosure) - } - - /** @private */ - method absolute(closure, criteria, emptyCaseClosure) { - self.checkNotNull(closure, "absolute") - self.checkNotNull(criteria, "absolute") - self.checkNotNull(emptyCaseClosure, "absolute") - if (self.isEmpty()) { - return emptyCaseClosure.apply() - } - const result = self.fold(null, { acc, e => - const n = closure.apply(e) - if (acc == null) - e -> n - else { - if (criteria.apply(n, acc.y())) - e -> n - else - acc - } - }) - return result.x() - } - - /** - * Answers the unique element in the collection. - * If collection is empty, an error is thrown. - * If collection has more than one element, an error is thrown. - * - * Example: - * [1].uniqueElement() => Answers 1 - * [].uniqueElement() => Throws error, list must not be empty - * [1, 2].uniqueElement() => Throws error, list must have one element - */ - method uniqueElement() { - self.validateNotEmpty("uniqueElement") - const size = self.size() - if (size > 1) - throw new Exception(message = "Illegal operation 'uniqueElement' on collection with " + size.toString() + " elements") - return self.anyOne() - } - - - // non-native methods - - /** - * Concatenates this collection to all elements from the given - * collection parameter giving a new collection - * (no side effect) - * - * Example: - * [1, 2] + [3] => Answers [1, 2, 3] - * [1, 2] + #{3} => supports concatenation between lists and sets, answers [1, 2, 3] - * #{} + [] => Answers #{} - */ - method +(elements) { - const newCol = self.copy() - newCol.addAll(elements) - return newCol - } - - /** - * Adds all elements from the given collection parameter to self collection. - * This is a side effect operation. - * - * Example: - * const list = [] - * list.addAll(#{2, 4}) => list == [2, 4], always pointing to a list - */ - method addAll(elements) { - self.checkNotNull(elements, "addAll") - elements.forEach { element => self.add(element) } - } - - /** - * Removes all elements of the given collection parameter from self collection. - * This is a side effect operation. - * - * Example: - * const list = [1, 6, 5] - * list.removeAll([6]) => list == [1, 5] - */ - method removeAll(elements) { - self.checkNotNull(elements, "removeAll") - elements.forEach { element => self.remove(element) } - } - - /** - * Removes those elements that meet a given condition. - * This is a side effect operation. - * Supports empty collections. - * - * Example: - * const list = [1, 6, 5] - * list.removeAllSuchThat { e => e.even() } => list == [1, 5] - */ - method removeAllSuchThat(closure) { - self.checkNotNull(closure, "removeAllSuchThat") - self.removeAll( self.filter(closure) ) - } - - /** - * Tells whether self collection has no elements - * - * Example: - * [1, 6, 5].isEmpty() => Answers false - * [].isEmpty() => Answers true - */ - method isEmpty() = self.size() == 0 - - /** - * @private - * Throws error if self collection is empty - */ - method validateNotEmpty(operation) { - if (self.isEmpty()) - throw new Exception(message = "Illegal operation '" + operation + "' on empty collection") - } - - /** - * Performs an operation on every element of self collection. - * The logic to execute is passed as a closure that takes a single parameter. - * Supports empty collections. - * @returns nothing - * - * Example: - * plants.forEach { plant => plant.takeSomeWater() } - */ - method forEach(closure) { - self.checkNotNull(closure, "forEach") - self.fold(null, { seed, element => - closure.apply(element) - seed - }) - } - - /** - * Answers whether all the elements of self collection satisfy a given - * condition. The condition is a closure argument that takes a single - * element and answers a boolean value. - * - * @returns true/false - * - * Example: - * plants.all({ plant => plant.hasFlowers() }) - * [1, 3, 5].all { number => number.odd() } => Answers true - * [].all { number => number.odd() } => Answers true - */ - method all(predicate) { - self.checkNotNull(predicate, "all") - return self.fold(true, { seed, element => if (!seed) seed else predicate.apply(element) }) - } - - /** - * Tells whether at least one element of self collection satisfies a - * given condition. The condition is a closure argument that takes a - * single element and answers a boolean value. - * @returns true/false - * - * Example: - * plants.any({ plant => plant.hasFlowers() }) - * [1, 2, 3].any { number => number.even() } ==> Answers true - * [].any { number => number.even() } ==> Answers false - */ - method any(predicate) { - self.checkNotNull(predicate, "any") - return self.fold(false, { seed, element => if (seed) seed else predicate.apply(element) }) - } - - /** - * Answers the element of self collection that satisfies a given condition. - * If more than one element satisfies the condition then it depends - * on the specific collection class which element will be returned. - * - * @returns the element that complies the condition - * @throws ElementNotFoundException if no element matched the given predicate - * - * Example: - * users.find { user => user.name() == "Cosme Fulanito" } - * #{1, 4, 5}.find { number => number.even() } => Answers 4 - * #{1, 3}.find { number => number.even() } => Throws ElementNotFoundException - * #{}.find { number => number.even() } => Throws ElementNotFoundException - */ - method find(predicate) { - self.checkNotNull(predicate, "find") - return self.findOrElse(predicate, { - throw new ElementNotFoundException(message = "there is no element that satisfies the predicate") - }) - } - - /** - * Answers the element of self collection that satisfies a given condition, - * or the given default otherwise, if no element matched the predicate. - * If more than one element satisfies the condition then it depends on the specific - * collection class which element will be returned. - * - * @returns the element that complies the condition or the default value - * - * Example: - * users.findOrDefault({ user => user.name() == "Cosme Fulanito" }, homer) - * [1, 3, 5].findOrDefault({ number => number.even() }, 0) => Answers 0 - * [].findOrDefault({ number => number.even() }, 0) => Answers 0 - */ - method findOrDefault(predicate, value) = self.findOrElse(predicate, { value }) - - /** - * Answers the element of self collection that satisfies a given condition, - * or the the result of evaluating the given continuation. - * If more than one element satisfies the condition then it depends on the - * specific collection class which element will be returned. - * - * @returns the element that complies the condition or the result - * of evaluating the continuation - * - * Example: - * users.findOrElse({ user => user.name() == "Cosme Fulanito" }, { homer }) - * [1, 3, 5].findOrElse({ number => number.even() }, { 6.max(4) }) => Answers 6 - * [].findOrElse({ number => number.even() }, { false }) => Answers false - */ - method findOrElse(predicate, continuation) native - - /** - * Counts all elements of self collection that satisfies a given condition - * The condition is a closure argument that takes a single element and - * answers a number. - * @returns an integer number - * - * Example: - * plants.count { plant => plant.hasFlowers() } - * #{1, 2, 3, 4, 5}.count { number => number.odd() } => Answers 3 - * #{}.count { number => number.odd() } => Answers 0 - */ - method count(predicate) { - self.checkNotNull(predicate, "count") - return self.fold(0, { total, element => if (predicate.apply(element)) total+1 else total }) - } - - /** - * Counts the occurrences of a given element in self collection. - * @returns an integer number - * - * Example: - * [1, 8, 4, 1].occurrencesOf(1) => Answers 2 - * [].occurrencesOf(2) => Answers 0 - */ - method occurrencesOf(element) = self.count({it => it == element}) - - /** - * Collects the sum of each value for all elements. - * This is similar to call a map {} to transform each element into a - * number object and then adding all those numbers. - * The condition is a closure argument that takes a single element and - * answers a boolean value. - * - * @returns an integer - * - * Example: - * const totalNumberOfFlowers = plants.sum{ plant => plant.numberOfFlowers() } - * [].sum { employee => employee.salary() } => Answers 0 - */ - method sum(closure) { - self.checkNotNull(closure, "sum") - return self.fold(0, { total, element => total + closure.apply(element) }) - } - - /** - * Sums all elements in the collection. - * @returns an integer - * - * Example: - * [1, 2, 3, 4, 5].sum() => Answers 15 - * [].sum() => Answers 0 - */ - method sum() = self.sum( {it => it} ) - - /** - * Answers a new collection that contains the result of transforming - * each of self collection's elements using a given closure. - * The condition is a closure argument that takes a single element - * and answers an object. - * @returns another list - * - * Example: - * const ages = users.map({ user => user.age() }) - * [1, 2, 3].map { number => number.odd() } => Answers [true, false, true] - * [].map { number => number.odd() } => Answers [] - */ - method map(closure) { - self.checkNotNull(closure, "map") - return self.fold([], { newCollection, element => - newCollection.add(closure.apply(element)) - newCollection - }) - } - - /** - * Map + flatten operation - * @see map - * @see flatten - * - * Example: - * object klaus { - * method languages() = ["c", "cobol", "pascal"] - * } - * - * object fritz { - * method languages() = ["java", "perl"] - * } - * - * - * [klaus, fritz].flatMap({ person => person.languages() }) - * => Answers ["c", "cobol", "pascal", "java", "perl"] - */ - method flatMap(closure) { - self.checkNotNull(closure, "flatMap") - return self.fold(self.newInstance(), { flattenedList, element => - flattenedList.addAll(closure.apply(element)) - flattenedList - }) - } - - /** - * Answers a new collection that contains the elements that - * meet a given condition. The condition is a closure argument that - * takes a single element and answers a boolean. - * @returns another collection (same type as self one) - * - * Example: - * const overageUsers = users.filter({ user => user.age() >= 18 }) - * #{1, 2, 3, 4, 5}.filter { number => number.even() } => Answers #{2, 4} - * #{}.filter { number => number.even() } => Answers #{} - */ - method filter(closure) { - self.checkNotNull(closure, "filter") - return self.fold(self.newInstance(), { newCollection, element => - if (closure.apply(element)) - newCollection.add(element) - newCollection - }) - } - - /** - * Answers whether this collection contains the specified element. - * - * Example: - * [].contains(3) => Answers false - * [1, 2, 3].contains(2) => Answers true - */ - method contains(element) = self.any {one => element == one } - - /** - * Flattens a collection of collections - * - * Example: - * [ [1, 2], [3], [4, 0], [] ].flatten() => Answers [1, 2, 3, 4, 0] - * - */ - method flatten() = self.flatMap { it => it } - - /** @private */ - /* - * Optimized version for long collections - * - * @see Object#toString() - */ - override method internalToSmartString(alreadyShown) { - const size = self.size() - const internalCollection = if (size > 50) "..." + size + " elements" else self.map{ e => e.toSmartString(alreadyShown) }.join(", ") - return self.toStringPrefix() + internalCollection + self.toStringSuffix() - } - - /** @private */ - method toStringPrefix() - - /** @private */ - method toStringSuffix() - - /** Converts a collection to a list */ - method asList() - - /** Converts a collection to a set (removing duplicates if necessary) - * - * Examples: - * [1, 2, 3].asSet() => Answers #{1, 2, 3} - * [].asSet() => Answers #{} - * [1, 2, 1, 1, 2].asSet() => Answers #{1, 2} - * - * #{1, 2, 3}.asSet() => Answers #{1, 2, 3} - * #{}.asSet() => Answers #{} - * - * @see Set - */ - method asSet() { - const result = #{} - result.addAll(self) - return result - } - - /** - * Answers a new collection of the same type and with the same content - * as self. Supports empty collections. - * - * @returns a new collection - * - * Example: - * const usersCopy = users.copy() - */ - method copy() { - const copy = self.newInstance() - copy.addAll(self) - return copy - } - - /** - * Answers a new collection without element that is passed by parameter. - * If the element occurs more than once in the collection, all occurrences - * will be removed. - * - * @returns a new Collection - * - * Example: - * [1, 5, 9, 2, 4].copyWithout(9) => Answers [1, 5, 2, 4] - * [1, 5, 9, 2, 9].copyWithout(9) => Answers [1, 5, 2] - * - */ - method copyWithout(elementToRemove) { - return self.filter{ element => element != elementToRemove } - } - - /** - * Answers a new collection with the added element which is received by parameter. - * - * @returns a new Collection - * - * Example: - * [1, 5, 9, 2, 4].copyWith(9) => Answers [1, 5, 2, 4, 9] - * - */ - method copyWith(elementToAdd) { - const copy = self.copy() - copy.add(elementToAdd) - return copy - } - - /** - * Answers a new List that contains the elements of self collection - * sorted by a criteria given by a closure. The closure receives two objects - * X and Y and answers a boolean, true if X should come before Y in the - * resulting collection. Supports empty collections. - * - * @returns a new List - * - * Example: - * const usersByAge = users.sortedBy({ a, b => a.age() < b.age() }) - * const studentsByNameDesc = students.sortedBy({ a, b => a.name() > b.name() }) - * [1, 5, 9, 2, 4].sortedBy { a, b => a < b } => Answers [1, 2, 4, 5, 9] - * [1, 5, 9, 2, 4].sortedBy { a, b => a > b } => Answers [9, 5, 4, 2, 1] - * [].sortedBy { a, b => a > b } => Answers [] - * - */ - method sortedBy(closure) { - const copy = self.copy().asList() - copy.sortBy(closure) - return copy - } - - - /** - * Answers a new, empty collection of the same type as self. - * @returns a new collection - * - * Example: - * const newCollection = users.newInstance() - */ - method newInstance() - - /** - * @see subclasses implementations - */ - method anyOne() = throw new Exception(message = "Should be implemented by the subclasses") - - /** - * @see subclasses implementations - */ - method add(element) = throw new Exception(message = "Should be implemented by the subclasses") - - /** - * @see subclasses implementations - */ - method remove(element) = throw new Exception(message = "Should be implemented by the subclasses") - - /** - * @see subclasses implementations - */ - method fold(element, closure) = throw new Exception(message = "Should be implemented by the subclasses") - - /** - * @see subclasses implementations - */ - method size() = throw new Exception(message = "Should be implemented by the subclasses") - - /** - * Removes all of the elements from this set. This is a side effect operation. - * - * @see subclasses implementations - */ - method clear() - - /** - * Answers the concatenated string representation of the elements in the given set. - * You can pass an optional character as an element separator (default is ",") - */ - method join(separator) - - /** - * Answers the concatenated string representation of the elements in the given set - * with default element separator (",") - */ - method join() - -} - -/** - * - * A collection that contains no duplicate elements. - * It models the mathematical set abstraction. - * A Set guarantees no order of elements. - * - * @author jfernandes - * @since 1.3 - */ -class Set inherits Collection { - - /** @private */ - override method newInstance() = #{} - - /** @private */ - override method toStringPrefix() = "#{" - - /** @private */ - override method toStringSuffix() = "}" - - /** - * Converts this set to a list. - * - * Examples - * #{1, 2, 3}.asList() => Answers [1, 2, 3] - * #{}.asList() => Answers [] - * - * @see List - */ - override method asList() { - const result = [] - result.addAll(self) - return result - } - - /** - * Answers any element of a non-empty collection - * - * Examples - * #{1, 2, 3}.anyOne() => Answers 1, for example - * #{}.anyOne() => Throws error, set must not be empty - * - */ - override method anyOne() native - - /** - * Answers a new Set with the elements of both self and another collection. - * - * Examples - * #{1, 2}.union(#{5, 2}) => #{1, 2, 5} - * #{}.union(#{3}) => #{3} - * - * @returns a Set - */ - method union(another) = self + another - - /** - * Answers a new Set with the elements of self that exist in another collection - * - * Examples - * #{1, 2}.intersection(#{5, 2}) => #{2} - * #{}.intersection(#{3}) => #{} - * - * @returns a Set - */ - method intersection(another) = - self.filter({it => another.contains(it)}) - - /** - * Answers a new Set with the elements of self that don't exist in another collection - * - * Examples - * #{1, 2}.difference(#{5, 2}) => #{1} - * #{3}.difference(#{}) => #{3} - * - * @returns a Set - */ - method difference(another) = - self.filter({it => !another.contains(it)}) - - /** - * Reduce a collection to a certain value, beginning with a seed or initial value. - * - * Examples - * #{1, 9, 3, 8}.fold(0, {acum, each => acum + each}) - * => Answers 21, the sum of all elements - * - * #{}.fold(0, {acum, each => acum + each}) - * => Answers 0, the seed. - * - * var numbers = #{3, 2, 9, 1, 7} - * numbers.fold(numbers.anyOne(), { acum, number => acum.max(number) }) - * => Answers 9, the maximum of all elements - * - */ - override method fold(initialValue, closure) native - - /** - * @see Collection#filter(closure) - */ - override method filter(closure) native - - - /** - * @see Collection#max() - */ - override method max() native - - /** - * Tries to find an element in a collection (based on a closure) or - * applies a continuation closure. - * - * Examples: - * #{1, 9, 3, 8}.findOrElse({ n => n.even() }, { 100 }) => Answers 8 - * #{1, 5, 3, 7}.findOrElse({ n => n.even() }, { 100 }) => Answers 100 - */ - override method findOrElse(predicate, continuation) native - - /** - * Adds the specified element to this set if it is not already present. - * - * Example: - * const set = #{} - * set.add(3) => set = #{3} - * set.add(2) => set = #{2, 3} - * set.add(2) => set = #{2, 3}, second add produces no effect - */ - override method add(element) native - - /** - * Removes the specified element from this set if it is present. - * - * Example: - * const set = #{2, 3} - * set.remove(3) => set = #{2} - * set.remove(4) => set = #{2}, remove operation produces no effect - */ - override method remove(element) native - - /** Answers the number of elements in this set (its cardinality). - * - * Example: - * #{2, 3}.size() => Answers 2 - * #{}.size() => Answers 0 - */ - override method size() native - - /** - * Removes all of the elements from this set. This is a side effect operation. - * - * Example: - * const set = #{2, 3} - * set.clear() => set = #{} - */ - override method clear() native - - /** - * Answers the concatenated string representation of the elements in the given set. - * You can pass an optional character as an element separator (default is ",") - * - * Examples: - * #{1, 5, 3, 7}.join(":") => Answers "1:5:3:7" - * #{"you","will","love","wollok"}.join(" ") => Answers "love will wollok you" - * #{}.join(",") => Answers "" - */ - override method join(separator) native - - /** - * Answers the concatenated string representation of the elements in the given set - * with default element separator (",") - * - * Example: - * #{"you","will","love","wollok"}.join() => Answers "love,will,wollok,you" - */ - override method join() native - - /** - * - * @see List#contains(other) - */ - override method contains(other) native - - /** - * Two sets are equals if they have the same elements - * - * Examples: - * #{}.equals(#{}) => Answers true - * #{1, 2}.equals(#{2, 1}) => Answers true - * #{3, 2}.equals(#{2, 1}) => Answers false - */ - override method equals(other) native - - /** - * - * Set equality operator as defined by equals - * - * #{1, 2} == #{2, 1} => Answers true - * #{} == #{} => Answers true - * - * @see Object#== - */ - override method ==(other) native - -} - -/** - * - * An ordered collection (also known as a sequence). - * You iterate the list the same order elements are inserted. - * The user can access elements by their integer index (position in the list). - * A List can contain duplicate elements. - * - * @author jfernandes - * @since 1.3 - */ -class List inherits Collection { - - /** - * Answers the element at the specified position in this non-empty list. - * - * The first char value of the sequence is at index 0, - * the next at index 1, and so on, as for array indexing. - * Index must be a positive and integer value. - * - * Examples: - * [].get(0) => Throws error, list must not be empty - * [1].get(-1) => Throws error, index must be 0 or positive - * [1, 2, 3].get(3) => Throws error, index exceeds list size - * [5, 2, 7].get(0) => Answers 5 - */ - method get(index) native - - /** Creates a new list */ - override method newInstance() = [] - - /** - * Answers any element of a non-empty collection. - * - * Examples - * #[1, 2, 3].anyOne() => Answers 3, for example - * #[].anyOne() => Throws error, list must not be empty - */ - override method anyOne() { - self.validateNotEmpty("anyOne") - return self.get(0.randomUpTo(self.size())) - } - - /** - * Answers first element of the non-empty list - * - * @returns first element - * - * Example: - * [1, 2, 3, 4].first() => Answers 1 - * [].first() => Throws error, list must not be empty - */ - method first() = self.head() - - /** - * Synonym for first method - */ - method head() = self.get(0) - - /** - * Answers the last element of the non-empty list. - * - * @returns last element - * - * Examples: - * [1, 2, 3, 4].last() => Answers 4 - * [].last() => Throws error, list must not be empty - */ - method last() = self.get(self.size() - 1) - - /** @private */ - override method toStringPrefix() = "[" - - /** @private */ - override method toStringSuffix() = "]" - - /** - * Converts this collection to a list. No effect on Lists. - * - * @see List - */ - override method asList() = self - - /** - * Answers a view of the portion of this list between the specified start index - * and the end of the list. Remember first element is position 0, - * second is position 1, and so on. - * If toIndex exceeds length of list, no error is thrown. - * - * Example: - * [1, 5, 3, 2, 7, 9].subList(2) => Answers [3, 2, 7, 9] - * [1, 5, 3, 2, 7, 9].subList(4) => Answers [7, 9] - * [].subList(1) => Answers [] - */ - method subList(start) { - if (self.isEmpty()) return [] - if (start >= self.size()) return [] - return self.subList(start, self.size() - 1) - } - - /** - * Answers a view of the portion of this list between the specified fromIndex - * and toIndex, both inclusive. Remember first element is position 0, - * second is position 1, and so on. - * If toIndex exceeds length of list, no error is thrown. - * - * Example: - * [1, 5, 3, 2, 7, 9].subList(2, 3) => Answers [3, 2] - * [1, 5, 3, 2, 7, 9].subList(4, 6) => Answers [7, 9] - * [].subList(1, 2) => Answers [] - */ - method subList(start, end) { - self.checkNotNull(start, "subList") - self.checkNotNull(end, "subList") - if (self.isEmpty() || start >= self.size()) - return self.newInstance() - - const newList = self.newInstance() - const _start = start.coerceToInteger().limitBetween(0, self.size() - 1) - const _end = end.coerceToInteger().limitBetween(0, self.size() - 1) - (_start.._end).forEach { i => newList.add(self.get(i)) } - return newList - } - - /** - * - * Sorts elements of a list by a specific closure. - * Order of elements is modified (produces effect). - * - * Examples: - * const list = [2, 9, 3] - * list.sortBy { el1, el2 => el1 > el2 } - * list.get(0) => Answers 9 - * - * @see List#sortedBy - */ - method sortBy(closure) native - - /** - * Takes first n elements of a list. - * - * Examples: - * [1,9,2,3].take(5) ==> Answers [1, 9, 2, 3] - * [1,9,2,3].take(2) ==> Answers [1, 9] - * [1,9,2,3].take(-2) ==> Answers [] - * [].take(2) ==> Answers [] - */ - method take(n) { - self.checkNotNull(n, "take") - return if (n <= 0) self.newInstance() else self.subList(0, n - 1) - } - - /** - * Answers a new list dropping first n elements of a list. - * This operation has no side effect. - * - * Examples: - * [1, 9, 2, 3].drop(3) ==> Answers [3] - * [1, 9, 2, 3].drop(1) ==> Answers [9, 2, 3] - * [1, 9, 2, 3].drop(-2) ==> Answers [1, 9, 2, 3] - * [].drop(2) ==> Answers [] - */ - method drop(n) { - self.checkNotNull(n, "drop") - return if (n >= self.size()) self.newInstance() else self.subList(n, self.size() - 1) - } - - /** - * Answers a new list reversing the elements, - * so that first element becomes last element of the new list and so on. - * This operation has no side effect. - * - * Example: - * [1, 9, 2, 3].reverse() ==> Answers [3, 2, 9, 1] - * [1, 2].reverse() ==> Answers [2, 1] - * [].reverse() ==> Answers [] - * - */ - method reverse() = self.subList(self.size() - 1, 0) - - /** - * @see Collection#filter(closure) - */ - override method filter(closure) native - - /** - * @see Collection#contains(obj) - */ - override method contains(obj) native - - /** - * @see Collection#max() - */ - override method max() native - - /** - * Reduce a collection to a certain value, beginning with a seed or initial value - * - * Examples - * #{1, 9, 3, 8}.fold(0, {acum, each => acum + each}) - * => Answers 21, the sum of all elements - * - * [].fold(0, {acum, each => acum + each}) - * => Answers 0, the seed. - * - * var numbers = #{3, 2, 9, 1, 7} - * numbers.fold(numbers.anyOne(), { acum, number => acum.max(number) }) - * => Answers 9, the maximum of all elements - * - */ - override method fold(initialValue, closure) native - - /** - * Finds the first element matching the boolean closure, - * or evaluates the continuation block closure if no element is found - * - * Examples: - * [1, 9, 3, 8].findOrElse({ n => n.even() }, { 100 }) => Answers 8 - * [1, 5, 3, 7].findOrElse({ n => n.even() }, { 100 }) => Answers 100 - */ - override method findOrElse(predicate, continuation) native - - /** - * Adds the specified element as last one - * - * Example: - * const list = [] - * list.add(3) => list = [3] - * list.add(2) => list = [3, 2] - * list.add(2) => list = [3, 2, 2] - */ - override method add(element) native - - /** - * Removes an element in this list, if it is present. - * - * Example: - * const list = [2, 3] - * list.remove(3) => list = [2] - * list.remove(4) => list = [2], remove operation produces no effect - */ - override method remove(element) native - - /** - * Answers the number of elements - * - * Example: - * [2, 3].size() => Answers 2 - * [].size() => Answers 0 - */ - override method size() native - - /** - * Removes all of the mappings from this Dictionary. - * This is a side effect operation. - * - * Example: - * const list = [2, 3] - * list.clear() => list = [] - */ - override method clear() native - - /** - * Answers the concatenated string representation of the elements in the given set. - * You can pass an optional character as an element separator (default is ",") - * - * Examples: - * [1, 5, 3, 7].join(":") => Answers "1:5:3:7" - * ["you","will","love","wollok"].join(" ") => Answers "you will love wollok" - */ - override method join(separator) native - - /** - * - * Answers the concatenated string representation of the elements in the given set, - * using default element separator (",") - * - * Examples: - * ["you","will","love","wollok"].join() => Answers "you,will,love,wollok" - */ - override method join() native - - /** - * @see == message - */ - override method equals(other) native - - /** - * A list is == another list if all elements are equal (defined by == message) - * - * - * Examples: - * [] == [] => Answers true - * [1, 2] == [2, 1] => Answers false - * [1, 2] == [1, 2] => Answers true - */ - override method ==(other) native - - /** - * Answers the list without duplicate elements. Preserves order of elements. - * - * [1, 3, 1, 5, 1, 3, 2, 5].withoutDuplicates() => Answers [1, 3, 5, 2] - * [].withoutDuplicates() => Answers [] - */ - method withoutDuplicates() native - -} - -/** - * Represents a set of key -> values - * - */ -class Dictionary { - - /** - * Adds or updates a value based on a key. - * If key is not present, a new value is added. - * If key is present, value is updated. - * This is a side effect operation. - * - * Example: - * const phones = new Dictionary() - * phones.put("4004-4004", rolo) - * => phones == a Dictionary ["4004-4004" -> rolo] - */ - method put(_key, _value) native - - /** - * Answers the value to which the specified key is mapped, - * or null if this Dictionary contains no mapping for the key. - * - * Example, assuming phones is the dictionary created in put example: - * phones.basicGet("4004-4004") => Answers rolo - * phones.basicGet("4004-4005") => Answers null - */ - method basicGet(_key) native - - /** - * Answers the value to which the specified key is mapped, - * or evaluates a non-parameter closure otherwise. - * - * Example, assuming phones is the dictionary created in put example: - * phones.getOrElse("4004-4004", { 0 }) => Answers rolo - * phones.getOrElse("4004-4005", { 0 }) => Answers 0 - */ - method getOrElse(_key, _closure) { - const value = self.basicGet(_key) - if (value == null) - return _closure.apply() - else - return value - } - - /** - * Answers the value to which the specified key is mapped. - * If this Dictionary contains no mapping for the key, an error is thrown. - * - * Example, assuming phones is the dictionary created in put example: - * phones.get("4004-4004") => Answers rolo - * phones.get("4004-4005") => Throws ElementNotFoundException - */ - method get(_key) = self.getOrElse(_key,{ => throw new ElementNotFoundException(message = "there is no element associated with key " + _key) }) - - /** - * Answers the number of key-value mappings in this Dictionary. - * - * Example, assuming phones is the dictionary created in put example: - * phones.size() => Answers 1 - * new Dictionary().size() => Answers 0 - */ - method size() = self.values().size() - - /** - * Answers whether the dictionary has no elements - * - * Example, assuming phones is the dictionary created in put example: - * phones.isEmpty() => Answers false - * new Dictionary().isEmpty() => Answers true - */ - method isEmpty() = self.size() == 0 - - /** - * Answers whether this Dictionary contains a mapping for the specified key. - * - * Example, assuming phones is the dictionary created in put example: - * phones.containsKey("4004-4004") => Answers true - * phones.containsKey("4004-4005") => Answers false - * new Dictionary().containsKey(1) => Answers false - */ - method containsKey(_key) = self.keys().contains(_key) - - /** - * Answers whether if this Dictionary maps one or more keys to the specified value. - * - * Example: - * const numbers = new Dictionary() - * numbers.put("one", 1) - * numbers.put("two", 2) - * numbers.containsValue(2) => Answers true - * numbers.containsValue(5) => Answers false - * new Dictionary().containsValue(3) => Answers false - */ - method containsValue(_value) = self.values().contains(_value) - - /** - * Removes the mapping for a key from this Dictionary if it is present. - * If key is not present nothing happens. - * This is a side effect operation. - * - * Example: - * const numbers = new Dictionary() - * numbers.put("one", 1) - * numbers.put("two", 2) - * numbers.remove("one") => numbers is a dictionary ("two" -> 2) - * numbers.remove("three") => nothing happens - */ - method remove(_key) native - - /** - * Answers a list of the keys contained in this Dictionary. - * - * Example: - * const numbers = new Dictionary() - * numbers.put("one", 1) - * numbers.put("two", 2) - * numbers.keys() => ["one", "two"] - */ - method keys() native - - /** - * Answers a list of the values contained in this Dictionary. - * - * Example: - * const numbers = new Dictionary() - * numbers.put("one", 1) - * numbers.put("two", 2) - * numbers.values() => [1, 2] - */ - method values() native - - /** - * Performs the given action for each entry in this Dictionary - * until all entries have been processed or the action throws an exception. - * - * Expected closure with two parameters: the first associated with key and - * second with value. - * - * Example: - * mapaTelefonos.forEach({ k, v => result += k.size() + v.size() }) - * - */ - method forEach(closure) native - - /** - * Removes all of the mappings from this Dictionary. - * This is a side effect operation. - * - * Example: - * const numbers = new Dictionary() - * numbers.put("one", 1) - * numbers.put("two", 2) - * numbers.clear() => phones == empty dictionary - */ - method clear() native - - /** - * String representation of a Dictionary - * - * Example: - * const numbers = new Dictionary() - * numbers.put("one", 1) - * numbers.put("two", 2) - * => Answers a Dictionary ["one" -> 1, "two" -> 2] - */ - override method toString() { - var result = "a Dictionary [" - self.forEach { key, value => result = result + (key.printString() + " -> " + value.printString() + ", ") } - if (self.size() > 0) result = result.substring(0, result.length() - 2) - return result + "]" - } - - /** - * Two dictionaries are equal if they have the same keys and values - */ - override method equals(other) { - self.checkNotNull(other, "equals") - return self.keys() == other.keys() && self.values() == other.values() - } - -} - -/** - * - * In Wollok we have numbers as an immutable representation. You can customize - * how many decimals you want to work with, and printing strategies. So - * number two could be printed as "2", "2,00000", "2,000", etc. - * - * Coercing strategy for numbers can be - * 1) rounding up: 2,3258 using 3 decimals will result in 2,326 - * 2) rounding down or truncation: 2,3258 using 3 decimals will - * result in 2,325 - * 3) not allowed: 2,3258 using 3 decimals will throw an exception - * since decimals exceeds maximum allowed - * - * @author jfernandes - * @author dodain (unification between Double and Integer in a single Number class) - * - * @since 1.3 - * @noInstantiate - */ -class Number { - - /** @private */ - override method simplifiedToSmartString(){ return self.stringValue() } - - /** @private */ - override method internalToSmartString(alreadyShown) { return self.stringValue() } - - /** - * @private - * - * Applies coercing strategy to integer. If it is an integer, nothing happens. - * Otherwise, if it is a decimal, defined coercing algorithm is applied - * (see definition of class Number) - */ - method coerceToInteger() native - - /** - * @private - * @see coerceToInteger - * - * Applies coercing strategy to integer. And throws exception if it is negative. - */ - method coerceToPositiveInteger() native - - /** - * Two references are identical if they are the same number - */ - override method ===(other) native - - method +(other) native - method -(other) native - method *(other) native - method /(other) native - - /** - * Integer division between self and other - * - * Example: - * 8.div(3) ==> Answers 2 - * 15.div(5) ==> Answers 3 - * 8.2.div(3.3) ==> Answers 2 - */ - method div(other) { - self.checkNotNull(other, "div") - return (self / other).truncate(0) - } - - /** - * raisedTo operation - * - * Example: - * 3.2 ** 2 ==> Answers 10.24 - * 3 ** 2 ==> Answers 9 - */ - method **(other) native - - /** - * Answers remainder of division between self and other - */ - method %(other) native - - /** String representation of self number */ - override method toString() native - - /** @private */ - override method toSmartString(alreadyShown) = self.toString() - - /** - * Builds a Range between self and end - * - * Example: - * 1..4 Answers ==> a new Range object from 1 to 4 - */ - method ..(end) { - self.checkNotNull(end, "..") - return new Range(start = self, end = end) - } - - method >(other) native - method <(other) native - - method >=(other) = self > other || self == other - method <=(other) = self < other || self == other - - /** - * Answers absolute value of self - * - * Example: - * 2.abs() ==> 2 - * (-3).abs() ==> 3 (be careful with parentheses) - * 2.7.abs() ==> Answers 2.7 - * (-3.2).abs() ==> Answers 3.2 (be careful with parentheses) - */ - method abs() native - - /** - * Inverts sign of self - * - * Example: - * 3.invert() ==> Answers -3 - * (-2).invert() ==> Answers 2 (be careful with parentheses) - * 3.2.invert() ==> -3.2 - * (-2.4).invert() ==> 2.4 (be careful with parentheses) - */ - method invert() native - - /** - * Answers the greater number between two - * Example: - * 5.max(8) ==> Answers 8 - */ - method max(other) { - self.checkNotNull(other, "max") - return if (self >= other) self else other - } - - /** - * Answers the lower number between two. @see max - * Example: - * 5.min(8) ==> Answers 5 - */ - method min(other) { - self.checkNotNull(other, "min") - return if (self <= other) self else other - } - - /** - * Given self and a range of integer values, - * answers self if it is in that range - * or nearest value from self to that range - * - * Examples - * 4.limitBetween(2, 10) ==> Answers 4, because 4 is in the range - * 4.limitBetween(6, 10) ==> Answers 6, because 4 is not in range 6..10, and 6 is nearest value to 4 - * 4.limitBetween(1, 2) ==> Answers 2, because 4 is not in range 1..2, but 2 is nearest value to 4 - * - */ - method limitBetween(limitA, limitB) { - self.checkNotNull(limitA, "limitBetween") - self.checkNotNull(limitB, "limitBetween") - return - if (limitA <= limitB) - limitA.max(self).min(limitB) - else - limitB.max(self).min(limitA) - } - - /** - * Answers whether self is between min and max - * - * Example: - * 2.between(2, 3) ==> Answers true - * 6.between(4, 6) ==> Answers true - * 3.between(4, 6) ==> Answers false - */ - method between(min, max) = (self >= min) && (self <= max) - - /** Answers squareRoot of self - * - * Example: - * 9.squareRoot() => Answers 3 - */ - method squareRoot() = self ** 0.5 - - /** Answers square of self - * - * Example: - * 3.square() => Answers 9 - */ - method square() = self * self - - /** - * Answers whether self is an even number - * (divisible by 2, mathematically 2k). - * - * Self must be an integer value - */ - method even() = self % 2 == 0 - - /** - * Answers whether self is an odd number - * (not divisible by 2, mathematically 2k + 1). - * - * Self must be an integer value - */ - method odd() { - if (!self.isInteger()) return false - return !self.even() - } - - /** Answers remainder between self and other - * - * Example: - * 5.rem(3) ==> Answers 2 - * 5.5.rem(3) ==> Answers 2 - */ - method rem(other) { - self.checkNotNull(other, "rem") - return self % other - } - - /* - * Self as String value. Equivalent: toString() - */ - method stringValue() = self.toString() - - /** - * Rounds up self up to a certain amount of decimals. - * Amount of decimals must be a positive and integer value. - * - * Example: - * 1.223445.roundUp(3) ==> 1.224 - * -1.223445.roundUp(3) ==> -1.224 - * 14.6165.roundUp(3) ==> 14.617 - * 5.roundUp(3) ==> 5 - */ - method roundUp(_decimals) native - - /** - * Truncates self up to a certain amount of decimals. - * Amount of decimals must be a positive and integer value. - * - * Example: - * 1.223445.truncate(3) ==> 1.223 - * 14.6165.truncate(3) ==> 14.616 - * -14.6165.truncate(3) ==> -14.616 - * 5.truncate(3) ==> 5 - */ - method truncate(_decimals) native - - /** - * Answers a random number between self and max - */ - method randomUpTo(max) native - - /** - * Answers the next integer greater than self - * 13.224.roundUp() ==> 14 - * -13.224.roundUp() ==> -14 - * 15.942.roundUp() ==> 16 - */ - method roundUp() = self.roundUp(0) - - /** - * greater common divisor. - * Both self and "other" parameter are coerced to be integer values. - * - * Example: - * 8.gcd(12) ==> Answers 4 - * 5.gcd(10) ==> Answers 5 - */ - method gcd(other) native - - /** - * least common multiple. - * Both self and "other" parameter are coerced to be integer values. - * - * Example: - * 3.lcm(4) ==> Answers 12 - * 6.lcm(12) ==> Answers 12 - */ - method lcm(other) { - self.checkNotNull(other, "lcm") - const mcd = self.gcd(other) - return self * (other / mcd) - } - - /** - * Number of digits of self (without sign) - * - * Examples: - * 600.digits() ==> Answers 3 - * 6.00012.digits() ==> Answers 6 - * -100.digits() ==> Answers -3 - */ - method digits() { - var digits = self.toString().size() - if (self < 0) { - digits -= 1 - } - if (!self.isInteger()) { - digits -= 1 - } - return digits - } - - /** - * Tells if this number can be considered an integer number. - * - * Examples: - * 2.isInteger() ==> Answers true - * (2.0).isInteger() ==> Answers true - * (2.3).isInteger() ==> Answers false - * - * This could depend also on the rounding strategy, for example: - * (2.0001).isInteger() ==> Answers false if rounding strategy is set to 5 decimal places (default) - * (2.0001).isInteger() ==> Answers true if rounding strategy is set to 3 decimal places - */ - method isInteger() native - - /** Answers whether self is a prime number, - * like 2, 3, 5, 7, 11 ... - * Self must be an integer positive value - */ - method isPrime() { - const intValue = self.coerceToInteger() - if (intValue == 1) return false - return (2..(intValue.div(2) + 1)).any({ i => intValue % i == 0 }).negate() - } - - /** - * Executes the given action n times (n = self) - * - * Self must be a positive integer value. - * The closure must have one argument (index goes from 1 to self) - * - * Example: - * 4.times({ i => console.println(i) }) ==> Answers - * 1 - * 2 - * 3 - * 4 - */ - method times(action) { - self.checkNotNull(action, "times") - const intValue = self.coerceToInteger() - if (intValue < 0) self.error("times requires a positive integer number") - if (intValue > 0) (1..intValue).forEach(action) - } - - /** Allows users to define a positive number with 1 or +1 */ - method plus() = self -} - -/** - * Strings are constant; - * their values cannot be changed after they are created. - * - * @author jfernandes - * @noInstantiate - */ -class String { - /** Answers the number of elements */ - method length() native - - /** - * Answers the char value at the specified index. An index ranges - * from 0 to length() - 1. The first char value of the sequence is - * at index 0, the next at index 1, and so on, as for array indexing. - * Parameter index must be a positive integer value. - */ - method charAt(index) { - self.checkNotNull(index, "charAt") - if (!index.isInteger()) throw new DomainException(message = "charAt expects an integer instead of " + index) - return self.substring(index, index + 1) - } - - /** - * Concatenates the specified string to the end of this string. - * Example: - * "cares" + "s" => Answers "caress" - */ - method +(other) = self.concat(other.toString()) - - /** - * Concatenates the specified string to the end of this string. Same as +. - * Example: - * "cares".concat("s") => Answers "caress" - */ - method concat(other) native - - - /** - * Tests if this string starts with the specified prefix. - * It is case sensitive. - * - * Examples: - * "mother".startsWith("moth") ==> Answers true - * "mother".startsWith("Moth") ==> Answers false - */ - method startsWith(other) native - - /** - * Tests if this string ends with the specified suffix. - * It is case sensitive. - * @see startsWith - */ - method endsWith(other) native - - /** - * Answers the index within this string of the first occurrence - * of the specified character. - * If character is not present, Answers -1 - * - * Examples: - * "pototo".indexOf("o") ==> Answers 1 - * "unpredictable".indexOf("o") ==> Answers -1 - */ - method indexOf(other) native - - /** - * Answers the index within this string of the last - * occurrence of the specified character. - * If character is not present, Answers -1 - * - * Examples: - * "pototo".lastIndexOf("o") ==> Answers 5 - * "unpredictable".lastIndexOf("o") ==> Answers -1 - */ - method lastIndexOf(other) native - - /** - * Converts all of the characters in this String to lower case - * - * Examples: - * "Fer".toLowerCase() ==> Answers "fer" - * "".toLowerCase() ==> Answers "" - */ - method toLowerCase() native - - /** - * Converts all of the characters in this String to upper case - * - * Examples: - * "Fer".toUpperCase() ==> Answers "FER" - * "".toUpperCase() ==> Answers "" - */ - method toUpperCase() native - - /** - * Answers a string whose value is this string, - * with any leading and trailing whitespace removed. - * - * Example: - * " emptySpace ".trim() ==> "emptySpace" - */ - method trim() native - - /** - * Answers a string reversing this string, - * so that first character becomes last character of the new string and so on. - * - * Example: - * "hola".reverse() ==> "aloh" - */ - method reverse() native - - /** - * @see take - * - * Example: - * "word".takeLeft(3) ==> Answers "wor" - * "word".takeLeft(0) ==> Answers "" - * "word".takeLeft(-1) ==> Throws error - * "".takeLeft(2) ==> Answers "" - */ - method takeLeft(length) = self.take(length) - - /** - * Takes last n characters of this string. - * n must be zero-positive integer. - * - * Example: - * "word".takeRight(3) ==> Answers "ord" - * "word".takeRight(0) ==> Answers "" - * "word".takeRight(-1) ==> Throws error - * "".takeRight(2) ==> Answers "" - */ - method takeRight(_length) { - const length = _length.coerceToPositiveInteger().min(self.size()) - return self.drop(self.size() - length) - } - - method <(aString) native - method <=(aString) { - return self < aString || (self.equals(aString)) - } - method >(aString) native - method >=(aString) { - return self > aString || (self.equals(aString)) - } - - /** - * Answers whether this string contains the specified sequence of char values. - * It is a case sensitive test. - * - * Examples: - * "unusual".contains("usual") ==> Answers true - * "become".contains("CO") ==> Answers false - */ - method contains(other) native - - /** Answers whether this string has no characters */ - method isEmpty() = self.size() == 0 - - /** - * Compares this String to another String, ignoring case considerations. - * - * Example: - * "WoRD".equalsIgnoreCase("Word") ==> Answers true - */ - method equalsIgnoreCase(aString) { - self.checkNotNull(aString, "equalsIgnoreCase") - return self.toUpperCase() == aString.toUpperCase() - } - - /** - * Answers a substring of this string beginning from - * an inclusive index. Parameter index must be a positive - * integer value. - * - * Examples: - * "substitute".substring(6) ==> Answers "tute", second "t" is in position 6 - * "effect".substring(0) ==> Answers "effect", has no effect at all - */ - method substring(index) native - - /** - * Answers a substring of this string beginning - * from an inclusive index up to another inclusive index - * - * Examples: - * "walking".substring(2, 4) ==> Answers "lk" - * "walking".substring(3, 5) ==> Answers "ki" - * "walking".substring(0, 5) ==> Answers "walki" - * "walking".substring(0, 45) ==> throws an out of range exception - */ - method substring(startIndex, length) native - - /** - * Splits this string around matches of the given string. - * Answers a list of strings. - * - * Example: - * "this,could,be,a,list".split(",") - * ==> Answers ["this", "could", "be", "a", "list"] - */ - method split(expression) { - self.checkNotNull(expression, "split") - const result = [] - var me = self.toString() + expression - var first = 0 - (0..me.size() - 1).forEach { i => - if (me.charAt(i) == expression) { - result.add(me.substring(first, i)) - first = i + 1 - } - } - return result - } - - /** - * Answers a string resulting from replacing all occurrences of - * expression in this string with replacement - * - * Example: - * "stupid is what stupid does".replace("stupid", "genius") - * ==> Answers "genius is what genius does" - */ - method replace(expression, replacement) native - - /** This object (which is already a string!) is itself returned */ - override method toString() native - - /** String implementation of printString, - * simply adds quotation marks - */ - override method printString() = '"' + self.toString() + '"' - - /** @private */ - override method toSmartString(alreadyShown) native - - /** Compares this string to the specified object. - * The result is true if and only if the - * argument is not null and is a String object - * that represents the same sequence of characters as this object. - */ - override method ==(other) native - - /** A synonym for length */ - method size() = self.length() - - /** - * Takes first n characters of this string. - * n must be zero-positive integer. - * - * Examples: - * "lowercase".take(3) ==> Answers "low" - * "lowercase".take(0) ==> Answers "" - * "lowercase".take(-1) ==> Throws error - * "".take(2) ==> Answers "" - */ - method take(n) { - self.checkNotNull(n, "take") - return self.substring(0, n.min(self.size())) - } - - /** - * Answers a new string dropping - * first n characters of this string. - * n must be zero-positive integer. - * - * Examples: - * "caption".drop(4) ==> Answers "ion" - * "caption".drop(0) ==> Answers "caption" - * "caption".drop(-1) ==> Throws error - * "".drop(2) ==> Answers "" - */ - method drop(n) { - self.checkNotNull(n, "drop") - return self.substring(n.min(self.size()), self.size()) - } - - /** - * Splits this strings into several words. - * - * Examples: - * "how does words work?".words() - * ==> Answers ["how", "does", "words", "work?"] - * - * "".words() ==> Answers [] - */ - method words() = self.split(" ") - - /** - * Changes the first letter of every word to - * upper case in this string. - * - * Example: - * "javier fernandes".capitalize() ==> Answers "Javier Fernandes" - */ - method capitalize() { - const capitalizedPhrase = self.words().fold("", { words, word => words + word.take(1).toUpperCase() + word.drop(1).toLowerCase() + " " }) - return capitalizedPhrase.take(capitalizedPhrase.size() - 1) - } - -} - -/** - * Represents a Boolean value (true or false) - * - * @author jfernandes - * @noInstantiate - */ -class Boolean { - - /** - * Answers the result of applying the logical AND operator - * to the specified boolean operands self and other - */ - method and(other) native - - /** A synonym for and operation */ - method &&(other) native - - /** Answers the result of applying the logical OR operator - * to the specified boolean operands self and other - */ - method or(other) native - - /** A synonym for or operation */ - method ||(other) native - - /** Answers a String object representing this Boolean's value. */ - override method toString() native - - /** @private */ - override method toSmartString(alreadyShown) native - - /** Compares this string to the specified object. - * The result is true if and only if the - * argument is not null and represents same value - * (true or false) - */ - override method ==(other) native - - /** NOT logical operation */ - method negate() native -} - -/** - * Represents a finite arithmetic progression - * of integer numbers with optional step - * If start = 1, end = 8, Range will represent [1, 2, 3, 4, 5, 6, 7, 8] - * If start = 1, end = 8, step = 3, Range will represent [1, 4, 7] - * - * @author jfernandes - * @since 1.3 - */ -class Range { - var start - var end - var property step = null - - /** - * Instantiates a Range. - * Both start and end must be integer values. - */ - method initialize() { - start = start.truncate(0) - end = end.truncate(0) - if (step == null) { - if (start > end) { - step = -1 - } else { - step = 1 - } - } - } - - /** - * Getter for start attribute - */ - method start() = start - - /** - * Getter for end attribute - */ - method end() = end - - /** - * Setter for step attribute. - */ - method step(_step) { - self.checkNotNull(_step, "step") - step = _step.coerceToInteger() - } - - /** - * Iterates over a Range from start to end, based on step. - * - * Example: - * new Range(start = 1, end = 3).forEach { value => console.println(value) } - * => prints 1, 2, 3 - */ - method forEach(closure) native - - /** - * Answers a new collection that contains the result of - * transforming each of self collection's elements using - * a given closure. - * - * The condition is a closure argument that takes an integer - * and answers an object. - * @returns another list - * - * Example: - * (1..10).map({ n => n * 2}) ==> Answers [2, 4, 6, 8, 10, 12, 14, 16, 18, 20] - */ - method map(closure) { - self.checkNotNull(closure, "map") - const list = [] - self.forEach { element => list.add(closure.apply(element)) } - return list - } - - /** - * Map + flatten operation - * @see map - * @see flatten - * - * Example: - * (1..4).flatMap({ n => 1 .. n }) ==> Answers [1, 1, 2, 1, 2, 3, 1, 2, 3, 4] - */ - method flatMap(closure) { - self.checkNotNull(closure, "flatMap") - return self.fold([], { seed, element => - seed.addAll(closure.apply(element)) - seed - }) - } - - /** @private */ - method asList() { - return self.map({ elem => elem }) - } - - /** - * Answers whether this range contains no elements - * @see Collection#isEmpty() - */ - method isEmpty() = self.size() == 0 - - /** @see List#fold(seed, foldClosure) */ - method fold(seed, foldClosure) = self.asList().fold(seed, foldClosure) - - /** - * Answers the number of elements - * - * Examples: - * new Range(start = 0, end = 2).size() ==> Answers 3 - * new Range(start = -2, end = 2).size() ==> Answers 5 - */ - method size() { - const base = (end - start) / step - return if (base >= 0) base.truncate(0) + 1 else 0 - } - - /** @see List#any(closure) */ - method any(closure) = self.asList().any(closure) - - /** @see List#all(closure) */ - method all(closure) = self.asList().all(closure) - - /** @see List#filter(closure) */ - method filter(closure) = self.asList().filter(closure) - - /** @see List#min() */ - method min() = self.asList().min() - - /** @see List#max() */ - method max() = self.asList().max() - - /** - * Answers a random integer contained in the range - * - * Example: - * new Range(start = 1, end = 3).anyOne() ==> Answers 1 or 2 or 3 - */ - method anyOne() native - - /** - * Tests whether a number e is contained in the range - * - * Examples: - * new Range(start = 2, end = 5).contains(4) ==> Answers true - * new Range(start = 2, end = 5).contains(0) ==> Answers false - */ - method contains(element) = self.asList().contains(element) - - /** @see List#sum() */ - method sum() = self.asList().sum() - - /** - * Sums all elements that match the boolean closure - * - * Example: - * (1..9).sum({ i => if (i.even()) i else 0 }) ==> Answers 20 - */ - method sum(closure) = self.asList().sum(closure) - - /** - * Counts how many elements match the boolean closure - * - * Example: - * (1..9).count({ i => i.even() }) ==> Answers 4 (2, 4, 6 and 8 are even) - */ - method count(closure) = self.asList().count(closure) - - /** @see List#find(closure) */ - method find(closure) = self.asList().find(closure) - - /** @see List#findOrElse(predicate, continuation) */ - method findOrElse(closure, continuation) = self.asList().findOrElse(closure, continuation) - - /** @see List#findOrDefault(predicate, value) */ - method findOrDefault(predicate, value) = self.asList().findOrDefault(predicate, value) - - /** @see List#sortBy */ - method sortedBy(closure) = self.asList().sortedBy(closure) - - /** @private */ - override method internalToSmartString(alreadyShown) = start.toString() + ".." + end.toString() -} - -/** - * - * Represents an executable piece of code. You can create a closure, - * assign it to a reference, evaluate it many times, - * send it as parameter to another object, and many useful things. - * - * @author jfernandes - * @since 1.3 - * @noInstantiate - */ -class Closure { - - method initialize() native - - /** Evaluates this closure passing its parameters - * - * Example: - * { number => number + 1 }.apply(8) ==> Answers 9 // 1 parameter - * { "screw" + "driver" }.apply() ==> Answers "screwdriver" // no parameter - */ - method apply(parameters...) native - - /** Answers a string representation of this closure object */ - override method toString() native - -} - -/** Represents days of week. */ - -object monday { } -object tuesday { } -object wednesday { } -object thursday { } -object friday { } -object saturday { } -object sunday { } -const daysOfWeek = [monday, tuesday, wednesday, thursday, friday, saturday, sunday] - -/** - * - * Represents a Date (without time). A Date is immutable, once created you can not change it. - * - * @since 1.4.5 - */ -class Date { - - const property day - const property month - const property year - - /** @private */ - method initialize() native - - /** String representation of a date */ - override method toString() = self.toSmartString(false) - - /** Two dates are equals if they represent the same date */ - override method ==(_aDate) native - - /** - * Answers a copy of this Date with the specified number of days added. - * Parameter must be an integer value. - * This operation has no side effect (a new date is returned). - * - * Example: - * new Date(day = 12, month = 5, year = 2018).plusDays(1) - * ==> Answers 13/5/2018, a day forward - * - * new Date(day = 12, month = 5, year = 2018).plusDays(-1) - * ==> Answers 11/5/2018, a day back - */ - method plusDays(_days) native - - /** - * Answers a copy of this Date with the specified number of months added. - * Parameter must be an integer value. - * This operation has no side effect (a new date is returned). - * - * Example: - * new Date(day = 31, month = 1, year = 2018).plusMonths(1) - * ==> Answers 28/2/2018, a month forward - * - * new Date(day = 12, month = 5, year = 2018).plusMonths(-1) - * ==> Answers 12/4/2018, a month back - */ - method plusMonths(_months) native - - /** - * Answers a copy of this Date with the specified number of years added. - * Parameter must be an integer value. - * This operation has no side effect (a new date is returned). - * - * Example: - * new Date(day = 31, month = 1, year = 2018).plusYears(1) - * ==> Answers 31/1/2019, a year forward - * - * new Date(day = 12, month = 5, year = 2018).plusYears(-1) - * ==> Answers 12/5/2017, a year back - */ - method plusYears(_years) native - - /** - * Checks if the year is a leap year, like 2000, 2004, 2008... - * - * Example: - * new Date(day = 12, month = 5, year = 2018).isLeapYear() ==> Answers false - */ - method isLeapYear() native - - /** Answers the day of the week of the Date with an object representation. - * There is a wko (well known object) for every day of the week. - * - * Example: - * new Date(day = 24, month = 2, year = 2018).dayOfWeek() ==> Answers saturday object - */ - method dayOfWeek() = daysOfWeek.get(self.internalDayOfWeek() - 1) - - /** Answers the day of week of the Date, where - * 1 = MONDAY - * 2 = TUESDAY - * 3 = WEDNESDAY - * ... - * 7 = SUNDAY - * - * Example: - * new Date(day = 24, month = 2, year = 2018).internalDayOfWeek() ==> Answers 6 (SATURDAY) - */ - method internalDayOfWeek() native - - /** - * Answers the difference in days between two dates, assuming self is minuend and _aDate is subtrahend. - * - * Examples: - * new Date().plusDays(4) - new Date() ==> Answers 4 - * new Date() - new Date().plusDays(2) ==> Answers -2 - */ - method -(_aDate) native - - /** - * Answers a copy of this date with the specified number of days subtracted. - * This instance is immutable and unaffected by this method call. - * Parameter must be an integer value. - * This operation has no side effect (a new date is returned). - * - * Examples: - * new Date(day = 1, month = 1, year = 2009).minusDays(1) - * ==> Answers 31/12/2008, a day back - * - * new Date(day = 1, month = 1, year = 2009).minusDays(-1) - * ==> Answers 2/1/2009, a day forward - */ - method minusDays(_days) native - - /** - * Answers a copy of this date with the specified number of months subtracted. - * Parameter must be an integer value. - * This operation has no side effect (a new date is returned). - * - * Examples: - * new Date(day = 1, month = 1, year = 2009).minusMonths(1) - * ==> Answers 1/12/2008, a month back - * - * new Date(day = 1, month = 1, year = 2009).minusMonths(-1) - * ==> Answers 1/2/2009, a month forward - */ - method minusMonths(_months) native - - /** - * Answers a copy of this date with the specified number of years subtracted. - * Parameter must be an integer value. - * This operation has no side effect (a new date is returned). - * - * Examples: - * new Date(day = 1, month = 1, year = 2009).minusYears(1) - * ==> Answers 1/1/2008, a year back - * - * new Date(day = 1, month = 1, year = 2009).minusYears(-1) - * ==> Answers 1/1/2010, a year forward - */ - method minusYears(_years) native - - method <(_aDate) native - method >(_aDate) native - method <=(_aDate) = (self < _aDate) || (self.equals(_aDate)) - method >=(_aDate) = (self > _aDate) || (self.equals(_aDate)) - - /** - * Answers whether self is between two dates (both inclusive comparison) - * - * Example: - * new Date(day = 2, month = 4, year = 2018).between(new Date(day = 1, month = 4, year = 2018), new Date(day = 2, month = 4, year = 2018)) - * ==> Answers true - */ - method between(_startDate, _endDate) = (self >= _startDate) && (self <= _endDate) - - /** Shows nicely an internal representation of a date **/ - override method toSmartString(alreadyShown) = - self.shortDescription() - - /** - * Shows a short, internal representation of a date - * (the result varies depending on user's locale) - * - * Example: - * new Date(day = 2, month = 4, year = 2018).shortDescription() - * ==> Answers 2/4/2018 - */ - override method shortDescription() native - -} - -object io { - const eventHandlers = new Dictionary() - var eventQueue = [] - - method queueEvent(event) { - eventQueue.add(event) - } - - // TODO: removeHandler - method addHandler(event, callback) { - if (!eventHandlers.containsKey(event)) eventHandlers.put(event, []) - eventHandlers.get(event).add(callback) - } - - method flushEvents() { - const currentEvents = eventQueue.copy() - eventQueue = [] - currentEvents.forEach{ event => - eventHandlers.getOrElse(event, { [] }).forEach{ callback => callback.apply() } - } - } -} diff --git a/org.uqbar.project.wollok.lib/src/wollok/lib.wlk b/org.uqbar.project.wollok.lib/src/wollok/lib.wlk deleted file mode 100644 index 78e904a87e..0000000000 --- a/org.uqbar.project.wollok.lib/src/wollok/lib.wlk +++ /dev/null @@ -1,253 +0,0 @@ -/** - * Console is a global wollok object that implements a character-based console device - * called "standard input/output" stream - */ -object console { - - /** Prints a String with end-of-line character */ - method println(obj) native - - /** Reads a line from input stream */ - method readLine() native - - /** Reads an int character from input stream */ - method readInt() native - - /** Returns the system's representation of a new line: - * - \n in Unix systems - * - \r\n in Windows systems - */ - method newline() native -} - -/** - * Exception to handle other values expected in assert.throwsException... methods - */ -class OtherValueExpectedException inherits wollok.lang.Exception {} - -/** - * Exception to handle difference between current and expected values - * in assert.throwsException... methods - */ -class AssertionException inherits Exception { - const property expected = null - const property actual = null -} - -/** - * Assert object simplifies testing conditions - */ -object assert { - - /** - * Tests whether value is true. Otherwise throws an exception. - * - * Example: - * assert.that(7.even()) ==> throws an exception "Value was not true" - * assert.that(8.even()) ==> ok, nothing happens - */ - method that(value) { - self.checkNotNull(value, "that") - if (!value) throw new AssertionException(message = "Value was not true") - } - - /** Tests whether value is false. Otherwise throws an exception. - * @see assert#that(value) - */ - method notThat(value) { - self.checkNotNull(value, "notThat") - if (value) throw new AssertionException(message = "Value was not false") - } - - /* - * This method avoids confusion with equals definition in Object - */ - override method equals(value) { - throw new AssertionException(message = "assert.equals(expected, actual): missing second parameter") - } - - /** - * Tests whether two values are equal, based on wollok ==, != methods - * - * Examples: - * assert.equals(10, 100.div(10)) ==> ok, nothing happens - * assert.equals(10.0, 100.div(10)) ==> ok, nothing happens - * assert.equals(10.01, 100.div(10)) ==> throws an exception - */ - method equals(expected, actual) { - if (expected != actual) throw new AssertionException(message = "Expected [" + expected.printString() + "] but found [" + actual.printString() + "]") - } - - /** - * Tests whether two values are equal, based on wollok ==, != methods - * - * Examples: - * const value = 5 - * assert.notEquals(10, value * 3) ==> ok, nothing happens - * assert.notEquals(10, value) ==> throws an exception - */ - method notEquals(expected, actual) { - if (expected == actual) throw new AssertionException(message = "Expected to be different, but [" + expected.printString() + "] and [" + actual.printString() + "] match") - } - - /** - * Tests whether a block throws an exception. Otherwise an exception is thrown. - * - * Examples: - * assert.throwsException({ 7 / 0 }) - * ==> Division by zero error, it is expected, ok - * - * assert.throwsException({ "hola".length() }) - * ==> throws an exception "Block should have failed" - */ - method throwsException(block) { - self.checkNotNull(block, "throwsException") - var failed = false - try { - block.apply() - } catch e { - failed = true - } - if (!failed) throw new AssertionException(message = "Block " + block + " should have failed") - } - - /** - * Tests whether a block throws an exception and this is the same expected. - * Otherwise an exception is thrown. - * - * Examples: - * assert.throwsExceptionLike(new BusinessException("hola"), - * { => throw new BusinessException("hola") } - * => Works! Exception class and message both match. - * - * assert.throwsExceptionLike(new BusinessException("chau"), - * { => throw new BusinessException("hola") } - * => Doesn't work. Exception class matches but messages are different. - * - * assert.throwsExceptionLike(new OtherException("hola"), - * { => throw new BusinessException("hola") } - * => Doesn't work. Messages matches but they are instances of different exceptions. - */ - method throwsExceptionLike(exceptionExpected, block) { - self.checkNotNull(exceptionExpected, "throwsExceptionLike") - self.checkNotNull(block, "throwsExceptionLike") - try - { - self.throwsExceptionByComparing(block, {a => a.equals(exceptionExpected)}) - } - catch ex : OtherValueExpectedException - { - throw new AssertionException(message = "The Exception expected was " + exceptionExpected + " but got " + ex.cause()) - } - } - - /** - * Tests whether a block throws an exception and it has the error message as is expected. - * Otherwise an exception is thrown. - * - * Examples: - * assert.throwsExceptionWithMessage("hola",{ => throw new BusinessException(message = "hola") } - * => Works! Both have the same message. - * - * assert.throwsExceptionWithMessage("hola",{ => throw new OtherException(message = "hola") } - * => Works! Both have the same message. - * - * assert.throwsExceptionWithMessage("chau",{ => throw new BusinessException(message = "hola") } - * => Doesn't work. Both are instances of BusinessException but their messages differ. - */ - method throwsExceptionWithMessage(errorMessage, block) { - self.checkNotNull(errorMessage, "throwsExceptionWithMessage") - self.checkNotNull(block, "throwsExceptionWithMessage") - try - { - self.throwsExceptionByComparing(block, {a => errorMessage.equals(a.message())}) - } - catch ex : OtherValueExpectedException - { - throw new AssertionException(message = "The error message expected was " + errorMessage + " but got " + ex.cause().message()) - } - } - - /** - * Tests whether a block throws an exception and this is the same exception class expected. - * Otherwise an exception is thrown. - * - * Examples: - * assert.throwsExceptionWithType(new BusinessException("hola"),{ => throw new BusinessException("hola") } - * => Works! Both exceptions are instances of the same class. - * - * assert.throwsExceptionWithType(new BusinessException("chau"),{ => throw new BusinessException("hola") } - * => Works again! Both exceptions are instances of the same class. - * - * assert.throwsExceptionWithType(new OtherException("hola"),{ => throw new BusinessException("hola") } - * => Doesn't work. Exception classes differ although they contain the same message. - */ - method throwsExceptionWithType(exceptionExpected, block) { - self.checkNotNull(exceptionExpected, "throwsExceptionWithType") - self.checkNotNull(block, "throwsExceptionWithType") - try - { - self.throwsExceptionByComparing(block,{a => exceptionExpected.className().equals(a.className())}) - } - catch ex : OtherValueExpectedException - { - throw new AssertionException(message = "The exception expected was " + exceptionExpected.className() + " but got " + ex.cause().className()) - } - } - - /** - * Tests whether a block throws an exception and compare this exception with other block - * called comparison. Otherwise an exception is thrown. The block comparison - * receives a value (an exception thrown) that is compared in a boolean expression - * returning the result. - * - * Examples: - * assert.throwsExceptionByComparing({ => throw new BusinessException("hola"),{ex => "hola".equals(ex.message())}} - * => Works!. - * - * assert.throwsExceptionByComparing({ => throw new BusinessException("hola"),{ex => new BusinessException("lele").className().equals(ex.className())} } - * => Works again! - * - * assert.throwsExceptionByComparing({ => throw new BusinessException("hola"),{ex => "chau!".equals(ex.message())} } - * => Doesn't work. The block evaluation resolves to a false value. - */ - method throwsExceptionByComparing(block, comparison){ - self.checkNotNull(block, "throwsExceptionByComparing") - self.checkNotNull(comparison, "throwsExceptionByComparing") - var continue = false - try - { - block.apply() - continue = true - } - catch ex - { - if(comparison.apply(ex)) - self.that(true) - else - throw new OtherValueExpectedException(message = "Expected other value", cause = ex) - } - if (continue) throw new AssertionException(message = "Should have thrown an exception") - } - - /** - * Throws an exception with a custom message. - * Useful when you reach code that should not be reached. - */ - method fail(message) { - self.checkNotNull(message, "fail") - throw new AssertionException(message = message) - } - -} - -class StringPrinter { - var buffer = "" - - method println(obj) { - const objAsString = if (obj === null) "null" else obj.toString() - buffer += objAsString + console.newline() - } - - method getBuffer() = buffer -} diff --git a/org.uqbar.project.wollok.lib/src/wollok/mirror.wlk b/org.uqbar.project.wollok.lib/src/wollok/mirror.wlk deleted file mode 100644 index 08ae25802c..0000000000 --- a/org.uqbar.project.wollok.lib/src/wollok/mirror.wlk +++ /dev/null @@ -1,13 +0,0 @@ -class InstanceVariableMirror { - const target - const property name - - method value() = target.resolve(name) - - method valueToSmartString(alreadyShown) { - const value = self.value() - return if (value == null) "null" else value.toSmartString(alreadyShown) - } - - override method toString() = name + "=" + self.value() -} diff --git a/org.uqbar.project.wollok.lib/src/wollok/vm.wlk b/org.uqbar.project.wollok.lib/src/wollok/vm.wlk deleted file mode 100644 index 17b74b0af9..0000000000 --- a/org.uqbar.project.wollok.lib/src/wollok/vm.wlk +++ /dev/null @@ -1,3 +0,0 @@ -object runtime { - method isInteractive() native -} diff --git a/wollok-language b/wollok-language new file mode 160000 index 0000000000..e5ed9f1a41 --- /dev/null +++ b/wollok-language @@ -0,0 +1 @@ +Subproject commit e5ed9f1a416c9030258976a1527f790d8bbd6426 From 80c6727a2d86e89eca704727907de6969a27bafd Mon Sep 17 00:00:00 2001 From: Fernando Dodino Date: Sat, 19 Oct 2019 20:37:14 -0300 Subject: [PATCH 025/133] Replacing gitmodule to https instead of git - for travis build --- .gitmodules | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitmodules b/.gitmodules index 377c582d43..637bd19ced 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,3 @@ [submodule "wollok-language"] path = wollok-language - url = git@github.com:uqbar-project/wollok-language.git + url = https://github.com/uqbar-project/wollok-language.git From c75fa26594c179de0fc50211113b927d8b5d207a Mon Sep 17 00:00:00 2001 From: Fernando Dodino Date: Sat, 19 Oct 2019 21:15:02 -0300 Subject: [PATCH 026/133] Forcing a git submodule add in travis build --- .travis.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.travis.yml b/.travis.yml index 8d12aa3d7d..b05fe56730 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,6 +8,7 @@ before_install: - openssl aes-256-cbc -K $encrypted_1cc7b892dc78_key -iv $encrypted_1cc7b892dc78_iv -in settings.xml.enc -out settings.xml -d - mv settings.xml ~/.m2/settings.xml +- git submodule add --branch master https://github.com/uqbar-project/wollok-language.git after_success: - | if [ $TRAVIS_PULL_REQUEST == "false" -a $TRAVIS_BRANCH == "master" ] ; then From 902e43c03e63ac99fdf84aff228a24de8557ba43 Mon Sep 17 00:00:00 2001 From: Fernando Dodino Date: Sun, 20 Oct 2019 01:20:22 -0300 Subject: [PATCH 027/133] Using soft links from wollok-language in wollok.lib --- .travis.yml | 1 - org.uqbar.project.wollok.lib/.project | 27 ------------------- .../src/wollok/game.wlk | 1 + .../src/wollok/lang.wlk | 1 + .../src/wollok/lib.wlk | 1 + .../src/wollok/mirror.wlk | 1 + .../src/wollok/vm.wlk | 1 + .../highlight/WollokConsoleAttributes.xtend | 2 +- .../ExtractMethodRefactoring.xtend | 9 +++---- .../WollokDslProposalProvider.xtend | 3 +-- .../quickfix/WollokDslQuickfixProvider.xtend | 5 ++-- 11 files changed, 13 insertions(+), 39 deletions(-) create mode 120000 org.uqbar.project.wollok.lib/src/wollok/game.wlk create mode 120000 org.uqbar.project.wollok.lib/src/wollok/lang.wlk create mode 120000 org.uqbar.project.wollok.lib/src/wollok/lib.wlk create mode 120000 org.uqbar.project.wollok.lib/src/wollok/mirror.wlk create mode 120000 org.uqbar.project.wollok.lib/src/wollok/vm.wlk diff --git a/.travis.yml b/.travis.yml index b05fe56730..8d12aa3d7d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,7 +8,6 @@ before_install: - openssl aes-256-cbc -K $encrypted_1cc7b892dc78_key -iv $encrypted_1cc7b892dc78_iv -in settings.xml.enc -out settings.xml -d - mv settings.xml ~/.m2/settings.xml -- git submodule add --branch master https://github.com/uqbar-project/wollok-language.git after_success: - | if [ $TRAVIS_PULL_REQUEST == "false" -a $TRAVIS_BRANCH == "master" ] ; then diff --git a/org.uqbar.project.wollok.lib/.project b/org.uqbar.project.wollok.lib/.project index 88ece7b342..75f982934e 100644 --- a/org.uqbar.project.wollok.lib/.project +++ b/org.uqbar.project.wollok.lib/.project @@ -37,31 +37,4 @@ org.eclipse.jdt.core.javanature org.eclipse.xtext.ui.shared.xtextNature - - - src/wollok/game.wlk - 1 - PARENT-1-PROJECT_LOC/wollok-language/src/wollok/game.wlk - - - src/wollok/lang.wlk - 1 - PARENT-1-PROJECT_LOC/wollok-language/src/wollok/lang.wlk - - - src/wollok/lib.wlk - 1 - PARENT-1-PROJECT_LOC/wollok-language/src/wollok/lib.wlk - - - src/wollok/mirror.wlk - 1 - PARENT-1-PROJECT_LOC/wollok-language/src/wollok/mirror.wlk - - - src/wollok/vm.wlk - 1 - PARENT-1-PROJECT_LOC/wollok-language/src/wollok/vm.wlk - - diff --git a/org.uqbar.project.wollok.lib/src/wollok/game.wlk b/org.uqbar.project.wollok.lib/src/wollok/game.wlk new file mode 120000 index 0000000000..78a671621a --- /dev/null +++ b/org.uqbar.project.wollok.lib/src/wollok/game.wlk @@ -0,0 +1 @@ +../../../wollok-language/src/wollok/game.wlk \ No newline at end of file diff --git a/org.uqbar.project.wollok.lib/src/wollok/lang.wlk b/org.uqbar.project.wollok.lib/src/wollok/lang.wlk new file mode 120000 index 0000000000..6a158a00d3 --- /dev/null +++ b/org.uqbar.project.wollok.lib/src/wollok/lang.wlk @@ -0,0 +1 @@ +../../../wollok-language/src/wollok/lang.wlk \ No newline at end of file diff --git a/org.uqbar.project.wollok.lib/src/wollok/lib.wlk b/org.uqbar.project.wollok.lib/src/wollok/lib.wlk new file mode 120000 index 0000000000..df6a69f86a --- /dev/null +++ b/org.uqbar.project.wollok.lib/src/wollok/lib.wlk @@ -0,0 +1 @@ +../../../wollok-language/src/wollok/lib.wlk \ No newline at end of file diff --git a/org.uqbar.project.wollok.lib/src/wollok/mirror.wlk b/org.uqbar.project.wollok.lib/src/wollok/mirror.wlk new file mode 120000 index 0000000000..74fb5c030b --- /dev/null +++ b/org.uqbar.project.wollok.lib/src/wollok/mirror.wlk @@ -0,0 +1 @@ +../../../wollok-language/src/wollok/mirror.wlk \ No newline at end of file diff --git a/org.uqbar.project.wollok.lib/src/wollok/vm.wlk b/org.uqbar.project.wollok.lib/src/wollok/vm.wlk new file mode 120000 index 0000000000..77bf6dfea6 --- /dev/null +++ b/org.uqbar.project.wollok.lib/src/wollok/vm.wlk @@ -0,0 +1 @@ +../../../wollok-language/src/wollok/vm.wlk \ No newline at end of file diff --git a/org.uqbar.project.wollok.ui.launch/src/org/uqbar/project/wollok/ui/console/highlight/WollokConsoleAttributes.xtend b/org.uqbar.project.wollok.ui.launch/src/org/uqbar/project/wollok/ui/console/highlight/WollokConsoleAttributes.xtend index 869f829b89..dbf22d3251 100644 --- a/org.uqbar.project.wollok.ui.launch/src/org/uqbar/project/wollok/ui/console/highlight/WollokConsoleAttributes.xtend +++ b/org.uqbar.project.wollok.ui.launch/src/org/uqbar/project/wollok/ui/console/highlight/WollokConsoleAttributes.xtend @@ -64,7 +64,7 @@ class WollokConsoleAttributes implements Cloneable { // Eclipse console specific attributes (resolving color palette, default colors, etc.) def static updateRangeStyle(StyleRange range, WollokConsoleAttributes attribute) { val useWindowsMapping = getBoolean(WollokConsolePreferenceConstants.PREF_WINDOWS_MAPPING) - val WollokConsoleAttributes tempAttrib = attribute.clone as WollokConsoleAttributes + val tempAttrib = attribute.clone as WollokConsoleAttributes var hilite = false diff --git a/org.uqbar.project.wollok.ui/src/org/uqbar/project/wollok/refactoring/ExtractMethodRefactoring.xtend b/org.uqbar.project.wollok.ui/src/org/uqbar/project/wollok/refactoring/ExtractMethodRefactoring.xtend index 4537cd7c9b..5816154b2a 100644 --- a/org.uqbar.project.wollok.ui/src/org/uqbar/project/wollok/refactoring/ExtractMethodRefactoring.xtend +++ b/org.uqbar.project.wollok.ui/src/org/uqbar/project/wollok/refactoring/ExtractMethodRefactoring.xtend @@ -5,7 +5,6 @@ import com.google.common.collect.Multimap import com.google.inject.Inject import com.google.inject.Provider import java.util.List -import org.apache.log4j.Logger import org.eclipse.core.runtime.CoreException import org.eclipse.core.runtime.IProgressMonitor import org.eclipse.core.runtime.OperationCanceledException @@ -65,7 +64,7 @@ import static extension org.uqbar.project.wollok.ui.utils.XTendUtilExtensions.* // - any unnecessary code (since it was based on xtend) @Accessors class ExtractMethodRefactoring extends Refactoring { - static val Logger LOG = Logger.getLogger(ExtractMethodRefactoring) + // static val Logger LOG = Logger.getLogger(ExtractMethodRefactoring) @Inject ILocationInFileProvider locationInFileProvider; // @Inject NewFeatureNameUtil nameUtil @@ -111,7 +110,7 @@ class ExtractMethodRefactoring extends Refactoring { if (xtendClass === null || originalMethod === null) return false - val successorExpression = expressionUtil.findSuccessorExpressionForVariableDeclaration(lastExpression) +// val successorExpression = expressionUtil.findSuccessorExpressionForVariableDeclaration(lastExpression) // nameUtil.setFeatureScopeContext(successorExpression) rewriter = rewriterFactory.create(document, firstExpression.eResource as XtextResource) true @@ -149,7 +148,7 @@ class ExtractMethodRefactoring extends Refactoring { } if (element instanceof WMemberFeatureCall) { - val featureCall = element as WMemberFeatureCall +// val featureCall = element as WMemberFeatureCall // val String feature = featureCall.feature // // var isLocalFeature = EcoreUtil.isAncestor(expressions, feature) @@ -202,7 +201,7 @@ class ExtractMethodRefactoring extends Refactoring { val eContainer = lastExpression.eContainer if (eContainer instanceof WBlockExpression) { if (eContainer.eContainer == originalMethod) { - val siblings = (eContainer as WBlockExpression).expressions + val siblings = eContainer.expressions return siblings.indexOf(lastExpression) == siblings.size -1 } } diff --git a/org.uqbar.project.wollok.ui/src/org/uqbar/project/wollok/ui/contentassist/WollokDslProposalProvider.xtend b/org.uqbar.project.wollok.ui/src/org/uqbar/project/wollok/ui/contentassist/WollokDslProposalProvider.xtend index 630408f31c..67675f98ae 100644 --- a/org.uqbar.project.wollok.ui/src/org/uqbar/project/wollok/ui/contentassist/WollokDslProposalProvider.xtend +++ b/org.uqbar.project.wollok.ui/src/org/uqbar/project/wollok/ui/contentassist/WollokDslProposalProvider.xtend @@ -86,8 +86,7 @@ class WollokDslProposalProvider extends AbstractWollokDslProposalProvider { // default def dispatch void memberProposalsForTarget(WExpression expression, Assignment assignment, ICompletionProposalAcceptor acceptor) { if (expression instanceof WConstructorCall) { - val constructorCall = expression as WConstructorCall - constructorCall.classRef?.methodsAsProposals(acceptor) + expression.classRef?.methodsAsProposals(acceptor) return } if (expression.isTypeSystemEnabled) { diff --git a/org.uqbar.project.wollok.ui/src/org/uqbar/project/wollok/ui/quickfix/WollokDslQuickfixProvider.xtend b/org.uqbar.project.wollok.ui/src/org/uqbar/project/wollok/ui/quickfix/WollokDslQuickfixProvider.xtend index 2a9a5d9aa2..ec733edb12 100644 --- a/org.uqbar.project.wollok.ui/src/org/uqbar/project/wollok/ui/quickfix/WollokDslQuickfixProvider.xtend +++ b/org.uqbar.project.wollok.ui/src/org/uqbar/project/wollok/ui/quickfix/WollokDslQuickfixProvider.xtend @@ -390,9 +390,8 @@ class WollokDslQuickfixProvider extends DefaultQuickfixProvider { def changeDeclarationToVar(Issue issue, IssueResolutionAcceptor acceptor) { acceptor.accept(issue, Messages.WollokDslQuickfixProvider_changeToVar_name, Messages.WollokDslQuickfixProvider_changeToVar_description, null) [ e, context | - val f = (e as WAssignment).feature.ref.eContainer - if (f instanceof WVariableDeclaration) { - val feature = f as WVariableDeclaration + val feature = (e as WAssignment).feature.ref.eContainer + if (feature instanceof WVariableDeclaration) { val valueOrNothing = if (feature.right === null) "" else " =" + feature.right.node.text context.xtextDocument.replace(feature.before, feature.node.length, VAR + " " + feature.variable.name + valueOrNothing) From 60b7abc7686741af62fbcd2c827fb01a8bcea316 Mon Sep 17 00:00:00 2001 From: Fernando Dodino Date: Sun, 20 Oct 2019 12:38:59 -0300 Subject: [PATCH 028/133] AppVeyor - adding symbolic links to wollok-language lib files --- appveyor.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/appveyor.yml b/appveyor.yml index 2ba150ea11..81c270b624 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -14,6 +14,7 @@ install: - cmd: SET MAVEN_OPTS=-XX:MaxPermSize=2g -Xmx4g - cmd: SET JAVA_OPTS=-XX:MaxPermSize=2g -Xmx4g - cmd: SET M2_HOME=C:\maven\apache-maven-3.2.5 + - cmd: MKLINK /D ..\..\..\wollok-language\src\wollok\* . build_script: - cd org.uqbar.project.wollok.releng/ - mvn clean install -U -Darguments='-Dtycho.disableP2Mirrors=true' -Dtycho.disableP2Mirrors=true From a60b6b0232a6b6b6d9b17d2c4fcea911ea1c568a Mon Sep 17 00:00:00 2001 From: Fernando Dodino Date: Sun, 20 Oct 2019 12:41:14 -0300 Subject: [PATCH 029/133] AppVeyor build - copying lib files from root folder --- appveyor.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/appveyor.yml b/appveyor.yml index 81c270b624..365c0e52ae 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -14,7 +14,7 @@ install: - cmd: SET MAVEN_OPTS=-XX:MaxPermSize=2g -Xmx4g - cmd: SET JAVA_OPTS=-XX:MaxPermSize=2g -Xmx4g - cmd: SET M2_HOME=C:\maven\apache-maven-3.2.5 - - cmd: MKLINK /D ..\..\..\wollok-language\src\wollok\* . + - cmd: MKLINK /D wollok-language\src\wollok\* org.uqbar.project.wollok.lib\src\wollok build_script: - cd org.uqbar.project.wollok.releng/ - mvn clean install -U -Darguments='-Dtycho.disableP2Mirrors=true' -Dtycho.disableP2Mirrors=true From 3bfb4b60e76cefa29bdb07fd372af859cadc9550 Mon Sep 17 00:00:00 2001 From: Fernando Dodino Date: Sun, 20 Oct 2019 12:42:04 -0300 Subject: [PATCH 030/133] Adding DIR for debug purposes --- appveyor.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/appveyor.yml b/appveyor.yml index 365c0e52ae..4056964200 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -14,6 +14,7 @@ install: - cmd: SET MAVEN_OPTS=-XX:MaxPermSize=2g -Xmx4g - cmd: SET JAVA_OPTS=-XX:MaxPermSize=2g -Xmx4g - cmd: SET M2_HOME=C:\maven\apache-maven-3.2.5 + - cmd: DIR - cmd: MKLINK /D wollok-language\src\wollok\* org.uqbar.project.wollok.lib\src\wollok build_script: - cd org.uqbar.project.wollok.releng/ From d60eeaf57ec46b7197f25dedce9bb8de519805fa Mon Sep 17 00:00:00 2001 From: Fernando Dodino Date: Sun, 20 Oct 2019 12:43:50 -0300 Subject: [PATCH 031/133] AppVeyor - generating symlinks using absolute paths --- appveyor.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/appveyor.yml b/appveyor.yml index 4056964200..f23da1ff8a 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -15,7 +15,7 @@ install: - cmd: SET JAVA_OPTS=-XX:MaxPermSize=2g -Xmx4g - cmd: SET M2_HOME=C:\maven\apache-maven-3.2.5 - cmd: DIR - - cmd: MKLINK /D wollok-language\src\wollok\* org.uqbar.project.wollok.lib\src\wollok + - cmd: MKLINK /D C:\projects\wollok\wollok-language\src\wollok\* C:\projects\wollok\org.uqbar.project.wollok.lib\src\wollok build_script: - cd org.uqbar.project.wollok.releng/ - mvn clean install -U -Darguments='-Dtycho.disableP2Mirrors=true' -Dtycho.disableP2Mirrors=true From e18cf3b9f8db7516940603f47d0d1709a42dbc3c Mon Sep 17 00:00:00 2001 From: Fernando Dodino Date: Sun, 20 Oct 2019 12:46:01 -0300 Subject: [PATCH 032/133] AppVeyor - build debugging --- appveyor.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/appveyor.yml b/appveyor.yml index f23da1ff8a..0ca4210387 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -15,7 +15,9 @@ install: - cmd: SET JAVA_OPTS=-XX:MaxPermSize=2g -Xmx4g - cmd: SET M2_HOME=C:\maven\apache-maven-3.2.5 - cmd: DIR - - cmd: MKLINK /D C:\projects\wollok\wollok-language\src\wollok\* C:\projects\wollok\org.uqbar.project.wollok.lib\src\wollok + - cmd: DIR C:\projects\wollok\wollok-language\src\wollok\*.wlk + - cmd: DIR wollok-language\src\wollok\*.wlk + - cmd: MKLINK /D C:\projects\wollok\wollok-language\src\wollok\*.wlk C:\projects\wollok\org.uqbar.project.wollok.lib\src\wollok build_script: - cd org.uqbar.project.wollok.releng/ - mvn clean install -U -Darguments='-Dtycho.disableP2Mirrors=true' -Dtycho.disableP2Mirrors=true From 22c2dde157c4942b23eea1db4d71b9410a0f905d Mon Sep 17 00:00:00 2001 From: Fernando Dodino Date: Sun, 20 Oct 2019 12:47:46 -0300 Subject: [PATCH 033/133] AppVeyor - dir #2 time --- appveyor.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index 0ca4210387..19aec8a1a1 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -15,8 +15,8 @@ install: - cmd: SET JAVA_OPTS=-XX:MaxPermSize=2g -Xmx4g - cmd: SET M2_HOME=C:\maven\apache-maven-3.2.5 - cmd: DIR - - cmd: DIR C:\projects\wollok\wollok-language\src\wollok\*.wlk - - cmd: DIR wollok-language\src\wollok\*.wlk + - cmd: DIR wollok-language + - cmd: DIR wollok-language\src - cmd: MKLINK /D C:\projects\wollok\wollok-language\src\wollok\*.wlk C:\projects\wollok\org.uqbar.project.wollok.lib\src\wollok build_script: - cd org.uqbar.project.wollok.releng/ From e83da8f76b7a44d25d3f36672b3759a2e120e8ac Mon Sep 17 00:00:00 2001 From: Fernando Dodino Date: Sun, 20 Oct 2019 12:53:06 -0300 Subject: [PATCH 034/133] AppVeyor - workaround for git submodules --- appveyor.yml | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/appveyor.yml b/appveyor.yml index 19aec8a1a1..f0e6a4c03a 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,5 +1,11 @@ version: '{build}' os: Windows Server 2012 +clone_script: +- cmd: >- + git clone -q --branch=%APPVEYOR_REPO_BRANCH% https://github.com/%APPVEYOR_REPO_NAME%.git %APPVEYOR_BUILD_FOLDER% + cd %APPVEYOR_BUILD_FOLDER% + git checkout -qf %APPVEYOR_REPO_COMMIT% + git submodule update --init --recursive install: - ps: | Add-Type -AssemblyName System.IO.Compression.FileSystem @@ -17,7 +23,7 @@ install: - cmd: DIR - cmd: DIR wollok-language - cmd: DIR wollok-language\src - - cmd: MKLINK /D C:\projects\wollok\wollok-language\src\wollok\*.wlk C:\projects\wollok\org.uqbar.project.wollok.lib\src\wollok + # - cmd: MKLINK /D C:\projects\wollok\wollok-language\src\wollok\*.wlk C:\projects\wollok\org.uqbar.project.wollok.lib\src\wollok build_script: - cd org.uqbar.project.wollok.releng/ - mvn clean install -U -Darguments='-Dtycho.disableP2Mirrors=true' -Dtycho.disableP2Mirrors=true From 9c8fb369775f0eab222ba523fbe67adfad39eb29 Mon Sep 17 00:00:00 2001 From: Fernando Dodino Date: Sun, 20 Oct 2019 12:54:24 -0300 Subject: [PATCH 035/133] AppVeyor - new fight! --- appveyor.yml | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index f0e6a4c03a..3e5c6c8c38 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,11 +1,8 @@ version: '{build}' os: Windows Server 2012 clone_script: -- cmd: >- - git clone -q --branch=%APPVEYOR_REPO_BRANCH% https://github.com/%APPVEYOR_REPO_NAME%.git %APPVEYOR_BUILD_FOLDER% - cd %APPVEYOR_BUILD_FOLDER% - git checkout -qf %APPVEYOR_REPO_COMMIT% - git submodule update --init --recursive +- cmd: git clone -q --recursive --branch=%APPVEYOR_REPO_BRANCH% https://github.com/%APPVEYOR_REPO_NAME%.git %APPVEYOR_BUILD_FOLDER% +- cmd: git checkout -qf %APPVEYOR_REPO_COMMIT% install: - ps: | Add-Type -AssemblyName System.IO.Compression.FileSystem From 3f5b28af8802b84999aba2b7548ef41f2ee029a6 Mon Sep 17 00:00:00 2001 From: Fernando Dodino Date: Sun, 20 Oct 2019 13:09:15 -0300 Subject: [PATCH 036/133] AppVeyor - fight #3 --- appveyor.yml | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index 3e5c6c8c38..0436e3c206 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,9 +1,8 @@ version: '{build}' os: Windows Server 2012 -clone_script: -- cmd: git clone -q --recursive --branch=%APPVEYOR_REPO_BRANCH% https://github.com/%APPVEYOR_REPO_NAME%.git %APPVEYOR_BUILD_FOLDER% -- cmd: git checkout -qf %APPVEYOR_REPO_COMMIT% install: + - cd %APPVEYOR_BUILD_FOLDER% + - git submodule update --init --recursive - ps: | Add-Type -AssemblyName System.IO.Compression.FileSystem if (!(Test-Path -Path "C:\maven" )) { From f0467c964ebd37f90751defccafe9a052a6d6a01 Mon Sep 17 00:00:00 2001 From: Fernando Dodino Date: Sun, 20 Oct 2019 13:34:51 -0300 Subject: [PATCH 037/133] AppVeyor - back to copy symlinks --- appveyor.yml | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index 0436e3c206..1f1effc8e3 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -16,10 +16,7 @@ install: - cmd: SET MAVEN_OPTS=-XX:MaxPermSize=2g -Xmx4g - cmd: SET JAVA_OPTS=-XX:MaxPermSize=2g -Xmx4g - cmd: SET M2_HOME=C:\maven\apache-maven-3.2.5 - - cmd: DIR - - cmd: DIR wollok-language - - cmd: DIR wollok-language\src - # - cmd: MKLINK /D C:\projects\wollok\wollok-language\src\wollok\*.wlk C:\projects\wollok\org.uqbar.project.wollok.lib\src\wollok + - cmd: MKLINK /D wollok-language\src\wollok\*.wlk org.uqbar.project.wollok.lib\src\wollok build_script: - cd org.uqbar.project.wollok.releng/ - mvn clean install -U -Darguments='-Dtycho.disableP2Mirrors=true' -Dtycho.disableP2Mirrors=true From f6f81c355d7672043670d3ec437a481072e95314 Mon Sep 17 00:00:00 2001 From: Fernando Dodino Date: Sun, 20 Oct 2019 13:38:58 -0300 Subject: [PATCH 038/133] AppVeyor - copying symlinks as files --- appveyor.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/appveyor.yml b/appveyor.yml index 1f1effc8e3..65ebffb4bf 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -16,7 +16,7 @@ install: - cmd: SET MAVEN_OPTS=-XX:MaxPermSize=2g -Xmx4g - cmd: SET JAVA_OPTS=-XX:MaxPermSize=2g -Xmx4g - cmd: SET M2_HOME=C:\maven\apache-maven-3.2.5 - - cmd: MKLINK /D wollok-language\src\wollok\*.wlk org.uqbar.project.wollok.lib\src\wollok + - cmd: MKLINK wollok-language\src\wollok\*.wlk org.uqbar.project.wollok.lib\src\wollok build_script: - cd org.uqbar.project.wollok.releng/ - mvn clean install -U -Darguments='-Dtycho.disableP2Mirrors=true' -Dtycho.disableP2Mirrors=true From ae3b95f4dde4ef5841b7ccf339a22a05c6f0c1a0 Mon Sep 17 00:00:00 2001 From: Fernando Dodino Date: Sun, 20 Oct 2019 13:43:35 -0300 Subject: [PATCH 039/133] AppVeyor => win10 doesn't have wildcards in mklink! --- appveyor.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/appveyor.yml b/appveyor.yml index 65ebffb4bf..e2cb87c12e 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -16,7 +16,7 @@ install: - cmd: SET MAVEN_OPTS=-XX:MaxPermSize=2g -Xmx4g - cmd: SET JAVA_OPTS=-XX:MaxPermSize=2g -Xmx4g - cmd: SET M2_HOME=C:\maven\apache-maven-3.2.5 - - cmd: MKLINK wollok-language\src\wollok\*.wlk org.uqbar.project.wollok.lib\src\wollok + - cmd: for /r %file in (*.wlk) do MKLINK wollok-language\src\wollok\%file org.uqbar.project.wollok.lib\src\wollok build_script: - cd org.uqbar.project.wollok.releng/ - mvn clean install -U -Darguments='-Dtycho.disableP2Mirrors=true' -Dtycho.disableP2Mirrors=true From 39eb7036876570d2bf5ab80e47186d4d00346528 Mon Sep 17 00:00:00 2001 From: Fernando Dodino Date: Sun, 20 Oct 2019 13:45:05 -0300 Subject: [PATCH 040/133] AppVeyor & win10 sucks! --- appveyor.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/appveyor.yml b/appveyor.yml index e2cb87c12e..9fe2bc4b97 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -16,7 +16,7 @@ install: - cmd: SET MAVEN_OPTS=-XX:MaxPermSize=2g -Xmx4g - cmd: SET JAVA_OPTS=-XX:MaxPermSize=2g -Xmx4g - cmd: SET M2_HOME=C:\maven\apache-maven-3.2.5 - - cmd: for /r %file in (*.wlk) do MKLINK wollok-language\src\wollok\%file org.uqbar.project.wollok.lib\src\wollok + - cmd: for /r %file in (*.wlk) do MKLINK wollok-language\src\wollok\%file org.uqbar.project.wollok.lib\src\wollok\%file build_script: - cd org.uqbar.project.wollok.releng/ - mvn clean install -U -Darguments='-Dtycho.disableP2Mirrors=true' -Dtycho.disableP2Mirrors=true From 5dddad8249f9bf82ae2ec0dd77d4e07fc07d3f7a Mon Sep 17 00:00:00 2001 From: Fernando Dodino Date: Sun, 20 Oct 2019 13:48:04 -0300 Subject: [PATCH 041/133] AppVeyor try #8 --- appveyor.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/appveyor.yml b/appveyor.yml index 9fe2bc4b97..4558dfc1d4 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -16,7 +16,7 @@ install: - cmd: SET MAVEN_OPTS=-XX:MaxPermSize=2g -Xmx4g - cmd: SET JAVA_OPTS=-XX:MaxPermSize=2g -Xmx4g - cmd: SET M2_HOME=C:\maven\apache-maven-3.2.5 - - cmd: for /r %file in (*.wlk) do MKLINK wollok-language\src\wollok\%file org.uqbar.project.wollok.lib\src\wollok\%file + - cmd: for /r %%file in (*.wlk) do MKLINK wollok-language\src\wollok\%%file org.uqbar.project.wollok.lib\src\wollok\%%file build_script: - cd org.uqbar.project.wollok.releng/ - mvn clean install -U -Darguments='-Dtycho.disableP2Mirrors=true' -Dtycho.disableP2Mirrors=true From 92023556dab9e97c17ea9103cab94a21a280d6e5 Mon Sep 17 00:00:00 2001 From: Fernando Dodino Date: Sun, 20 Oct 2019 13:50:05 -0300 Subject: [PATCH 042/133] AppVeyor try #9 --- appveyor.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/appveyor.yml b/appveyor.yml index 4558dfc1d4..173e3def87 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -16,7 +16,10 @@ install: - cmd: SET MAVEN_OPTS=-XX:MaxPermSize=2g -Xmx4g - cmd: SET JAVA_OPTS=-XX:MaxPermSize=2g -Xmx4g - cmd: SET M2_HOME=C:\maven\apache-maven-3.2.5 - - cmd: for /r %%file in (*.wlk) do MKLINK wollok-language\src\wollok\%%file org.uqbar.project.wollok.lib\src\wollok\%%file + - cmd: for /r %%file in (*.wlk) do ( + echo Copying %%file + MKLINK wollok-language\src\wollok\%%file org.uqbar.project.wollok.lib\src\wollok\%%file + ) build_script: - cd org.uqbar.project.wollok.releng/ - mvn clean install -U -Darguments='-Dtycho.disableP2Mirrors=true' -Dtycho.disableP2Mirrors=true From 4801bfe09503f5ddeb96025e3abf5a7c1130c338 Mon Sep 17 00:00:00 2001 From: Fernando Dodino Date: Sun, 20 Oct 2019 17:02:43 -0300 Subject: [PATCH 043/133] AppVeyor - try #9 --- appveyor.yml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index 173e3def87..f2bb8213a5 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -16,9 +16,7 @@ install: - cmd: SET MAVEN_OPTS=-XX:MaxPermSize=2g -Xmx4g - cmd: SET JAVA_OPTS=-XX:MaxPermSize=2g -Xmx4g - cmd: SET M2_HOME=C:\maven\apache-maven-3.2.5 - - cmd: for /r %%file in (*.wlk) do ( - echo Copying %%file - MKLINK wollok-language\src\wollok\%%file org.uqbar.project.wollok.lib\src\wollok\%%file + - cmd: for %%FILE in (*.wlk) do MKLINK "wollok-language\src\wollok\%%FILE" "org.uqbar.project.wollok.lib\src\wollok\%%FILE" ) build_script: - cd org.uqbar.project.wollok.releng/ From b2d140390ba5eecaf931c66179b3220a5ab03ef9 Mon Sep 17 00:00:00 2001 From: Fernando Dodino Date: Sun, 20 Oct 2019 17:04:04 -0300 Subject: [PATCH 044/133] AppVeyor - try #10 --- appveyor.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index f2bb8213a5..e31f0032cb 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -16,8 +16,7 @@ install: - cmd: SET MAVEN_OPTS=-XX:MaxPermSize=2g -Xmx4g - cmd: SET JAVA_OPTS=-XX:MaxPermSize=2g -Xmx4g - cmd: SET M2_HOME=C:\maven\apache-maven-3.2.5 - - cmd: for %%FILE in (*.wlk) do MKLINK "wollok-language\src\wollok\%%FILE" "org.uqbar.project.wollok.lib\src\wollok\%%FILE" - ) + - cmd: for %FILE% in (*.wlk) do MKLINK "wollok-language\src\wollok\%FILE%" "org.uqbar.project.wollok.lib\src\wollok\%FILE%" build_script: - cd org.uqbar.project.wollok.releng/ - mvn clean install -U -Darguments='-Dtycho.disableP2Mirrors=true' -Dtycho.disableP2Mirrors=true From 6616a02cdcd7743dc0277444248b22ada8f56b48 Mon Sep 17 00:00:00 2001 From: Fernando Dodino Date: Sun, 20 Oct 2019 17:07:08 -0300 Subject: [PATCH 045/133] AppVeyor - try #11 --- appveyor.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/appveyor.yml b/appveyor.yml index e31f0032cb..0c7346306b 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -16,7 +16,7 @@ install: - cmd: SET MAVEN_OPTS=-XX:MaxPermSize=2g -Xmx4g - cmd: SET JAVA_OPTS=-XX:MaxPermSize=2g -Xmx4g - cmd: SET M2_HOME=C:\maven\apache-maven-3.2.5 - - cmd: for %FILE% in (*.wlk) do MKLINK "wollok-language\src\wollok\%FILE%" "org.uqbar.project.wollok.lib\src\wollok\%FILE%" + - cmd: for %FILE in (.\*.wlk) do MKLINK "wollok-language\src\wollok\%FILE" "org.uqbar.project.wollok.lib\src\wollok\%FILE" build_script: - cd org.uqbar.project.wollok.releng/ - mvn clean install -U -Darguments='-Dtycho.disableP2Mirrors=true' -Dtycho.disableP2Mirrors=true From b14fc98f3d7e05a3b8c76c4988e5f870c7ef4338 Mon Sep 17 00:00:00 2001 From: Fernando Dodino Date: Sun, 20 Oct 2019 17:08:50 -0300 Subject: [PATCH 046/133] AppVeyor - try #12 --- appveyor.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/appveyor.yml b/appveyor.yml index 0c7346306b..0223fbb212 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -16,7 +16,7 @@ install: - cmd: SET MAVEN_OPTS=-XX:MaxPermSize=2g -Xmx4g - cmd: SET JAVA_OPTS=-XX:MaxPermSize=2g -Xmx4g - cmd: SET M2_HOME=C:\maven\apache-maven-3.2.5 - - cmd: for %FILE in (.\*.wlk) do MKLINK "wollok-language\src\wollok\%FILE" "org.uqbar.project.wollok.lib\src\wollok\%FILE" + - cmd: for %FILE in (.\*.wlk) do (MKLINK "wollok-language\src\wollok\%FILE" "org.uqbar.project.wollok.lib\src\wollok\%FILE") build_script: - cd org.uqbar.project.wollok.releng/ - mvn clean install -U -Darguments='-Dtycho.disableP2Mirrors=true' -Dtycho.disableP2Mirrors=true From b78d350815a0120776f2c49a9c5789b07dd40012 Mon Sep 17 00:00:00 2001 From: Fernando Dodino Date: Sun, 20 Oct 2019 17:14:36 -0300 Subject: [PATCH 047/133] AppVeyor - try #13 --- appveyor.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/appveyor.yml b/appveyor.yml index 0223fbb212..08a5379451 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -16,7 +16,7 @@ install: - cmd: SET MAVEN_OPTS=-XX:MaxPermSize=2g -Xmx4g - cmd: SET JAVA_OPTS=-XX:MaxPermSize=2g -Xmx4g - cmd: SET M2_HOME=C:\maven\apache-maven-3.2.5 - - cmd: for %FILE in (.\*.wlk) do (MKLINK "wollok-language\src\wollok\%FILE" "org.uqbar.project.wollok.lib\src\wollok\%FILE") + - cmd: for %FILE in (.\*.wlk) do (MKLINK "wollok-language\src\wollok\%FILE%" "org.uqbar.project.wollok.lib\src\wollok\%FILE%") build_script: - cd org.uqbar.project.wollok.releng/ - mvn clean install -U -Darguments='-Dtycho.disableP2Mirrors=true' -Dtycho.disableP2Mirrors=true From c2c15468afe6623e9d27a086d2e199dd5163b5d4 Mon Sep 17 00:00:00 2001 From: Fernando Dodino Date: Sun, 20 Oct 2019 17:18:26 -0300 Subject: [PATCH 048/133] AppVeyor - try #14 --- appveyor.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/appveyor.yml b/appveyor.yml index 08a5379451..82c5041181 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -16,7 +16,7 @@ install: - cmd: SET MAVEN_OPTS=-XX:MaxPermSize=2g -Xmx4g - cmd: SET JAVA_OPTS=-XX:MaxPermSize=2g -Xmx4g - cmd: SET M2_HOME=C:\maven\apache-maven-3.2.5 - - cmd: for %FILE in (.\*.wlk) do (MKLINK "wollok-language\src\wollok\%FILE%" "org.uqbar.project.wollok.lib\src\wollok\%FILE%") + - cmd: for %I in (.\*.wlk) do (MKLINK "wollok-language\src\wollok\%I" "org.uqbar.project.wollok.lib\src\wollok\%I") build_script: - cd org.uqbar.project.wollok.releng/ - mvn clean install -U -Darguments='-Dtycho.disableP2Mirrors=true' -Dtycho.disableP2Mirrors=true From 7c24febbc85caa49e976fba6af6aa816acd6173c Mon Sep 17 00:00:00 2001 From: Fernando Dodino Date: Sun, 20 Oct 2019 17:20:33 -0300 Subject: [PATCH 049/133] AppVeyor - try #15 --- appveyor.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/appveyor.yml b/appveyor.yml index 82c5041181..8979529621 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -16,7 +16,7 @@ install: - cmd: SET MAVEN_OPTS=-XX:MaxPermSize=2g -Xmx4g - cmd: SET JAVA_OPTS=-XX:MaxPermSize=2g -Xmx4g - cmd: SET M2_HOME=C:\maven\apache-maven-3.2.5 - - cmd: for %I in (.\*.wlk) do (MKLINK "wollok-language\src\wollok\%I" "org.uqbar.project.wollok.lib\src\wollok\%I") + - cmd: for %%I in (.\*.wlk) do (MKLINK "wollok-language\src\wollok\%%I" "org.uqbar.project.wollok.lib\src\wollok\%%I") build_script: - cd org.uqbar.project.wollok.releng/ - mvn clean install -U -Darguments='-Dtycho.disableP2Mirrors=true' -Dtycho.disableP2Mirrors=true From 294f4202b3f830a77367e003b4299cf151b8a461 Mon Sep 17 00:00:00 2001 From: Fernando Dodino Date: Sun, 20 Oct 2019 19:21:57 -0300 Subject: [PATCH 050/133] AppVeyor - try #16 --- appveyor.yml | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/appveyor.yml b/appveyor.yml index 8979529621..751ff5ae98 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -16,7 +16,13 @@ install: - cmd: SET MAVEN_OPTS=-XX:MaxPermSize=2g -Xmx4g - cmd: SET JAVA_OPTS=-XX:MaxPermSize=2g -Xmx4g - cmd: SET M2_HOME=C:\maven\apache-maven-3.2.5 - - cmd: for %%I in (.\*.wlk) do (MKLINK "wollok-language\src\wollok\%%I" "org.uqbar.project.wollok.lib\src\wollok\%%I") + # - cmd: for %%I in (.\*.wlk) do (MKLINK "wollok-language\src\wollok\%%I" "org.uqbar.project.wollok.lib\src\wollok\%%I") + - cmd: MKLINK "wollok-language\src\wollok\lang.wlk" "org.uqbar.project.wollok.lib\src\wollok\lang.wlk" + - cmd: MKLINK "wollok-language\src\wollok\lib.wlk" "org.uqbar.project.wollok.lib\src\wollok\lib.wlk" + - cmd: MKLINK "wollok-language\src\wollok\game.wlk" "org.uqbar.project.wollok.lib\src\wollok\game.wlk" + - cmd: MKLINK "wollok-language\src\wollok\vm.wlk" "org.uqbar.project.wollok.lib\src\wollok\vm.wlk" + - cmd: MKLINK "wollok-language\src\wollok\runtime.wlk" "org.uqbar.project.wollok.lib\src\wollok\runtime.wlk" + - cmd: DIR org.uqbar.project.wollok.lib\src\wollok build_script: - cd org.uqbar.project.wollok.releng/ - mvn clean install -U -Darguments='-Dtycho.disableP2Mirrors=true' -Dtycho.disableP2Mirrors=true From 2e5dd9cd355ec9f02becb44074fdd1307b81b12c Mon Sep 17 00:00:00 2001 From: Fernando Dodino Date: Sun, 20 Oct 2019 19:23:22 -0300 Subject: [PATCH 051/133] AppVeyor - try #17 --- appveyor.yml | 5 ----- 1 file changed, 5 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index 751ff5ae98..cdd83b4724 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -17,11 +17,6 @@ install: - cmd: SET JAVA_OPTS=-XX:MaxPermSize=2g -Xmx4g - cmd: SET M2_HOME=C:\maven\apache-maven-3.2.5 # - cmd: for %%I in (.\*.wlk) do (MKLINK "wollok-language\src\wollok\%%I" "org.uqbar.project.wollok.lib\src\wollok\%%I") - - cmd: MKLINK "wollok-language\src\wollok\lang.wlk" "org.uqbar.project.wollok.lib\src\wollok\lang.wlk" - - cmd: MKLINK "wollok-language\src\wollok\lib.wlk" "org.uqbar.project.wollok.lib\src\wollok\lib.wlk" - - cmd: MKLINK "wollok-language\src\wollok\game.wlk" "org.uqbar.project.wollok.lib\src\wollok\game.wlk" - - cmd: MKLINK "wollok-language\src\wollok\vm.wlk" "org.uqbar.project.wollok.lib\src\wollok\vm.wlk" - - cmd: MKLINK "wollok-language\src\wollok\runtime.wlk" "org.uqbar.project.wollok.lib\src\wollok\runtime.wlk" - cmd: DIR org.uqbar.project.wollok.lib\src\wollok build_script: - cd org.uqbar.project.wollok.releng/ From b8e83736675c40b6d3ea5563980b26d417061acb Mon Sep 17 00:00:00 2001 From: Fernando Dodino Date: Sun, 20 Oct 2019 19:42:23 -0300 Subject: [PATCH 052/133] AppVeyor - try #18 --- appveyor.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/appveyor.yml b/appveyor.yml index cdd83b4724..65df5a016d 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -17,7 +17,7 @@ install: - cmd: SET JAVA_OPTS=-XX:MaxPermSize=2g -Xmx4g - cmd: SET M2_HOME=C:\maven\apache-maven-3.2.5 # - cmd: for %%I in (.\*.wlk) do (MKLINK "wollok-language\src\wollok\%%I" "org.uqbar.project.wollok.lib\src\wollok\%%I") - - cmd: DIR org.uqbar.project.wollok.lib\src\wollok + - cmd: TYPE wollok-language\src\wollok\lang.wlk build_script: - cd org.uqbar.project.wollok.releng/ - mvn clean install -U -Darguments='-Dtycho.disableP2Mirrors=true' -Dtycho.disableP2Mirrors=true From ba970041ff251adc27fd9625947eb367306f1e83 Mon Sep 17 00:00:00 2001 From: Fernando Dodino Date: Sun, 20 Oct 2019 20:02:49 -0300 Subject: [PATCH 053/133] AppVeyor - try #20 --- appveyor.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/appveyor.yml b/appveyor.yml index 65df5a016d..3fc7a70738 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -17,7 +17,7 @@ install: - cmd: SET JAVA_OPTS=-XX:MaxPermSize=2g -Xmx4g - cmd: SET M2_HOME=C:\maven\apache-maven-3.2.5 # - cmd: for %%I in (.\*.wlk) do (MKLINK "wollok-language\src\wollok\%%I" "org.uqbar.project.wollok.lib\src\wollok\%%I") - - cmd: TYPE wollok-language\src\wollok\lang.wlk + - cmd: copy /Y wollok-language\src\wollok\*.wlk org.uqbar.project.wollok.lib\src\wollok build_script: - cd org.uqbar.project.wollok.releng/ - mvn clean install -U -Darguments='-Dtycho.disableP2Mirrors=true' -Dtycho.disableP2Mirrors=true From aba1f583721d700a7d8e8577fc3ad7b91d8d2989 Mon Sep 17 00:00:00 2001 From: Fernando Dodino Date: Sun, 20 Oct 2019 23:35:13 -0300 Subject: [PATCH 054/133] Adding sanity tests to wollok-xtext CI flow --- .../AbstractWollokInterpreterTestCase.xtend | 10 +++- .../tests/sanityTests/SanityTestCase.xtend | 52 +++++++++++++++++++ 2 files changed, 60 insertions(+), 2 deletions(-) create mode 100644 org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/sanityTests/SanityTestCase.xtend diff --git a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/AbstractWollokInterpreterTestCase.xtend b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/AbstractWollokInterpreterTestCase.xtend index ae53346568..af7b12d480 100644 --- a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/AbstractWollokInterpreterTestCase.xtend +++ b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/AbstractWollokInterpreterTestCase.xtend @@ -18,6 +18,8 @@ import org.uqbar.project.wollok.interpreter.core.WollokProgramExceptionWrapper import org.uqbar.project.wollok.tests.injectors.WollokTestInjectorProvider import wollok.lang.WDate +import static wollok.lang.WDate.* + /** * Abstract base class for all interpreter tests cases. * Already has all the necessary behavior and objects @@ -120,9 +122,13 @@ abstract class AbstractWollokInterpreterTestCase extends Assert { } def interpretPropagatingErrors(File fileToRead) { + fileToRead.interpretPropagatingErrors(true) + } + + def interpretPropagatingErrors(File fileToRead, boolean validate) { new FileInputStream(fileToRead).parse(URI.createFileURI(fileToRead.path), null, resourceSet) => [ - assertNoErrors - interpret(true) + if (validate) assertNoErrors + interpret(true, !validate) ] } diff --git a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/sanityTests/SanityTestCase.xtend b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/sanityTests/SanityTestCase.xtend new file mode 100644 index 0000000000..f362570e2f --- /dev/null +++ b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/sanityTests/SanityTestCase.xtend @@ -0,0 +1,52 @@ +package org.uqbar.project.wollok.tests.sanityTests + +import java.io.File +import java.nio.file.Files +import java.nio.file.Paths +import java.util.Map +import org.junit.Test +import org.uqbar.project.wollok.tests.interpreter.AbstractWollokInterpreterTestCase + +import static org.uqbar.project.wollok.WollokConstants.* + +/** + * Executes Sanity Tests from wollok-language + * + * @author dodain + */ +class SanityTestCase extends AbstractWollokInterpreterTestCase { + val path = "../wollok-language/test/sanity" + + @Test + def void run() { + val Map allErrors = newHashMap + println(''' + =================================================================================== + BEGIN SANITY TESTS + =================================================================================== + ''') + Files.walk(Paths.get(path)) + .filter([ path | !Files.isDirectory(path) && path.toString.endsWith(TEST_EXTENSION) ]) + .forEach [ file | + try { + new File(file.toString).interpretPropagatingErrors(false) + println('''√ OK «file.fileName»''') + } catch (AssertionError e) { + allErrors.put(file.toString, e) + println( + ''' + ✗ ERRORED «file.fileName» + «e.message» + ''' + ) + } + ] + println(''' + =================================================================================== + END SANITY TESTS + =================================================================================== + ''') + assertEquals(newHashMap, allErrors) + } + +} From ab9c6eab6774b6ce45a9eb68a689128f02e98a5a Mon Sep 17 00:00:00 2001 From: Fernando Dodino Date: Mon, 21 Oct 2019 07:56:07 -0300 Subject: [PATCH 055/133] WIP => deleting BooleanTestCase & need to log error --- .../wollok/tests/interpreter/BooleanTestCase.xtend | 8 -------- .../project/wollok/tests/sanityTests/SanityTestCase.xtend | 5 +++-- 2 files changed, 3 insertions(+), 10 deletions(-) diff --git a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/BooleanTestCase.xtend b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/BooleanTestCase.xtend index 61ef5d9969..1601f11f71 100644 --- a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/BooleanTestCase.xtend +++ b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/BooleanTestCase.xtend @@ -9,14 +9,6 @@ import org.junit.Test */ class BooleanTestCase extends AbstractWollokInterpreterTestCase { - @Test - def void literals() { - '''program a { - assert.that(true) - assert.notThat(false) - }'''.interpretPropagatingErrors - } - @Test def void andWithLiterals() { '''program a { diff --git a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/sanityTests/SanityTestCase.xtend b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/sanityTests/SanityTestCase.xtend index f362570e2f..36d3aaca38 100644 --- a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/sanityTests/SanityTestCase.xtend +++ b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/sanityTests/SanityTestCase.xtend @@ -20,6 +20,7 @@ class SanityTestCase extends AbstractWollokInterpreterTestCase { @Test def void run() { val Map allErrors = newHashMap + // TODO: Meter Logger.log println(''' =================================================================================== BEGIN SANITY TESTS @@ -30,12 +31,12 @@ class SanityTestCase extends AbstractWollokInterpreterTestCase { .forEach [ file | try { new File(file.toString).interpretPropagatingErrors(false) - println('''√ OK «file.fileName»''') + println('''√ OK «file»''') } catch (AssertionError e) { allErrors.put(file.toString, e) println( ''' - ✗ ERRORED «file.fileName» + ✗ ERRORED «file» «e.message» ''' ) From 8b1cd0895e364bde98e97a9fa487841b84197755 Mon Sep 17 00:00:00 2001 From: Fernando Dodino Date: Mon, 21 Oct 2019 21:27:58 -0300 Subject: [PATCH 056/133] Sanity tests refactor => removing Boolean & Closure tests cases --- .../tests/interpreter/BooleanTestCase.xtend | 149 ------------------ .../tests/interpreter/ClosureTestCase.xtend | 127 --------------- 2 files changed, 276 deletions(-) delete mode 100644 org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/BooleanTestCase.xtend delete mode 100644 org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/ClosureTestCase.xtend diff --git a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/BooleanTestCase.xtend b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/BooleanTestCase.xtend deleted file mode 100644 index 1601f11f71..0000000000 --- a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/BooleanTestCase.xtend +++ /dev/null @@ -1,149 +0,0 @@ -package org.uqbar.project.wollok.tests.interpreter - -import org.junit.Test - -/** - * Tests for boolean objects and operations - * - * @author jfernandes - */ -class BooleanTestCase extends AbstractWollokInterpreterTestCase { - - @Test - def void andWithLiterals() { - '''program a { - assert.that(true && true) - assert.that(true and true) - - assert.notThat(true && false) - assert.notThat(true and false) - - assert.notThat(false && true) - assert.notThat(false and true) - - assert.notThat(false && false) - assert.notThat(false and false) - }'''.interpretPropagatingErrorsWithoutStaticChecks - } - - @Test - def void orWithLiterals() { - '''program a { - assert.that(true || true) - assert.that(true or true) - - assert.that(true || false) - assert.that(true or false) - - assert.that(false || true) - assert.that(false or true) - - assert.notThat(false || false) - assert.notThat(false or false) - }'''.interpretPropagatingErrorsWithoutStaticChecks - } - - @Test - def void andShortcirtuitMustEvaluate() { - ''' - object p { - var modified = false - - method getModifying() { - modified = true - return true - } - method getModified() = modified - method setModified(n) { modified = n } - } - program a { - // evaluated - assert.that(true && p.getModifying()) - assert.that(p.getModified()) - }'''.interpretPropagatingErrorsWithoutStaticChecks - } - - @Test - def void andShortcircuitMustNOTEvaluate() { - ''' - object p { - var modified = false - - method getModifying() { - modified = true - return true - } - method getModified() = modified - } - program a { - assert.notThat(false && p.getModifying()) - assert.notThat(p.getModified()) - - }'''.interpretPropagatingErrorsWithoutStaticChecks - } - - @Test - def void lazyPartOfTheAndShortCircuitAccessingTheContext() { - ''' - object liberarAFiona { - var cantidadTrolls = 0 - var solicitante = "" - - method solicitante() = return solicitante - method solicitante(_solicitante) { solicitante = _solicitante } - method cantidadTrolls(cant) { cantidadTrolls = cant } - method esDificil() { - const result = (cantidadTrolls > 3) and (cantidadTrolls < 6) - console.println(result) - return result - } - method puntosRecompensa() = return cantidadTrolls * 2 - } - program a { - liberarAFiona.cantidadTrolls(5) - liberarAFiona.esDificil() - } - '''.interpretPropagatingErrors - } - - @Test - def void orShortcirtuitMustEvaluateSecondPart() { - ''' - object p { - var modified = false - - method getModifying() { - modified = true - return true - } - method getModified() = modified - method setModified(n) { modified = n } - } - program a { - // evaluated - assert.that(false || p.getModifying()) - assert.that(p.getModified()) - }'''.interpretPropagatingErrorsWithoutStaticChecks - } - - @Test - def void orShortcircuitMustNOTEvaluateSecondPart() { - ''' - object p { - var modified = false - - method getModifying() { - modified = true - return true - } - method getModified() = modified - method setModified(n) { modified = n } - } - test "a" { - assert.that(true || p.getModifying()) - assert.notThat(p.getModified()) - - }'''.interpretPropagatingErrorsWithoutStaticChecks - } - -} \ No newline at end of file diff --git a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/ClosureTestCase.xtend b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/ClosureTestCase.xtend deleted file mode 100644 index 12b1c475d8..0000000000 --- a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/ClosureTestCase.xtend +++ /dev/null @@ -1,127 +0,0 @@ -package org.uqbar.project.wollok.tests.interpreter - -import org.junit.Test - -/** - * @author jfernandes - */ -class ClosureTestCase extends AbstractWollokInterpreterTestCase { - - @Test - def void applyNoArgsClosure() { - ''' - program p { - const helloWorld = { "helloWorld" } - const response = helloWorld.apply() - assert.equals("helloWorld", response) - }'''.interpretPropagatingErrors - } - - @Test - def void applyClosureWithOneArgument() { - ''' - program p { - const helloWorld = {to => "hello " + to } - const response = helloWorld.apply("world") - assert.equals("hello world", response) - }'''.interpretPropagatingErrors - } - - @Test - def void closureAccessLocalVariableInProgram() { - ''' - program p { - var to = "world" - const helloWorld = {=>"hello " + to } - - assert.equals("hello world", helloWorld.apply()) - - to = "someone else" - assert.equals("hello someone else", helloWorld.apply()) - }'''.interpretPropagatingErrors - } - - @Test - def void closureAsParamToClosure() { - ''' - program p { - const twice = { block => block.apply() + block.apply() } - - assert.equals(4, twice.apply {=> 2 }) - }'''.interpretPropagatingErrors - } - - @Test - def void nestedClosure() { - ''' - program p { - const sum = {a, b => a + b} - - const curried = { a => - { b => sum.apply(a, b) } - } - - const curriedSum = curried.apply(2) - - assert.equals(5, curriedSum.apply(3)) - }'''.interpretPropagatingErrors - } - - @Test - def void foldingClosures() { - ''' - program p { - const sum2 = { a => a + 2}; - const by3 = { b => b * 3}; - const pow = { c => c ** 2}; - - const op = [sum2, by3, pow] - - const result = op.fold(0, {acc, o => o.apply(acc) }) - - assert.equals(36, result) - }'''.interpretPropagatingErrors - } - - @Test - def void closuresWrongArguments() { - ''' - assert.throwsExceptionWithMessage( - "Wrong number of arguments for closure: expected 1 but you sent 2", - { { a => a + 2 }.apply(1, 2) } - ) - '''.test - } - - @Test - def void closuresWrongArguments2() { - ''' - assert.throwsExceptionWithMessage( - "Wrong number of arguments for closure: expected 1 but you sent 0", - { { a => a + 2 }.apply() } - ) - '''.test - } - - @Test - def void numberClosure() { - ''' - assert.equals(2, { a => a }.apply(2)) - '''.test - } - - @Test - def void nullClosure() { - ''' - assert.equals(null, { null }.apply()) - '''.test - } - - @Test - def void toStringClosure() { - ''' - assert.equals("{ a => a + 1 }", { a => a + 1 }.toString()) - '''.test - } - -} From bc597d5c964968c3cdddb3994fada2f34f218a87 Mon Sep 17 00:00:00 2001 From: Fernando Dodino Date: Mon, 21 Oct 2019 23:58:09 -0300 Subject: [PATCH 057/133] Removing date, string, number, void, range test cases => moved to sanity tests in wollok-language --- .../tests/interpreter/DateTestCase.xtend | 368 -------- .../tests/interpreter/DecimalTestCase.xtend | 58 -- .../tests/interpreter/NumberTestCase.xtend | 799 ------------------ .../tests/interpreter/RangeTestCase.xtend | 312 ------- .../tests/interpreter/StringTestCase.xtend | 435 ---------- .../tests/interpreter/VoidTestCase.xtend | 87 -- .../interpreter/numbers/ArithmeticTest.xtend | 76 -- .../MixedNumberTypesOperationsTest.xtend | 43 - .../numbers/NumberComparisonsTest.xtend | 88 -- .../numbers/NumberEqualityTest.xtend | 53 -- .../numbers/NumberExtensionsTest.xtend | 83 -- .../numbers/NumberIdentityTest.xtend | 67 -- 12 files changed, 2469 deletions(-) delete mode 100644 org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/DateTestCase.xtend delete mode 100644 org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/DecimalTestCase.xtend delete mode 100644 org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/NumberTestCase.xtend delete mode 100644 org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/RangeTestCase.xtend delete mode 100644 org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/StringTestCase.xtend delete mode 100644 org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/VoidTestCase.xtend delete mode 100644 org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/numbers/ArithmeticTest.xtend delete mode 100644 org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/numbers/MixedNumberTypesOperationsTest.xtend delete mode 100644 org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/numbers/NumberComparisonsTest.xtend delete mode 100644 org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/numbers/NumberEqualityTest.xtend delete mode 100644 org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/numbers/NumberExtensionsTest.xtend delete mode 100644 org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/numbers/NumberIdentityTest.xtend diff --git a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/DateTestCase.xtend b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/DateTestCase.xtend deleted file mode 100644 index 2fa221dec9..0000000000 --- a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/DateTestCase.xtend +++ /dev/null @@ -1,368 +0,0 @@ -package org.uqbar.project.wollok.tests.interpreter - -import java.time.LocalDate -import org.junit.Test - -/** - * - * @author dodain - */ -class DateTestCase extends AbstractWollokInterpreterTestCase { - - @Test - def void defaultDateCreationInitializesItsAttributesOk() { - ''' - const now = new Date() - assert.equals(now.day(), «LocalDate.now().dayOfMonth») - assert.equals(now.month(), «LocalDate.now().monthValue») - assert.equals(now.year(), «LocalDate.now().year») - '''.test - } - - @Test - def void initializedDateCreationInitializesItsAttributesOk() { - ''' - const otroNow = new Date(day = 1, month = 2, year = 2019) - assert.equals(otroNow.day(), 1) - assert.equals(otroNow.month(), 2) - assert.equals(otroNow.year(), 2019) - '''.test - } - - @Test - def void twoDatesAreEqualsBecauseTheyHaveNoTime() { - ''' - const now1 = new Date() - const now2 = new Date() - assert.that(now1.equals(now2)) - assert.that(now1 == now2) - '''.test - } - - def void twoEqualDatesCanBeDifferentObject() { - ''' - const now1 = new Date() - const now2 = new Date() - assert.that(now1 == now2) - assert.that(now1 !== now2) - '''.test - } - - @Test - def void year2000WasLeap() { - ''' - const year2000 = new Date(day = 4, month = 5, year = 2000) - assert.that(year2000.isLeapYear()) - '''.test - } - - // Default behavior is truncate decimals - // We should add more tests changing IDE preferences - @Test - def void year2000WasLeapWithDecimals() { - ''' - const year2000 = new Date(day = 4.8, month = 5.1, year = 2000.7) - assert.that(year2000.isLeapYear()) - '''.test - } - @Test - def void year2001WasNotLeap() { - ''' - const year2001 = new Date(day = 4, month = 5, year = 2001) - assert.notThat(year2001.isLeapYear()) - '''.test - } - - @Test - def void year2004WasLeap() { - ''' - const year2004 = new Date(day = 4, month = 5, year = 2004) - assert.that(year2004.isLeapYear()) - '''.test - } - - @Test - def void year2100WasNotLeap() { - ''' - const year2100 = new Date(day = 4, month = 5, year = 2100) - assert.notThat(year2100.isLeapYear()) - '''.test - } - - @Test - def void yesterdayIsLessThanToday() { - ''' - var yesterday = new Date().minusDays(1) - const today = new Date() - assert.that(yesterday < today) - '''.test - } - - @Test - def void allOperationsReturningADateAreCorrectWollokDates() { - ''' - assert.that(new Date().minusDays(1).day() !== null) - assert.that(new Date().minusDays(1).month() !== null) - assert.that(new Date().minusDays(1).year() !== null) - assert.that(new Date().plusDays(1).day() !== null) - assert.that(new Date().plusDays(1).month() !== null) - assert.that(new Date().plusDays(1).year() !== null) - assert.that(new Date().minusYears(1).day() !== null) - assert.that(new Date().minusYears(1).month() !== null) - assert.that(new Date().minusYears(1).year() !== null) - assert.that(new Date().plusYears(1).day() !== null) - assert.that(new Date().plusYears(1).month() !== null) - assert.that(new Date().plusYears(1).year() !== null) - '''.test - } - - @Test - def void a2001DateIsLessThanToday() { - ''' - const elyesterday = new Date(day = 10, month = 6, year = 2001) - const today = new Date() - assert.that(elyesterday < today) - '''.test - } - - @Test - def void todayIsBetweenYesterdayAndTomorrow() { - ''' - var yesterday = new Date() - yesterday = yesterday.minusDays(1) - const today = new Date() - var tomorrow = new Date() - tomorrow = tomorrow.plusDays(1) - assert.that(today > yesterday) - assert.that(today >= yesterday) - assert.that(today < tomorrow) - assert.that(today <= tomorrow) - assert.that(today.between(yesterday, tomorrow)) - '''.test - } - - @Test - def void tuesdayIsSecondDayOfWeek() { - ''' - const aDay = new Date(day = 7, month = 6, year = 2016) - assert.equals(aDay.internalDayOfWeek(), 2) - '''.test - } - - @Test - def void tuesdayDayOfWeekIsTuesdayObject() { - ''' - const aDay = new Date(day = 7, month = 6, year = 2016) - assert.equals(aDay.dayOfWeek(), tuesday) - '''.test - } - - @Test - def void differenceBetweenDatesPositive() { - ''' - const day1 = new Date(day = 7, month = 6, year = 2016) - const day2 = new Date(day = 9, month = 7, year = 2016) - assert.equals(day2 - day1, 32) - '''.test - } - - @Test - def void differenceBetweenDatesNegative() { - ''' - const day1 = new Date(day = 7, month = 6, year = 2016) - const day2 = new Date(day = 9, month = 7, year = 2016) - assert.equals(day1 - day2, -32) - '''.test - } - - @Test - def void differenceBetweenEqualDates() { - ''' - const day1 = new Date() - const day2 = new Date() - assert.equals(day2 - day1, 0) - '''.test - } - - @Test - def void addTwoMonths() { - ''' - const originalDay = new Date(day = 31, month = 12, year = 2015) - const finalDay = new Date(day = 29, month = 2, year = 2016) - const result = originalDay.plusMonths(2) - assert.that(result.equals(finalDay)) - '''.test - } - - @Test - def void subtractTwoMonths() { - ''' - const originalDay = new Date(day = 29, month = 2, year = 2016) - const finalDay = new Date(day = 29, month = 12, year = 2015) - const result = originalDay.minusMonths(2) - assert.that(result.equals(finalDay)) - '''.test - } - - @Test - def void subtractTwoMonthsPassingDecimals() { - ''' - const originalDay = new Date(day = 29, month = 2, year = 2016) - const finalDay = new Date(day = 29, month = 12, year = 2015) - const result = originalDay.minusMonths(2.4) - assert.that(result.equals(finalDay)) - '''.test - } - - @Test - def void addOneYear() { - ''' - const originalDay = new Date(day = 29, month = 2, year = 2016) - const finalDay = new Date(day = 28, month = 2, year = 2017) - const result = originalDay.plusYears(1) - assert.that(result.equals(finalDay)) - '''.test - } - - @Test - def void subtractOneYear() { - ''' - const originalDay = new Date(day = 28, month = 2, year = 2017) - const finalDay = new Date(day = 28, month = 2, year = 2016) - const result = originalDay.minusYears(1) - assert.that(result.equals(finalDay)) - '''.test - } - - @Test - def void toStringDefaultTest() { - ''' - const aDay = new Date(day = 28, month = 12, year = 2016) - assert.equals("28/12/16", aDay.toString()) - assert.equals("28/12/16", aDay.toSmartString(false)) - '''.test - } - - @Test - def void toStringWithA1DigitMonthTest() { - ''' - const aDay = new Date(day = 28, month = 2, year = 2016) - assert.equals("28/2/16", aDay.toString()) - assert.equals("28/2/16", aDay.toSmartString(false)) - '''.test - } - - @Test - def void plusDaysUsingNull() { - ''' - assert.throwsExceptionWithMessage("Operation plusDays doesn't support null parameters", { new Date(day = 28, month = 2, year = 2017).plusDays(null) }) - '''.test - } - - @Test - def void plusMonthsUsingNull() { - ''' - assert.throwsExceptionWithMessage("Operation plusMonths doesn't support null parameters", { new Date(day = 28, month = 2, year = 2017).plusMonths(null) }) - '''.test - } - - @Test - def void plusYearsUsingNull() { - ''' - assert.throwsExceptionWithMessage("Operation plusYears doesn't support null parameters", { new Date(day = 28, month = 2, year = 2017).plusYears(null) }) - '''.test - } - - @Test - def void differenceFail() { - ''' - assert.throwsExceptionWithMessage("Cannot convert parameter \"2\" to type wollok.lang.Date", { new Date(day = 28, month = 2, year = 2017) - "2" }) - '''.test - } - - @Test - def void minusDaysUsingNull() { - ''' - assert.throwsExceptionWithMessage("Operation minusDays doesn't support null parameters", { new Date(day = 28, month = 2, year = 2017).minusDays(null) }) - '''.test - } - - @Test - def void minusMonthsUsingNull() { - ''' - assert.throwsExceptionWithMessage("Operation minusMonths doesn't support null parameters", { new Date(day = 28, month = 2, year = 2017).minusMonths(null) }) - '''.test - } - - @Test - def void minusYearsUsingNull() { - ''' - assert.throwsExceptionWithMessage("Operation minusYears doesn't support null parameters", { new Date(day = 28, month = 2, year = 2017).minusYears(null) }) - '''.test - } - - @Test - def void betweenFail() { - ''' - assert.throwsExceptionWithMessage("Cannot convert parameter 2 to type wollok.lang.Date", { new Date(day = 28, month = 2, year = 2017).between(2, 9) }) - '''.test - } - - @Test - def void betweenNull() { - ''' - assert.throwsExceptionWithMessage("Operation > doesn't support null parameters", { new Date(day = 28, month = 2, year = 2017).between(null, null) }) - '''.test - } - - @Test - def void greaterThanFail() { - ''' - assert.throwsExceptionWithMessage("Cannot convert parameter 2 to type wollok.lang.Date", { new Date(day = 28, month = 2, year = 2017) > 2 }) - '''.test - } - - @Test - def void plusDaysFail() { - ''' - assert.throwsExceptionWithMessage("Cannot convert parameter \"a\" to type wollok.lang.Number", { new Date(day = 28, month = 2, year = 2017).plusDays("a") }) - '''.test - } - - @Test - def void plusMonthsFail() { - ''' - assert.throwsExceptionWithMessage("Cannot convert parameter \"a\" to type wollok.lang.Number", { new Date(day = 28, month = 2, year = 2017).plusMonths("a") }) - '''.test - } - - @Test - def void plusYearsFail() { - ''' - assert.throwsExceptionWithMessage("Cannot convert parameter \"a\" to type wollok.lang.Number", { new Date(day = 28, month = 2, year = 2017).plusYears("a") }) - '''.test - } - - @Test - def void minusDaysFail() { - ''' - assert.throwsExceptionWithMessage("Cannot convert parameter \"a\" to type wollok.lang.Number", { new Date(day = 28, month = 2, year = 2017).minusDays("a") }) - '''.test - } - - @Test - def void minusMonthsFail() { - ''' - assert.throwsExceptionWithMessage("Cannot convert parameter \"a\" to type wollok.lang.Number", { new Date(day = 28, month = 2, year = 2017).minusMonths("a") }) - '''.test - } - - @Test - def void minusYearsFail() { - ''' - assert.throwsExceptionWithMessage("Cannot convert parameter \"a\" to type wollok.lang.Number", { new Date(day = 28, month = 2, year = 2017).minusYears("a") }) - '''.test - } - - -} diff --git a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/DecimalTestCase.xtend b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/DecimalTestCase.xtend deleted file mode 100644 index 6ffed00399..0000000000 --- a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/DecimalTestCase.xtend +++ /dev/null @@ -1,58 +0,0 @@ -package org.uqbar.project.wollok.tests.interpreter - -import org.junit.Test - -/** - * - * @author dodain - */ -class DecimalTestCase extends AbstractWollokInterpreterTestCase { - - @Test - def void roundUp() { - ''' - assert.equals(14, 13.224.roundUp()) - assert.equals(-14, -13.224.roundUp()) - assert.equals(16, 15.942.roundUp()) - assert.equals(15, 15.0.roundUp()) - assert.equals(-15, -15.0.roundUp()) - '''.test - } - - @Test - def void roundUpDecimals() { - ''' - assert.equals(1.224, 1.223445.roundUp(3)) - assert.equals(-1.224, -1.223445.roundUp(3)) - assert.equals(14.617, 14.6165.roundUp(3)) - assert.equals(14.6165, 14.6165.roundUp(6)) - '''.test - } - - @Test - def void truncate() { - ''' - assert.equals(1.223, 1.223445.truncate(3)) - assert.equals(14.616, 14.6165.truncate(3)) - assert.equals(14.61, 14.6165.truncate(2)) - assert.equals(14.61, 14.61.truncate(3)) - '''.test - } - - @Test - def void roundUpNegativeDecimalsThrowsError() { - ''' - assert.throwsExceptionWithMessage("Scale must be an integer and positive value", { 1.223445.truncate(-3) }) - assert.throwsExceptionWithMessage("Scale must be an integer and positive value", { 1.223445.roundUp(-3) }) - '''.test - } - - @Test - def void roundUpAlphabeticDecimalsThrowsError() { - ''' - assert.throwsExceptionWithMessage("Cannot convert parameter \"A\" to type wollok.lang.Number", { 1.223445.truncate("A") }) - assert.throwsExceptionWithMessage("Cannot convert parameter \"B\" to type wollok.lang.Number", { 1.223445.roundUp("B") }) - '''.test - } - -} \ No newline at end of file diff --git a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/NumberTestCase.xtend b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/NumberTestCase.xtend deleted file mode 100644 index f9432d10c6..0000000000 --- a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/NumberTestCase.xtend +++ /dev/null @@ -1,799 +0,0 @@ -package org.uqbar.project.wollok.tests.interpreter - -import org.junit.Ignore -import org.junit.Test -import org.uqbar.project.wollok.interpreter.core.WollokProgramExceptionWrapper - -/** - * - * @author jfernandes - * @author dodain - */ -class NumberTestCase extends AbstractWollokInterpreterTestCase { - - @Test - def void integersAsResultValueOfNative() { - ''' - assert.equals(4, "hola".length()) - '''.test - } - - @Test - def void add() { - ''' - assert.equals(4, 3 + 1) - assert.equals(4.0, 3.0 + 1) - assert.equals(4.0, 3.0 + 1.0) - assert.equals(4.0, 3 + 1.0) - assert.equals(4, 4 + 0.0) - assert.equals(4, 4.0 + 0.0) - assert.equals(4, 4.0 + 0) - assert.equals(4, 4 + 0) - '''.test - } - - @Test - def void addWithFailingParameters() { - ''' - assert.throwsExceptionWithMessage("Operation doesn't support parameter 18/12/17", { 3 + new Date(day = 18, month = 12, year = 2017) }) - assert.throwsExceptionWithMessage("Operation doesn't support parameter pepe", { 3 + "pepe" }) - '''.test - } - - @Test - def void add1ToNull() { - ''' - assert.throwsExceptionWithMessage("Operation + doesn't support null parameters", { 1 + null }) - '''.test - } - - @Test - def void max() { - ''' - assert.equals(7, 4.max(7)) - '''.test - } - - @Test - def void maxFailingParameter() { - ''' - assert.throwsExceptionWithMessage("Operation doesn't support parameter 21/12/17", { 4.min(new Date(day = 21, month = 12, year = 2017)) }) - '''.test - } - - @Test - def void maxUsingNull() { - ''' - assert.throwsExceptionWithMessage("Operation max doesn't support null parameters", { 4.max(null) }) - '''.test - } - - @Test - def void min() { - ''' - assert.equals(4, 4.min(7)) - '''.test - } - - @Test - def void minFailingParameter() { - ''' - assert.throwsExceptionWithMessage("Operation doesn't support parameter 21/12/17", { 4.min(new Date(day = 21, month = 12, year = 2017)) }) - '''.test - } - - @Test - def void minUsingNull() { - ''' - assert.throwsExceptionWithMessage("Operation min doesn't support null parameters", { 4.min(null) }) - '''.test - } - - @Test - def void subtractUsingNull() { - ''' - assert.throwsExceptionWithMessage("Operation - doesn't support null parameters", { 1 - null }) - '''.test - } - - @Test - def void subtractFail() { - ''' - assert.throwsExceptionWithMessage("Operation doesn't support parameter a", { 4 - "a" }) - '''.test - } - - @Test - def void multiplyUsingNull() { - ''' - assert.throwsExceptionWithMessage("Operation * doesn't support null parameters", { 1 * null }) - '''.test - } - - @Test - def void multiplyFail() { - ''' - assert.throwsExceptionWithMessage("Operation doesn't support parameter a", { 4 * "a" }) - '''.test - } - - @Test - def void multiply() { - ''' - assert.equals(8, 4 * 2) - assert.equals(8.0, 4 * 2.0) - assert.equals(8.0, 4.0 * 2.0) - assert.equals(8.0, 4.0 * 2) - '''.test - } - - @Test - def void addSeveralDecimals() { - ''' - assert.equals(4.00001, 3.000004 + 1.000006) - assert.equals(4.00001, 3.000002 + 1.000006) - assert.equals(4, 3.000002 + 1.000002) - '''.test - } - - @Test - def void subtractSeveralDecimals() { - ''' - assert.equals(-0.00001, 4.000004 - 4.000006) - assert.equals(0, 4.000007 - 4.000006) - assert.equals(2, 3.000002 - 1.000001) - assert.equals(1.99999, 3.000002 - 1.000006) - assert.equals(1.99978, 3.000002 - 1.000222) - '''.test - } - - @Test - def void multiplySeveralDecimals() { - ''' - assert.equals(8, 4.00000000001 * 2.000000000003) - assert.equals(0, 4.00222222222222000000001 * 0) - assert.equals(4.00270, 4.00222222222222000000001 * 1.00012) - assert.equals(4.00415, 4.00222522222222000000001 * 1.00048) - '''.test - } - - @Test - def void multiplyByZero() { - ''' - assert.equals(6.2500000 * 0.5 * 0, 0) - assert.equals(6.2500000 * 0, 0) - assert.equals(0.0 * 0, 0) - assert.equals(0.0 * 0.0, 0) - assert.equals(0 * 0.0, 0) - '''.test - } - - @Test - def void divide() { - ''' - assert.equals(0.3, 3 / 10) - assert.equals(2.5, 5 / 2) - assert.equals(2, 4 / 2) - assert.equals(2, 4 / 2.0) - '''.test - } - - @Test - def void divideZero() { - ''' - assert.equals(0, 0 / 10) - assert.equals(0, 0 / 10.0) - assert.equals(0, 0.0 / 10.0) - assert.equals(0, 0 / 10.0) - assert.equals(0, 0 / 100.0) - assert.equals(0, 1 / 100000000000.0) - '''.test - } - - @Test - def void divideSeveralDecimals() { - ''' - assert.equals(0.51235, 5.123456 / 10.00000011) - assert.equals(0.51235, 5.123456 / 10) - assert.equals(0.51235, 5123456 / 10000000) - '''.test - } - - @Test - def void divisionByZero() { - ''' - assert.throwsExceptionWithMessage("/ by zero", { 1 / 0 }) - assert.throwsExceptionWithMessage("/ by zero", { 1.0 / 0 }) - assert.throwsExceptionWithMessage("/ by zero", { 1.0 / 0.0 }) - assert.throwsExceptionWithMessage("/ by zero", { 1 / 0.0 }) - '''.test - } - - @Test - def void dividePeriodicDecimals() { - ''' - assert.equals(0.72727, 40 / 55) - assert.equals(0.72727, 40 / 55.0) - assert.equals(0.72727, 40.0 / 55.0) - assert.equals(0.72727, 40.0 / 55) - assert.equals(0.33333, 1 / 3) - assert.equals(0.66667, 2 / 3) - '''.test - } - - @Test - def void divideDecimals() { - ''' - assert.equals(0.3, 3 / 10.0) - assert.equals(0.3, 3.0 / 10.0) - assert.equals(2.5, 5 / 2.0) - assert.equals(2, 4.0 / 2.0) - '''.test - } - - @Test - def void divisionUsingNull() { - ''' - assert.throwsExceptionWithMessage("Operation / doesn't support null parameters", { 3 / null }) - '''.test - } - - @Test - def void divisionFail() { - ''' - assert.throwsExceptionWithMessage("Operation doesn't support parameter a", { 3 / "a" }) - '''.test - } - - @Test - def void timesUsingPositiveValue() { - ''' - var x = 0 - 6.times { i => x += 1 } - assert.equals(6, x) - '''.test - } - - @Test - def void timesUsingZero() { - ''' - var x = 0 - 0.times { i => x += 1 } - assert.equals(0, x) - '''.test - } - - // We need a more intention revealing message - perhaps when type system gets activated - @Test - @Ignore - def void timesFail() { - ''' - assert.throwsExceptionWithMessage("Operation forEach doesn't support null parameters", { 4.times("a") } ) - '''.test - } - - @Test - def void timesUsingNull() { - ''' - assert.throwsExceptionWithMessage("Operation times doesn't support null parameters", { 4.times(null) } ) - '''.test - } - - @Test - def void integersFromNativeObjects() { - ''' - assert.equals(3, "hola".length() - 1) - '''.test - } - - @Test - def void integersBetweenTrue() { - ''' - assert.that(3.between(1, 5)) - '''.test - } - - @Test - def void integersBetweenFalse() { - ''' - assert.notThat(3.between(5, 9)) - '''.test - } - - @Test - def void betweenUsingNull() { - ''' - assert.throwsExceptionWithMessage("Operation < doesn't support null parameters", { 2.between(1, null) } ) - '''.test - } - - @Test - def void betweenFail() { - ''' - assert.throwsExceptionWithMessage("Cannot convert parameter \"a\" to type wollok.lang.Number", { 2.between("a", 2) } ) - '''.test - } - - @Test - def void absoluteValueOfAPositiveInteger() { - ''' - assert.equals(3, 3.abs()) - assert.equals(0, 0.abs()) - assert.equals(0, 0.0.abs()) - assert.equals(60, (-60.0).abs()) - assert.equals(60.664, (-60.664).abs()) - assert.equals(60.664, (60.664).abs()) - '''.test - } - - @Test - def void absoluteValueOfANegativeInteger() { - ''' - assert.equals(3, (-3).abs()) - '''.test - } - - @Test - def void squareRoot() { - ''' - assert.equals(3, 9.squareRoot()) - '''.test - } - - @Test - def void square() { - ''' - assert.equals(9, 3.square()) - '''.test - } - - @Test - def void lessThan() { - ''' - assert.that(3 < 7) - assert.notThat(13 < 7) - '''.test - } - - @Test - def void remainder() { - ''' - const remainder = 17.rem(7) - const remainder2 = 12.rem(6) - assert.equals(3, remainder) - assert.equals(0, remainder2) - assert.equals(0.11521, 1.1152112.rem(1.0000002)) - '''.test - } - - @Test - def void remainderUsingNull() { - ''' - assert.throwsExceptionWithMessage("Operation rem doesn't support null parameters", { 2.rem(null) } ) - '''.test - } - - @Test - def void remainderFail() { - ''' - assert.throwsExceptionWithMessage("Operation doesn't support parameter a", { 2.rem("a") } ) - '''.test - } - - @Test - def void even() { - ''' - assert.notThat(3.even()) - assert.that(260.even()) - '''.test - } - - @Test - def void odd() { - ''' - assert.that(3.odd()) - assert.notThat(260.odd()) - '''.test - } - - @Test - def void gcd() { - ''' - const gcd1 = 5.gcd(25) - const gcd2 = 25.gcd(20) - const gcd3 = 2.gcd(3) - assert.equals(5, gcd1) - assert.equals(5, gcd2) - assert.equals(1, gcd3) - '''.test - } - - @Test - def void gcdUsingNull() { - ''' - assert.throwsExceptionWithMessage("Operation gcd doesn't support null parameters", { 4.gcd(null) }) - '''.test - } - - @Test - def void gcdForInvalidArguments() { - ''' - assert.throwsExceptionWithMessage("Operation doesn't support parameter 1/1/18", { 4.gcd(new Date(day = 1, month = 1, year = 2018)) }) - '''.test - } - - // @Test - def void gcdForDecimalsIsInvalid() { - try { - ''' - program a { - (5.5).gcd(12) - } - '''.interpretPropagatingErrors - fail("decimals should not understand gcd message") - } catch (WollokProgramExceptionWrapper e) { - assertTrue(e.wollokMessage.startsWith("5.5 does not understand gcd(param1)")) - } - } - - // @Test - def void gcdForDecimalsIsInvalid2() { - try { - ''' - program a { - console.println((5).gcd(12.3)) - } - '''.interpretPropagatingErrors - fail("gcd works also for decimal argument!!") - } catch (WollokProgramExceptionWrapper e) { - assertTrue(e.wollokMessage.startsWith("gcd expects an integer as first argument")) - } - } - - @Test - def void lcm() { - ''' - const lcm1 = 5.lcm(25) - const lcm2 = 7.lcm(8) - const lcm3 = 10.lcm(15) - assert.equals(25, lcm1) - assert.equals(56, lcm2) - assert.equals(30, lcm3) - '''.test - } - - @Test - def void lcmUsingNull() { - ''' - assert.throwsExceptionWithMessage("Operation lcm doesn't support null parameters", { 4.lcm(null) }) - '''.test - } - - @Test - def void lcmForInvalidArguments() { - ''' - assert.throwsExceptionWithMessage("Operation doesn't support parameter 1/1/18", { 4.lcm(new Date(day = 1, month = 1, year = 2018)) }) - '''.test - } - - @Test - def void realDigits() { - ''' - assert.equals(4, 1024.digits()) - assert.equals(3, (-220).digits()) - '''.test - } - - @Test - def void decimalDigits() { - ''' - assert.equals(4, 10.24.digits()) - assert.equals(4, (-10.24).digits()) - '''.test - } - - @Test - def void isPrime() { - ''' - assert.that(3.isPrime()) - assert.notThat(4.isPrime()) - assert.that(5.isPrime()) - assert.notThat(88.isPrime()) - assert.that(17.isPrime()) - '''.test - } - - @Test - def void randomForIntegers() { - ''' - const random1 = 3.randomUpTo(8) - assert.that(random1.between(3, 8)) - assert.notThat(random1.between(9, 10)) - '''.test - } - - @Test - def void randomUpToFail() { - ''' - assert.throwsExceptionWithMessage("Cannot convert parameter \"a\" to type wollok.lang.Number", { 4.randomUpTo("a") } ) - '''.test - } - - @Test - def void randomUpUsingNull() { - ''' - assert.throwsExceptionWithMessage("Operation randomUpTo doesn't support null parameters", { 4.randomUpTo(null) } ) - '''.test - } - @Test - def void randomForReals() { - ''' - const random1 = (3.2).randomUpTo(8.9) - assert.that(random1.between(3.2, 8.9)) - assert.notThat(random1.between(9.0, 10.11)) - '''.test - } - - @Test - def void integerDivision() { - ''' - assert.equals(4, 16.div(4)) - assert.equals(4, 18.div(4)) - assert.equals(5, 21.div(4)) - assert.equals(5, (21.2).div(4.1)) - assert.throwsExceptionWithMessage("Operation div doesn't support null parameters", { 4.div(null) }) - '''.test - } - - @Test - def void integerDivisionByZero() { - ''' - assert.throwsExceptionWithMessage("/ by zero", { 16.div(0) }) - assert.throwsExceptionWithMessage("/ by zero", { (21.2).div(0.0) }) - '''.test - } - - @Test - def void integerDivisionFail() { - ''' - assert.throwsExceptionWithMessage("Operation doesn't support parameter a", { 8.div("a") }) - '''.test - } - - @Test - def void integerDivisionUsingNull() { - ''' - assert.throwsExceptionWithMessage("Operation div doesn't support null parameters", { 8.div(null) }) - '''.test - } - - @Test - def void printString() { - ''' - assert.equals("4", 4.printString()) - assert.equals("4.1", (4.1).printString()) - '''.test - } - - @Test - def void negativeExponentiation() { - ''' - assert.equals(0.2, 5 ** (-1)) - assert.equals(0.2, 5 ** (-1.0)) - assert.equals(0.2, 5.0 ** (-1.0)) - assert.equals(0.2, 5.0 ** (-1)) - assert.equals(1, 5.0 ** 0) - assert.equals(1, 5.0 ** 0.0) - assert.equals(1, 5 ** 0) - assert.equals(1, 5 ** 0.0) - '''.test - } - - @Test - def void integerExponentiation() { - ''' - assert.equals(25, 5 ** 2) - assert.equals(25, 5 ** 2.0) - assert.equals(25.0, 5.0 ** 2) - assert.equals(25.0, 5.0 ** 2.0) - '''.test - } - - @Test - def void exponentiationUsingNull() { - ''' - assert.throwsExceptionWithMessage("Operation ** doesn't support null parameters", { 4 ** null } ) - '''.test - } - - @Test - def void exponentiationFail() { - ''' - assert.throwsExceptionWithMessage("Operation doesn't support parameter a", { 4 ** "a" } ) - '''.test - } - - @Test - def void exponentiationPrecedence() { - ''' - assert.equals(24, 3 * 2 ** 3) - assert.equals(36, 4.0 * 3 ** 2) - assert.equals(5, 1 + 2 ** 2) - '''.test - } - - @Test - def void integerRoundUp() { - ''' - assert.equals(5, (10/2).roundUp(2)) - '''.test - } - - @Test - def void roundUpUsingNull() { - ''' - assert.throwsExceptionWithMessage("Operation roundUp doesn't support null parameters", { (10/2).roundUp(null) }) - '''.test - } - - @Test - def void roundUpFail() { - ''' - assert.throwsExceptionWithMessage("Cannot convert parameter \"a\" to type wollok.lang.Number", { (10/2).roundUp("a") }) - '''.test - } - - @Test - def void integerTruncate() { - ''' - assert.equals(5, (10/2).truncate(2)) - '''.test - } - - @Test - def void truncateUsingNull() { - ''' - assert.throwsExceptionWithMessage("Operation truncate doesn't support null parameters", { (10/2).truncate(null) }) - '''.test - } - - @Test - def void truncateFail() { - ''' - assert.throwsExceptionWithMessage("Cannot convert parameter \"a\" to type wollok.lang.Number", { (10/2).truncate("a") }) - '''.test - } - - @Test - def void doubleRoundUp() { - ''' - assert.equals(1.3, (5/4).roundUp(1)) - '''.test - } - - @Test - def void doubleTruncate() { - ''' - assert.equals(1.2, (5/4).truncate(1)) - '''.test - } - - @Test - def void modulus() { - ''' - assert.equals(1, 5 % 4) - assert.equals(1.5, 5.5 % 4) - assert.equals(0, 4 % 4) - assert.equals(0, 4.0 % 4) - assert.equals(0, 4.0 % 1) - '''.test - } - - @Test - def void modulusUsingNull() { - ''' - assert.throwsExceptionWithMessage("Operation % doesn't support null parameters", { 2 % null } ) - '''.test - } - - @Test - def void modulusFail() { - ''' - assert.throwsExceptionWithMessage("Operation doesn't support parameter a", { 2 % "a" } ) - '''.test - } - - @Test - def void numberComparison() { - ''' - assert.that((1.1 / 1) > (1.000002)) - assert.that(1 < 1.0001) - assert.notThat(1 < 1) - assert.notThat(1 > 1) - assert.that(1 <= 1) - assert.that(1 >= 1) - '''.test - } - - @Test - def void greaterThanFail() { - ''' - assert.throwsExceptionWithMessage("Cannot convert parameter [1, 2] to type wollok.lang.Number", { 3 > [1, 2] }) - '''.test - } - - @Test - def void greaterThanUsingNull() { - ''' - assert.throwsExceptionWithMessage("Operation > doesn't support null parameters", { 3 > null }) - '''.test - } - - @Test - def void lesserThanFail() { - ''' - assert.throwsExceptionWithMessage("Cannot convert parameter [1, 2] to type wollok.lang.Number", { 3 < [1, 2] }) - '''.test - } - - @Test - def void lesserThanUsingNull() { - ''' - assert.throwsExceptionWithMessage("Operation < doesn't support null parameters", { 3 < null }) - '''.test - } - - @Test - def void veryBigIntegerAdd() { - ''' - var a = 100000000000000000 - assert.equals(100000000000000001, a + 1) - '''.test - } - - @Test - def void veryBigIntegerMultiply() { - ''' - var a = 100000000000000000 - assert.equals(100000000000000000, a * 1) - '''.test - } - - @Test - def void veryBigIntegerDivide() { - ''' - var a = 100000000000000000 - assert.equals(100000, a / 1000000000000) - '''.test - } - - @Test - def void plusOne(){ - ''' - program xx{ - assert.equals(1, +1) - } - '''.interpretPropagatingErrors - } - - @Test - def void addingBigNumbersIssue1398(){ - ''' - class Cuenta { - var property monto = 0 - method depositar_monto(un_monto) { - monto += un_monto - } - method consultar_saldo() { - return monto - } - } - program xx { - const patricio = new Cuenta() - patricio.depositar_monto(100000000000) - assert.equals("100000000000", patricio.monto().toString()) - } - '''.interpretPropagatingErrors - } - -} \ No newline at end of file diff --git a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/RangeTestCase.xtend b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/RangeTestCase.xtend deleted file mode 100644 index 79b3b9fbe1..0000000000 --- a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/RangeTestCase.xtend +++ /dev/null @@ -1,312 +0,0 @@ -package org.uqbar.project.wollok.tests.interpreter - -import org.junit.Test - -/** - * Tests wollok ranges - * - * @author jfernandes - */ -class RangeTestCase extends AbstractWollokInterpreterTestCase { - - @Test - def void testForEach() { - ''' - const range = 0 .. 10 - var sum = 0 - assert.that(range != null) - range.forEach { i => sum += i } - assert.equals(55, sum) - '''.test - } - - @Test - def void fold() { - ''' - var range = 0 .. 10 - var sum = range.fold(0, { acum, each => acum + each }) - assert.equals(55, sum) - '''.test - } - - @Test - def void flatMap() { - ''' - var range = 1 .. 4 - var flatMap = range.flatMap { n => 1 .. n } - assert.equals([1, 1, 2, 1, 2, 3, 1, 2, 3, 4], flatMap) - '''.test - } - - @Test - def void sum() { - ''' - var range = 0 .. 9 - assert.equals(45, range.sum()) - '''.test - } - - @Test - def void sumClosure() { - ''' - var range = 0 .. 9 - assert.equals(90, range.sum({ n => n * 2 })) - '''.test - } - - @Test - def void contains() { - ''' - var range = 0 .. 9 - assert.that(range.contains(9)) - assert.that(range.contains(0)) - assert.that(range.contains(4)) - assert.notThat(range.contains(-1)) - assert.notThat(range.contains(10)) - '''.test - } - - @Test - def void size() { - ''' - assert.equals(11, (0..10).size()) - assert.equals(10, (12..21).size()) - assert.equals(7, (-3..3).size()) - assert.equals(3, new Range(start= 2, end = 10, step = 3).size()) - assert.equals(4, new Range(start= 2, end = 11, step = 3).size()) - assert.equals(3, new Range(start= 10, end = 2, step = -3).size()) - assert.equals(4, new Range(start= 11, end = 2, step = -3).size()) - assert.equals(1, new Range(start= 10, end = 11,step = 3).size()) - assert.equals(1, new Range(start= 10, end = 10,step = 3).size()) - assert.equals(0, new Range(start= 10, end = 9, step = 3).size()) - assert.equals(1, new Range(start= 10, end = 9, step = -3).size()) - assert.equals(1, new Range(start= 10, end = 10,step = -3).size()) - assert.equals(0, new Range(start= 10, end = 11,step = -3).size()) - assert.equals(0, new Range(start= 2, end = 10, step = -3).size()) - assert.equals(0, new Range(start= 10, end = 2, step = 3).size()) - '''.test - - } - - @Test - def void isEmpty() { - ''' - assert.notThat((0..10).isEmpty()) - assert.notThat((0 .. 0).isEmpty()) - '''.test - } - - @Test - def void any() { - ''' - assert.that((0..10).any({ elem => elem == 5})) - assert.notThat((0..10).any({ elem => elem == 15})) - '''.test - } - - @Test - def void all() { - ''' - var range = 0 .. 10 - assert.notThat(range.all({ elem => elem.even()})) - assert.that(range.any({ elem => elem < 11})) - '''.test - } - - @Test - def void map() { - ''' - var range = 0 .. 5 - assert.that([0, 2, 4, 6, 8, 10] == range.map({ elem => elem * 2})) - '''.test - } - - @Test - def void filter() { - ''' - const range = 0 .. 10 - const evenFiltered = range.filter({ elem => elem.even() }) - assert.that([0, 2, 4, 6, 8, 10] == evenFiltered) - '''.test - } - - @Test - def void count() { - ''' - const range = 0 .. 9 - const evenCount = range.count({ elem => elem.even() }) - assert.equals(5, evenCount) - '''.test - } - - @Test - def void anyOne() { - ''' - const range = 0 .. 10 - const anyOne = range.anyOne() - assert.that(range.contains(anyOne)) - '''.test - } - - @Test - def void anyOneProbability() { - ''' - const range = 0 .. 10 - range.step(2) - const counter = new Dictionary() - range.forEach({n => counter.put(n,0)}) - 5000.times({ i => - var n = range.anyOne() - var c = counter.get(n) + 1 - counter.put(n,c) - }) - range.forEach({n => assert.that(counter.get(n) > 500)}) - '''.test - } - - @Test - def void min() { - ''' - const range = -2 .. 10 - const range2 = 7 .. 3 - assert.equals(-2, range.min()) - assert.equals(3, range2.min()) - '''.test - } - - @Test - def void max() { - ''' - const range = -22 .. -3 - const range2 = 7 .. 3 - assert.equals(-3, range.max()) - assert.equals(7, range2.max()) - '''.test - } - - @Test - def void testRangeForDecimalsNotAllowed() { - ''' - const range = new Range(start = 2.4, end = 5.7) - assert.equals(range.start(), 2) - assert.equals(range.end(), 5) - assert.equals(range.step(), 1) - assert.equals([2, 3, 4, 5], range.asList()) - '''.test - } - - @Test - def void testRangeForStringsNotAllowed() { - ''' - assert.throwsException({ => new Range(start = "ABRACADBRA", end = "PATA")}) - '''.test - } - - @Test - def void find() { - ''' - const range = 1 .. 9 - const evenFound = range.find({ elem => elem.even() }) - assert.equals(2, evenFound) - '''.test - } - - @Test - def void findOrValue() { - ''' - const range = 1 .. 9 - const valueNotFound = range.findOrDefault({ elem => elem > 55 }, 22) - assert.equals(22, valueNotFound) - '''.test - } - - @Test - def void findOrElse() { - ''' - var encontro = true - const range = 1 .. 9 - const valueNotFound = range.findOrElse({ elem => elem > 55 }, { encontro = false }) - assert.notThat(encontro) - '''.test - } - - @Test - def void sortedBy() { - ''' - const range = 1 .. 9 - const sortedRange = range.sortedBy({ a, b => a.even() && b.even().negate() }) - assert.equals([2, 4, 6, 8, 1, 3, 5, 7, 9], sortedRange) - '''.test - } - - @Test - def void sumStep3() { - ''' - const range = 1 .. 14 - range.step(3) - assert.equals(35, range.sum()) - '''.test - } - - @Test - def void countStepMinus3() { - ''' - const range = 8 .. 1 - range.step(-3) - assert.equals(2, range.count({ elem => elem.even() })) - '''.test - } - - @Test - def void filterStepMinus3() { - ''' - const range = 8 .. 1 - range.step(-3) - assert.equals([8,2], range.filter({ elem => elem.even() })) - '''.test - } - - @Test - def void testRangeForDecimalsIfIntegersAreAllowed() { - ''' - const range = new Range(start = 2.0, end = 5.0) - assert.equals(5, range.max()) - '''.test - } - - @Test - def void rangeWithNullMustFail() { - ''' - assert.throwsExceptionWithMessage("Operation .. doesn't support null parameters", { => 1..null }) - '''.test - } - - @Test - def void forEachUsingNullMustFail() { - ''' - assert.throwsExceptionWithMessage("Operation forEach doesn't support null parameters", { => (1..4).forEach(null) }) - '''.test - } - - @Test - def void filterUsingNullMustFail() { - ''' - assert.throwsExceptionWithMessage("Operation filter doesn't support null parameters", { => (1..4).filter(null) }) - '''.test - } - - @Test - def void mapUsingNullMustFail() { - ''' - assert.throwsExceptionWithMessage("Operation map doesn't support null parameters", { => (1..4).map(null) }) - '''.test - } - - @Test - def void anyUsingNullMustFail() { - ''' - assert.throwsExceptionWithMessage("Operation any doesn't support null parameters", { => (1..4).any(null) }) - '''.test - } - -} \ No newline at end of file diff --git a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/StringTestCase.xtend b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/StringTestCase.xtend deleted file mode 100644 index acb8d24632..0000000000 --- a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/StringTestCase.xtend +++ /dev/null @@ -1,435 +0,0 @@ -package org.uqbar.project.wollok.tests.interpreter - -import org.uqbar.project.wollok.tests.interpreter.AbstractWollokInterpreterTestCase -import org.junit.Test - -/** - * @author tesonep - * @author dodain - */ -class StringTestCase extends AbstractWollokInterpreterTestCase { - - @Test - def void testWithAssertsOk() { - ''' - const x = "Hola, wollok!".substring(0, 3) - assert.equals("Hol", x) - '''.test - } - - @Test - def void greaterThanUsingNull() { - ''' - assert.throwsExceptionWithMessage("Operation > doesn't support null parameters", { "hola" > null }) - '''.test - } - - @Test - def void lessThanUsingNull() { - ''' - assert.throwsExceptionWithMessage("Operation < doesn't support null parameters", { "hola" < null }) - '''.test - } - - @Test - def void testLessThan() { - ''' - assert.that("miau" < "ufa") - '''.test - } - - @Test - def void testLessThanFalseCondition() { - ''' - assert.notThat("zapallo" <= "ufa") - '''.test - } - - @Test - def void testGreaterOrEqualThan() { - ''' - assert.that("zapallo" >= "ufa") - assert.that("zapallo" >= "zapallo") - assert.notThat("aguacero" >= "guarecer") - '''.test - } - - @Test - def void testLessOrEqualThanForLess() { - ''' - assert.that("miau" <= "ufa") - '''.test - } - - @Test - def void testLessOrEqualThanForEqual() { - ''' - assert.that("miau" <= "miau") - '''.test - } - - @Test - def void testContains() { - ''' - assert.that("aguacate".contains("cat")) - assert.that("aguacate".contains("agua")) - assert.notThat("aguacate".contains("managua")) - assert.notThat("aguacate".contains("AGUA")) - '''.test - } - - @Test - def void testIndexOf(){ - ''' - assert.equals(0, "aguacate".indexOf("agua")) - assert.equals(4, "aguacate".indexOf("cat")) - assert.throwsException( {"aguacate".indexOf("trinitrotolueno")} ) - '''.test - } - - @Test - def void testLastIndexOf(){ - ''' - assert.equals(6, "aguacate".lastIndexOf("te")) - assert.equals(5, "aguacate".lastIndexOf("a")) - assert.throwsException( {"aguacate".lastIndexOf("trinitrotolueno")} ) - '''.test - } - @Test - def void testisEmpty() { - ''' - assert.that("".isEmpty()) - assert.notThat("pepe".isEmpty()) - '''.test - } - - @Test - def void testEqualEqual() { - ''' - const unString = "perro" - const otroString = "per" + "ro" - assert.that(unString == otroString) - '''.test - } - - @Test - def void testEqualsIgnoreCaseOk() { - ''' - assert.that("mARejaDA".equalsIgnoreCase("MAREJADA")) - '''.test - } - - @Test - def void splitUsingNull() { - ''' - assert.throwsExceptionWithMessage("Operation split doesn't support null parameters", { "hola".split(null) }) - '''.test - } - - @Test - def void split() { - ''' - const result = "Esto Es una prueba".split(" ") - const result2 = "Esto|Es|una|prueba".split("|") - const result3 = "Esto,Es,una,prueba".split(",") - const comparison = ["Esto", "Es", "una", "prueba"] - (0..3).forEach { i => assert.that(result.get(i) == comparison.get(i)) } - (0..3).forEach { i => assert.that(result2.get(i) == comparison.get(i)) } - (0..3).forEach { i => assert.that(result3.get(i) == comparison.get(i)) } - '''.test - } - - @Test - def void testReplace() { - ''' - const mardel = "Mar del Plata" - const tuyu = mardel.replace("Plata", "Tuyu") - assert.that("Mar del Tuyu" == tuyu) - '''.test - } - - @Test - def void randomForStringsAreNotAllowedAnymore() { - ''' - assert.throwsException({ => "fafafa".randomUpTo(8.9)}) - '''.test - } - - @Test - def void takeUsingNull() { - ''' - assert.throwsExceptionWithMessage("Operation take doesn't support null parameters", { "hola".take(null) }) - '''.test - } - - @Test - def void take() { - ''' - assert.equals("cl", "clearly".take(2)) - assert.equals("clearly", "clearly".take(8)) - assert.equals("", "clearly".take(0)) - '''.test - } - - @Test - def void dropUsingNull() { - ''' - assert.throwsExceptionWithMessage("Operation drop doesn't support null parameters", { "hola".drop(null) }) - '''.test - } - - @Test - def void drop() { - ''' - assert.equals("early", "clearly".drop(2)) - assert.equals("", "clearly".drop(8)) - assert.equals("clearly", "clearly".drop(0)) - '''.test - } - - @Test - def void words() { - ''' - const words = "in wollok everything is an object".words() - assert.equals("in", words.get(0)) - assert.equals("object", words.get(5)) - '''.test - } - - @Test - def void capitalize() { - ''' - assert.equals("alfa romeo".capitalize(), "Alfa Romeo") - assert.equals("AUDI".capitalize(), "Audi") - assert.equals("bmw".capitalize(), "Bmw") - assert.equals("ONETWO THREE FOUR".capitalize(), "Onetwo Three Four") - '''.test - } - - @Test - def void printString() { - ''' - assert.equals("hola".printString(), "\"hola\"") - assert.equals("3".printString(), "\"3\"") - '''.test - } - - @Test - def void charAtUsingNull() { - ''' - assert.throwsExceptionWithMessage("Operation charAt doesn't support null parameters", { "hola".charAt(null) }) - '''.test - } - - @Test - def void charAtFail() { - ''' - assert.throwsExceptionWithMessage("a does not understand isInteger()", { "hola".charAt("a") }) - '''.test - } - - @Test - def void charAt() { - ''' - assert.equals("l", "hola".charAt(2)) - '''.test - } - - @Test - def void concatHappyPath() { - ''' - assert.equals("hey".concat("jude"), "heyjude") - '''.test - } - - @Test - def void concatWithNumbers() { - ''' - assert.equals("u".concat(2), "u2") - '''.test - } - - @Test - def void reverse() { - ''' - assert.equals("aloh", "hola".reverse()) - assert.equals("", "".reverse()) - '''.test - } - - @Test - def void takeLeft() { - ''' - assert.equals("hol", "hola".takeLeft(3)) - assert.equals("", "".takeLeft(3)) - assert.equals("", "hola".takeLeft(0)) - assert.equals("h", "hola".takeLeft(1.5)) - '''.test - } - - @Test - def void takeLeftFail() { - ''' - assert.throwsExceptionWithMessage("-1 must be a positive integer value", { "hola".takeLeft(-1) }) - '''.test - } - - @Test - def void takeRight() { - ''' - assert.equals("ola", "hola".takeRight(3)) - assert.equals("", "".takeRight(3)) - assert.equals("", "hola".takeRight(0)) - assert.equals("a", "hola".takeRight(1.5)) - '''.test - } - - @Test - def void takeRightFail() { - ''' - assert.throwsExceptionWithMessage("-1 must be a positive integer value", { "hola".takeRight(-1) }) - '''.test - } - - @Test - def void startsWithUsingNull() { - ''' - assert.throwsExceptionWithMessage("Operation startsWith doesn't support null parameters", { "hola".startsWith(null) }) - '''.test - } - - @Test - def void startsWithFail() { - ''' - assert.throwsExceptionWithMessage("Operation doesn't support parameter 1/1/18", { "hola".startsWith(new Date(day = 1, month = 1, year = 2018)) }) - '''.test - } - - @Test - def void startsWith() { - ''' - assert.that("hola".startsWith("ho")) - '''.test - } - - @Test - def void endsWithUsingNull() { - ''' - assert.throwsExceptionWithMessage("Operation endsWith doesn't support null parameters", { "hola".endsWith(null) }) - '''.test - } - - @Test - def void endsWithFail() { - ''' - assert.throwsExceptionWithMessage("Operation doesn't support parameter 1/1/18", { "hola".endsWith(new Date(day = 1, month = 1, year = 2018)) }) - '''.test - } - - @Test - def void endsWith() { - ''' - assert.that("hola".endsWith("la")) - '''.test - } - - @Test - def void indexOfUsingNull() { - ''' - assert.throwsExceptionWithMessage("Operation indexOf doesn't support null parameters", { "hola".indexOf(null) }) - '''.test - } - - @Test - def void indexOfFail() { - ''' - assert.throwsExceptionWithMessage("Operation doesn't support parameter 1/1/18", { "hola".indexOf(new Date(day = 1, month = 1, year = 2018)) }) - '''.test - } - - @Test - def void lastIndexOfUsingNull() { - ''' - assert.throwsExceptionWithMessage("Operation lastIndexOf doesn't support null parameters", { "hola".lastIndexOf(null) }) - '''.test - } - - @Test - def void lastIndexOfFail() { - ''' - assert.throwsExceptionWithMessage("Operation doesn't support parameter 1/1/18", { "hola".lastIndexOf(new Date(day = 1, month = 1, year = 2018)) }) - '''.test - } - - @Test - def void containsUsingNull() { - ''' - assert.throwsExceptionWithMessage("Operation contains doesn't support null parameters", { "hola".contains(null) }) - '''.test - } - - @Test - def void containsFail() { - ''' - assert.throwsExceptionWithMessage("Operation doesn't support parameter 1/1/18", { "hola".contains(new Date(day = 1, month = 1, year = 2018)) }) - '''.test - } - - @Test - def void substring2UsingNull() { - ''' - assert.throwsExceptionWithMessage("Operation substring doesn't support null parameters", { "hola".substring(null, null) }) - '''.test - } - - @Test - def void substring2Fail() { - ''' - assert.throwsExceptionWithMessage("Cannot convert parameter \"a\" to type wollok.lang.Number", { "hola".substring("a", "e") }) - '''.test - } - - @Test - def void substring1UsingNull() { - ''' - assert.throwsExceptionWithMessage("Operation substring doesn't support null parameters", { "hola".substring(null) }) - '''.test - } - - @Test - def void substring1Fail() { - ''' - assert.throwsExceptionWithMessage("Cannot convert parameter \"a\" to type wollok.lang.Number", { "hola".substring("a") }) - '''.test - } - - @Test - def void equalsIgnoreCaseNull() { - ''' - assert.throwsExceptionWithMessage("Operation equalsIgnoreCase doesn't support null parameters", { "hola".equalsIgnoreCase(null) }) - '''.test - } - - @Test - def void equalsIgnoreCaseFail() { - ''' - assert.throwsExceptionWithMessage("1/1/18 does not understand toUpperCase()", { "hola".equalsIgnoreCase(new Date(day = 1, month = 1, year = 2018)) }) - '''.test - } - - @Test - def void replaceUsingNull() { - ''' - assert.throwsExceptionWithMessage("Operation replace doesn't support null parameters", { "hola".replace("1", null) }) - assert.throwsExceptionWithMessage("Operation replace doesn't support null parameters", { "hola".replace(null, "2") }) - '''.test - } - - @Test - def void replaceFail() { - ''' - assert.throwsExceptionWithMessage("Operation doesn't support parameter 1/1/18, a", { "hola".replace(new Date(day = 1, month = 1, year = 2018), "a") }) - '''.test - } - -} diff --git a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/VoidTestCase.xtend b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/VoidTestCase.xtend deleted file mode 100644 index bde8aafb10..0000000000 --- a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/VoidTestCase.xtend +++ /dev/null @@ -1,87 +0,0 @@ -package org.uqbar.project.wollok.tests.interpreter - -import org.junit.Test - -/** - * - * @author dodain - */ -class VoidTestCase extends AbstractWollokInterpreterTestCase { - - def String wkoWithVoidMethods() { - ''' - class Ejemplo { - var fecha - - constructor(_fecha) { - fecha = _fecha - } - - method hoy() { - fecha.day() - } - - } - - object comparar { - - var date = new Date() - var fecha = new Ejemplo(date) - - method diaMayorA(otroDia) { - return otroDia > fecha.hoy() - } - - } - ''' - } - - @Test - def void voidInAssert() { - ''' - «wkoWithVoidMethods» - - program a { - var dia = new Date() - var fecha = new Ejemplo(dia) - assert.throwsExceptionWithMessage( - "Message send \"fecha.hoy()\" produces no value (missing return in method?)", - { assert.equals("27", fecha.hoy()) } - ) - } - '''.interpretPropagatingErrors - } - - @Test - def void voidInBinaryOperation() { - ''' - «wkoWithVoidMethods» - - program a { - var dia = new Date() - var fecha = new Ejemplo(dia) - assert.throwsExceptionWithMessage( - "Message send \"fecha.hoy()\" produces no value (missing return in method?)", - { assert.that(comparar.diaMayorA(15)) } - ) - } - '''.interpretPropagatingErrors - } - - @Test - def void voidInUnaryOperation() { - ''' - «wkoWithVoidMethods» - - program a { - var dia = new Date() - var fecha = new Ejemplo(dia) - assert.throwsExceptionWithMessage( - "Message send \"fecha.hoy()\" produces no value (missing return in method?)", - { assert.that(fecha.hoy().abs()) } - ) - } - '''.interpretPropagatingErrors - } - -} \ No newline at end of file diff --git a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/numbers/ArithmeticTest.xtend b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/numbers/ArithmeticTest.xtend deleted file mode 100644 index 98d607dd04..0000000000 --- a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/numbers/ArithmeticTest.xtend +++ /dev/null @@ -1,76 +0,0 @@ -package org.uqbar.project.wollok.tests.interpreter.numbers - -import org.apache.log4j.Logger -import org.junit.Test -import org.junit.runners.Parameterized.Parameter -import org.junit.runners.Parameterized.Parameters -import org.uqbar.project.wollok.interpreter.core.WollokObject -import org.uqbar.project.wollok.tests.base.AbstractWollokParameterizedInterpreterTest - -import static extension org.uqbar.project.wollok.interpreter.nativeobj.WollokJavaConversions.* - -/** - * @author tesonep - */ -class ArithmeticTest extends AbstractWollokParameterizedInterpreterTest { - - val Logger log = Logger.getLogger(this.class) - - @Parameter(0) - public String expression - - @Parameter(1) - public Number expectedResult - - @Parameters(name="{0} == {1}") - static def Iterable data() { - #[ - // Addition - #["1 + 1", 2], - #["1 + 1.5", 2.5], - #["1.5 + 1", 2.5], - #["1.3 + 1.7", 3.0], - - // Subtraction - #["1 - 1", 0], - #["1 - 1.5", -0.5], - #["1.5 - 1", 0.5], - #["1.5 - 1.5", 0.0], - - // Product - #["1 * 1", 1], - #["1 * 1.5", 1.5], - #["1.5 * 1", 1.5], - #["1.5 * 1.5", 2.25], // TODO Should be #["1.4*1.4", "1.96"], but it does not work - - // Division - #["3 / 2", 1.5], - #["3 / 2.0", 1.5], - #["3.0 / 2", 1.5], - #["2.25 / 1.5", 1.5], - - // Exponentiation - #["3 ** 2", 9], - #["9 ** 0.5", 3.0], - #["1.5 ** 2", 2.25], - #["2.25 ** 0.5", 1.5], - - // Module - #["10 % 3", 1] - ] - } - - @Test - def void validateResult() { - val WollokObject actual = expression.evaluate as WollokObject - val WollokObject expected = expectedResult.javaToWollok as WollokObject - - try { - assertTrue(expected.call("==", actual).wollokToJava(Boolean) as Boolean) - } - catch (AssertionError e) { - log.error("Expected " + expected + " but got " + actual) - throw e - } - } -} \ No newline at end of file diff --git a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/numbers/MixedNumberTypesOperationsTest.xtend b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/numbers/MixedNumberTypesOperationsTest.xtend deleted file mode 100644 index 170445b772..0000000000 --- a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/numbers/MixedNumberTypesOperationsTest.xtend +++ /dev/null @@ -1,43 +0,0 @@ -package org.uqbar.project.wollok.tests.interpreter.numbers - -import org.junit.Test -import org.uqbar.project.wollok.tests.interpreter.AbstractWollokInterpreterTestCase - -/** - * Tests that the numbers works as expected when mixing integer and doubles - * - * @author tesonep - */ -class MixedNumberTypesOperationsTest extends AbstractWollokInterpreterTestCase { - - @Test - def void testEquals() { - ''' - program a { - assert.equals(2 * 2.0, 2.0 * 2) - assert.equals(2 * 2.0, 2.0 * 2) - - assert.equals(1 + 2.0, 1.0 + 2) - assert.equals(1 + 2.0, 1.0 + 2) - - assert.equals(1 - 2.0, 1.0 - 2) - assert.equals(1 - 2.0, 1.0 - 2) - - assert.equals(1 / 2.0, 1.0 / 2) - assert.equals(1 / 2.0, 1.0 / 2) - } - '''.interpretPropagatingErrors - } - @Test - def void testFloatOperation(){ - ''' - program a { - assert.equals(100 * 1.1, 110.0) - assert.equals(100 * 1.1, 110.0) - - assert.equals(1.4 * 1.4, 1.96) - assert.equals(1.4 * 1.4, 1.96) - } - '''.interpretPropagatingErrors - } -} diff --git a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/numbers/NumberComparisonsTest.xtend b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/numbers/NumberComparisonsTest.xtend deleted file mode 100644 index 598cd60035..0000000000 --- a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/numbers/NumberComparisonsTest.xtend +++ /dev/null @@ -1,88 +0,0 @@ -package org.uqbar.project.wollok.tests.interpreter.numbers - -import org.junit.Test -import org.junit.runners.Parameterized.Parameter -import org.junit.runners.Parameterized.Parameters -import org.uqbar.project.wollok.tests.base.AbstractWollokParameterizedInterpreterTest - -import static extension org.uqbar.project.wollok.utils.StringUtils.* - -class NumberComparisonsTest extends AbstractWollokParameterizedInterpreterTest { - @Parameter(0) - public String expression - - @Parameters(name="{0}") - static def Iterable data() { - ''' - that(2 > 1) - notThat(1 > 1) - notThat(1 > 2) - - that(2 >= 1) - that(1 >= 1) - notThat(1 >= 2) - - notThat(2 < 1) - notThat(1 < 1) - that(1 < 2) - - notThat(2 <= 1) - that(1 <= 1) - that(1 <= 2) - - that(2 > 1.0) - notThat(1 > 1.0) - notThat(1 > 2.0) - - that(2 >= 1.0) - that(1 >= 1.0) - notThat(1 >= 2.0) - - notThat(2 < 1.0) - notThat(1 < 1.0) - that(1 < 2.0) - - notThat(2 <= 1.0) - that(1 <= 1.0) - that(1 <= 2.0) - - that(2.0 > 1) - notThat(1.0 > 1) - notThat(1.0 > 2) - - that(2.0 >= 1) - that(1.0 >= 1) - notThat(1.0 >= 2) - - notThat(2.0 < 1) - notThat(1.0 < 1) - that(1.0 < 2) - - notThat(2.0 <= 1) - that(1.0 <= 1) - that(1.0 <= 2) - - that(2.0 > 1.0) - notThat(1.0 > 1.0) - notThat(1.0 > 2.0) - - that(2.0 >= 1.0) - that(1.0 >= 1.0) - notThat(1.0 >= 2.0) - - notThat(2.0 < 1.0) - notThat(1.0 < 1.0) - that(1.0 < 2.0) - - notThat(2.0 <= 1.0) - that(1.0 <= 1.0) - that(1.0 <= 2.0) - - '''.lines.asParameters - } - - @Test - def void runAssertion() { assertion.interpretPropagatingErrors } - - def assertion() ''' program p { assert.«expression» } ''' -} \ No newline at end of file diff --git a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/numbers/NumberEqualityTest.xtend b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/numbers/NumberEqualityTest.xtend deleted file mode 100644 index ab5b405943..0000000000 --- a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/numbers/NumberEqualityTest.xtend +++ /dev/null @@ -1,53 +0,0 @@ -package org.uqbar.project.wollok.tests.interpreter.numbers - -import org.junit.Test -import org.junit.runners.Parameterized.Parameter -import org.junit.runners.Parameterized.Parameters -import org.uqbar.project.wollok.tests.base.AbstractWollokParameterizedInterpreterTest - -import static extension org.uqbar.project.wollok.utils.StringUtils.* - -/** - * Tests for numbers equality - * - * @author tesonep - * @author npasserini - * @author jfernandes - */ -class NumberEqualityTest extends AbstractWollokParameterizedInterpreterTest { - @Parameter(0) - public String expression - - @Parameters(name="{0}") - static def Iterable data() { - ''' - assert.that(1 == 1) - assert.that(1 == 1.0) - assert.that(1.0 == 1) - assert.that(1.0 == 1.0) - - assert.notThat(1 == 2) - assert.notThat(1.0 == 2) - assert.notThat(1 == 2.0) - assert.notThat(1.0 == 2.0) - - assert.that(1 != 2) - assert.that(1 != 2.0) - assert.that(1.0 != 2) - assert.that(1.0 != 2.0) - - assert.notThat(1 != 1) - assert.notThat(1.0 != 1) - assert.notThat(1 != 1.0) - assert.notThat(1.0 != 1.0) - - - assert.notThat(1 == "aString") - '''.lines.asParameters - } - - @Test - def void runAssertion() { assertion.interpretPropagatingErrors } - - def assertion() ''' program p { «expression» } ''' -} \ No newline at end of file diff --git a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/numbers/NumberExtensionsTest.xtend b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/numbers/NumberExtensionsTest.xtend deleted file mode 100644 index 0630d0ea16..0000000000 --- a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/numbers/NumberExtensionsTest.xtend +++ /dev/null @@ -1,83 +0,0 @@ -package org.uqbar.project.wollok.tests.interpreter.numbers - -import org.junit.Test -import org.junit.runners.Parameterized.Parameter -import org.junit.runners.Parameterized.Parameters -import org.uqbar.project.wollok.tests.base.AbstractWollokParameterizedInterpreterTest - -class NumberExtensionsTest extends AbstractWollokParameterizedInterpreterTest { - @Parameter(0) - public String expression - - @Parameter(1) - public String expectedResult - - @Parameters(name="{0} == {1}") - static def Iterable data() { - #[ - // Max - #["1.max(2)", "2"], - #["(1.0).max(2)", "2"], - #["1.max(2.0)", "2.0"], - #["(1.0).max(2.0)", "2.0"], - - #["2.max(1)", "2"], - #["(2.0).max(1)", "2.0"], - #["2.max(1.0)", "2"], - #["(2.0).max(1.0)", "2.0"], - - // Min - #["1.min(2)", "1"], - #["(1.0).min(2)", "1.0"], - #["1.min(2.0)", "1"], - #["(1.0).min(2.0)", "1.0"], - - #["2.min(1)", "1"], - #["(2.0).min(1)", "1"], - #["2.min(1.0)", "1.0"], - #["(2.0).min(1.0)", "1.0"], - - // Abs - #["1.abs()", "1"], - #["(-1).abs()", "1"], - #["(1.0).abs()", "1.0"], - #["(-1.0).abs()", "1.0"], - - // LimitBetween - #["1.limitBetween(2,3)", "2"], - #["(1.0).limitBetween(2,3)", "2"], - #["1.limitBetween(2.0,3)", "2.0"], - #["(1.0).limitBetween(2.0,3)", "2.0"], - - #["4.limitBetween(2,3)", "3"], - #["(4.0).limitBetween(2,3)", "3"], - #["4.limitBetween(2,3.0)", "3.0"], - #["(4.0).limitBetween(2,3.0)", "3.0"], - - #["4.limitBetween(2,10)", "4"], - #["(4.0).limitBetween(2,10)", "4.0"], - - #["1.limitBetween(3,2)", "2"], - #["(1.0).limitBetween(3,2)", "2"], - #["1.limitBetween(3,2.0)", "2.0"], - #["(1.0).limitBetween(3,2.0)", "2.0"], - - #["4.limitBetween(3,2)", "3"], - #["(4.0).limitBetween(3,2)", "3"], - #["4.limitBetween(3.0,2)", "3.0"], - #["(4.0).limitBetween(3.0,2)", "3.0"], - - #["4.limitBetween(10,2)", "4"], - #["(4.0).limitBetween(10,2)", "4.0"] - ] - } - - @Test - def void runAssertion() { assertion.interpretPropagatingErrors } - - def assertion() ''' - program p { - assert.equals(«expectedResult», «expression») - } - ''' -} \ No newline at end of file diff --git a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/numbers/NumberIdentityTest.xtend b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/numbers/NumberIdentityTest.xtend deleted file mode 100644 index 067e9d5126..0000000000 --- a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/numbers/NumberIdentityTest.xtend +++ /dev/null @@ -1,67 +0,0 @@ -package org.uqbar.project.wollok.tests.interpreter.numbers - -import org.junit.Test -import org.uqbar.project.wollok.tests.interpreter.AbstractWollokInterpreterTestCase - -/** - * Tests number literals cache. - * The interpreter won't create new instances for the same number. - * - * @author jfernandes - */ -class NumberIdentityTest extends AbstractWollokInterpreterTestCase { - - @Test - def void testTwoLiterals() { - ''' - program p { - assert.that(33.identity() == 33.identity()) - }'''.interpretPropagatingErrors - } - - @Test - def void testTwoVariablesInSameProgram() { - ''' - program p { - var a = 33 - var b = 33 - - assert.that(a.identity() == b.identity()) - }'''.interpretPropagatingErrors - } - - @Test - def void testVariablesInDifferentScopes() { - ''' - program p { - var a = 33 - - var o = object { - var b = 33 - method getB() { return b } - } - - assert.that(a.identity() == o.getB().identity()) - }'''.interpretPropagatingErrors - } - - @Test - def void testTwoDoubleLiterals() { - ''' - program p { - assert.that((33.0).identity() == (33.0).identity()) - }'''.interpretPropagatingErrors - } - - @Test - def void testNonIdenticalTwoDoubleLiterals() { - ''' - program p { - const thirtyThree = 33 - const anotherThirtyThree = 33 - assert.notThat(33.0 !== 33) - assert.notThat(anotherThirtyThree !== thirtyThree) - assert.that(34 !== anotherThirtyThree) - }'''.interpretPropagatingErrors - } -} \ No newline at end of file From 114398007db343c3a5f4f63244127a29ac829bc4 Mon Sep 17 00:00:00 2001 From: Fernando Dodino Date: Wed, 23 Oct 2019 18:25:23 -0300 Subject: [PATCH 058/133] Deleting Collection sanity tests --- .../interpreter/CollectionTestCase.xtend | 596 ------------------ .../interpreter/DictionaryTestCase.xtend | 202 ------ .../tests/interpreter/ListTestCase.xtend | 243 ------- .../tests/interpreter/SetTestCase.xtend | 340 ---------- .../InstanceVariableInitializationTest.xtend | 72 --- .../interpreter/classes/MethodTest.xtend | 93 --- .../interpreter/classes/ObjectTest.xtend | 23 - .../wollok/tests/sdk/CollectionTest.xtend | 152 ----- .../project/wollok/tests/sdk/ListTest.xtend | 447 ------------- .../project/wollok/tests/sdk/SetTest.xtend | 346 ---------- 10 files changed, 2514 deletions(-) delete mode 100644 org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/CollectionTestCase.xtend delete mode 100644 org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/DictionaryTestCase.xtend delete mode 100644 org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/ListTestCase.xtend delete mode 100644 org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/SetTestCase.xtend delete mode 100644 org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/classes/InstanceVariableInitializationTest.xtend delete mode 100644 org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/classes/MethodTest.xtend delete mode 100644 org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/classes/ObjectTest.xtend delete mode 100644 org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/sdk/CollectionTest.xtend delete mode 100644 org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/sdk/ListTest.xtend delete mode 100644 org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/sdk/SetTest.xtend diff --git a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/CollectionTestCase.xtend b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/CollectionTestCase.xtend deleted file mode 100644 index 58257256ff..0000000000 --- a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/CollectionTestCase.xtend +++ /dev/null @@ -1,596 +0,0 @@ -package org.uqbar.project.wollok.tests.interpreter - -import org.junit.Test -import org.uqbar.project.wollok.interpreter.core.WollokProgramExceptionWrapper - -/** - * - */ -class CollectionTestCase extends AbstractWollokInterpreterTestCase { - - def instantiateCollectionAsNumbersVariable() { - "const numbers = [22, 2, 10]" - } - - def instantiateCollectionWithA2() { - "const collectionWithA2 = [2]" - } - - def instantiateEmptyCollection() { - "const emptyCollection = []" - } - - def instantiateStrings() { - "const strings = ['hello', 'hola', 'bonjour', 'ciao', 'hi']" - } - - @Test - def void min() { - ''' - «instantiateStrings» - assert.equals('hi', strings.min{e=> e.length() }) - '''.test - } - - @Test - def void minUsingNull() { - ''' - assert.throwsExceptionWithMessage("Operation min doesn't support null parameters", { => [1, 2].min(null) }) - '''.test - } - - - @Test - def void minNoArgs() { - ''' - «instantiateCollectionAsNumbersVariable» - assert.equals(2, numbers.min() ) - assert.equals(1, [1].min()) - assert.throwsException({[].min()}) - '''.test - } - - @Test - def void minIfEmpty() { - ''' - «instantiateStrings» - assert.equals('hi', strings.minIfEmpty({ e => e.length() }, { 'lista vacia' })) - assert.equals('lista vacia', [].minIfEmpty({ e => e.length() }, { 'lista vacia' })) - '''.test - } - - @Test - def void minIfEmptyUsingNull() { - ''' - assert.throwsExceptionWithMessage("Operation minIfEmpty doesn't support null parameters", { => [1, 2].minIfEmpty(null) }) - '''.test - } - - @Test - def void minIfEmptyNoArgs() { - ''' - assert.equals(1, [3,1,2].minIfEmpty({ 99 })) - assert.equals(99, [].minIfEmpty({ 99 })) - '''.test - } - - @Test - def void max() { - try - ''' - «instantiateStrings» - const r = strings.max{e=> e.length() } - assert.equals('bonjour', strings.max{e=> e.length() }) - '''.test - catch (WollokProgramExceptionWrapper e) - fail(e.message) - } - - @Test - def void maxUsingNull() { - ''' - assert.throwsExceptionWithMessage("Operation max doesn't support null parameters", { => [1, 2].max(null) }) - '''.test - } - - @Test - def void maxNoArgs() { - ''' - «instantiateCollectionAsNumbersVariable» - assert.equals(22, numbers.max() ) - assert.equals(1, [1].max()) - assert.throwsException({[].max()}) - '''.test - } - - @Test - def void maxIfEmpty() { - ''' - «instantiateStrings» - assert.equals('bonjour', strings.maxIfEmpty({ e => e.length() }, { 'lista vacia' })) - assert.equals('lista vacia', [].maxIfEmpty({ e => e.length() }, { 'lista vacia' })) - '''.test - } - - @Test - def void maxIfEmptyUsingNull() { - ''' - assert.throwsExceptionWithMessage("Operation maxIfEmpty doesn't support null parameters", { => [1, 2].maxIfEmpty(null) }) - '''.test - } - - @Test - def void maxIfEmptyNoArgs() { - ''' - assert.equals(3, [1,3,2].maxIfEmpty({ 99 })) - assert.equals(99, [].maxIfEmpty({ 99 })) - '''.test - } - - @Test - def void size() { - ''' - «instantiateCollectionAsNumbersVariable» - assert.equals(3, numbers.size()) - '''.test - } - - @Test - def void contains() { - ''' - «instantiateCollectionAsNumbersVariable» - assert.that(numbers.contains(22)) - assert.that(numbers.contains(2)) - assert.that(numbers.contains(10)) - '''.test - } - - @Test - def void containsForAListOfWKOs() { - ''' - object a {} - object b {} - object c {} - object d {} - program p { - const l = [a, b, c] - assert.that(l.contains(a)) - assert.that(l.contains(b)) - assert.that(l.contains(c)) - assert.notThat(l.contains(d)) - assert.notThat(l.contains("hello world")) - assert.notThat(l.contains(4)) - }'''.interpretPropagatingErrors - } - - @Test - def void uniqueElement() { - ''' - assert.equals(1, [1].uniqueElement()) - '''.test - } - - @Test - def void uniqueElementWithEmptyCollection() { - ''' - assert.throwsExceptionWithMessage("Illegal operation 'uniqueElement' on empty collection", { => [].uniqueElement() }) - '''.test - } - - @Test - def void uniqueElementWithManyElements() { - ''' - assert.throwsExceptionWithMessage("Illegal operation 'uniqueElement' on collection with 2 elements", { => [1, 2].uniqueElement() }) - '''.test - } - - @Test - def void anyUsingNull() { - ''' - assert.throwsExceptionWithMessage("Operation any doesn't support null parameters", { => [1, 2].any(null) }) - '''.test - } - - @Test - def void any() { - ''' - «instantiateCollectionAsNumbersVariable» - assert.that(numbers.any{e=> e > 20}) - assert.that(numbers.any{e=> e > 0}) - assert.notThat(numbers.any{e=> e < 0}) - '''.test - } - - @Test - def void remove() { - ''' - «instantiateCollectionAsNumbersVariable» - numbers.remove(22) - assert.that(2 == numbers.size()) - '''.test - } - - @Test - def void clear() { - ''' - «instantiateCollectionAsNumbersVariable» - numbers.clear() - assert.that(0 == numbers.size()) - '''.test - } - - @Test - def void isEmpty() { - ''' - «instantiateCollectionAsNumbersVariable» - assert.notThat(numbers.isEmpty()) - '''.test - } - - @Test - def void forEachUsingNull() { - ''' - assert.throwsExceptionWithMessage("Operation forEach doesn't support null parameters", { => [1, 2].forEach(null) }) - '''.test - } - - @Test - def void forEach() { - ''' - «instantiateCollectionAsNumbersVariable» - - var sum = 0 - numbers.forEach({n => sum += n}) - - assert.equals(34, sum) - '''.test - } - - @Test - def void allUsingNull() { - ''' - assert.throwsExceptionWithMessage("Operation all doesn't support null parameters", { => [1, 2].all(null) }) - '''.test - } - - @Test - def void all() { - ''' - «instantiateCollectionAsNumbersVariable» - assert.that(numbers.all({n => n > 0})) - assert.notThat(numbers.all({n => n > 5})) - '''.test - } - - @Test - def void filterUsingNull() { - ''' - assert.throwsExceptionWithMessage("Operation filter doesn't support null parameters", { => [1, 2].filter(null) }) - '''.test - } - - @Test - def void filter() { - ''' - «instantiateCollectionAsNumbersVariable» - var greaterThanFiveElements = numbers.filter({n => n > 5}) - assert.that(greaterThanFiveElements.size() == 2) - '''.test - } - - @Test - def void mapUsingNull() { - ''' - assert.throwsExceptionWithMessage("Operation map doesn't support null parameters", { => [1, 2].map(null) }) - '''.test - } - - @Test - def void map() { - ''' - «instantiateCollectionAsNumbersVariable» - var halfs = numbers.map({n => n / 2}) - - assert.equals(3, halfs.size()) - assert.that(halfs.contains(11)) - assert.that(halfs.contains(5)) - assert.that(halfs.contains(1)) - '''.test - } - - @Test - def void mapReturnsList() { - ''' - const evens = #{1,2,3}.map({n => n.even()}) - - assert.equals(3, evens.size()) - assert.equals(1, evens.occurrencesOf(true)) - assert.equals(2, evens.occurrencesOf(false)) - '''.test - } - - @Test - def void shortCutAvoidingParenthesis() { - ''' - «instantiateCollectionAsNumbersVariable» - var greaterThanFiveElements = numbers.filter{n => n > 5} - assert.that(greaterThanFiveElements.size() == 2) - '''.test - } - - @Test - def void anyOne() { - ''' - «instantiateCollectionAsNumbersVariable» - const anyOne = numbers.anyOne() - assert.that(numbers.contains(anyOne)) - '''.test - } - - @Test - def void equalsWithMethodName() { - ''' - const a = [23, 2, 1] - const b = [23, 2, 1] - assert.that(a.equals(b)) - '''.test - } - - @Test - def void equalsWithEqualsEquals() { - ''' - const a = [23, 2, 1] - const b = [23, 2, 1] - assert.that(a == b) - '''.test - } - - @Test - def void testToString() { - ''' - «instantiateCollectionAsNumbersVariable» - assert.equals("[22, 2, 10]", numbers.toString()) - '''.test - } - - @Test - def void testToStringWithObjectRedefiningToStringInWollok() { - ''' - object myObject { - override method internalToSmartString(alreadyShown) = "My Object" - } - program p { - const a = [23, 2, 1, myObject] - assert.equals("[23, 2, 1, My Object]", a.toString()) - }'''.interpretPropagatingErrors - } - - @Test - def void findWhenElementExists() { - ''' - «instantiateCollectionAsNumbersVariable» - assert.equals(22, numbers.find{e=> e > 20}) - '''.test - } - - @Test - def void findOrElse() { - ''' - «instantiateCollectionAsNumbersVariable» - assert.equals(50, numbers.findOrElse({e=> e > 1000}, { 50 })) - '''.test - } - - @Test - def void findWhenElementDoesNotExist() { - ''' - «instantiateCollectionAsNumbersVariable» - assert.throwsException { numbers.find{e => e > 1000} } - '''.test - } - - @Test - def void findOrDefaultWhenElementDoesNotExist() { - ''' - «instantiateCollectionAsNumbersVariable» - assert.equals(50, numbers.findOrDefault({e=> e > 1000}, 50)) - '''.test - } - - @Test - def void findOrDefaultWhenElementExists() { - ''' - «instantiateCollectionAsNumbersVariable» - assert.equals(22, numbers.findOrDefault({e=> e > 20}, 50)) - '''.test - } - - @Test - def void countUsingNull() { - ''' - assert.throwsExceptionWithMessage("Operation count doesn't support null parameters", { => [1, 2].count(null) }) - '''.test - } - - @Test - def void count() { - ''' - «instantiateCollectionAsNumbersVariable» - assert.equals(1, numbers.count{e=> e > 20}) - assert.equals(3, numbers.count{e=> e > 0}) - assert.equals(0, numbers.count{e=> e < 0}) - '''.test - } - - @Test - def void sumUsingNull() { - ''' - assert.throwsExceptionWithMessage("Operation sum doesn't support null parameters", { => [1, 2].sum(null) }) - '''.test - } - - @Test - def void sum() { - ''' - «instantiateCollectionAsNumbersVariable» - - assert.equals(34, numbers.sum {n => n}) - '''.test - } - - @Test - def void concatenation() { - ''' - const lista1 = [1, 4] - const lista2 = [2, 7] - const lista3 = lista1 + lista2 - assert.equals([1, 4], lista1) - assert.equals([1, 4, 2, 7], lista3) - '''.test - } - - @Test - def void sumNoArgsWithManyElements() { - ''' - «instantiateCollectionAsNumbersVariable» - assert.equals(34, numbers.sum()) - '''.test - } - - @Test - def void sumNoArgsWithNoElementsSucceeds() { - ''' - assert.equals(0, [].sum()) - '''.test - } - - - @Test - def void sumNoArgsWithSingleElement() { - ''' - assert.equals(5, [5].sum()) - '''.test - } - - @Test - def void occurrencesOfInEmptyCollectionIsZero() { - ''' - assert.equals(0, [].occurrencesOf(4)) - '''.test - } - - @Test - def void occurrencesOfInSingleElementCollection() { - ''' - assert.equals(1, [4].occurrencesOf(4)) - assert.equals(0, [4].occurrencesOf('Hola')) - '''.test - } - - @Test - def void occurrencesOfInMultiElementCollection() { - ''' - assert.equals(3, [1, 2, 3, 4, 4, 1, 2, 4, 0].occurrencesOf(4)) - assert.equals(1, [1, 'Hola', 'mundo'].occurrencesOf('Hola')) - assert.equals(1, #{'Hola', 'mundo', 4, 4}.occurrencesOf(4)) - '''.test - } - - @Test - def void occurrencesOfInSetsNotGreaterThanOne() { - ''' - assert.equals(1, #{'Hola', 3.0, 4, 4}.occurrencesOf(4)) - '''.test - } - - @Test - def void lastWithNoElementsFails() { - ''' - assert.throwsException({ [].last() }) - '''.test - } - - @Test - def void lastWithSingleElementSucceeds() { - ''' - assert.equals('Hola', ['Hola'].last()) - '''.test - } - - @Test - def void lastWithManyElementsSucceeds() { - ''' - assert.equals(4, [1, 2, 3, 4].last()) - '''.test - } - - @Test - def void removeAll() { - ''' - «instantiateCollectionAsNumbersVariable» - numbers.removeAll(numbers.drop(1)) - assert.equals([numbers.head()], numbers) - '''.test - } - - @Test - def void removeAllSuchThat() { - ''' - «instantiateCollectionAsNumbersVariable» - «instantiateCollectionWithA2» - «instantiateEmptyCollection» - numbers.removeAllSuchThat({it => it >= 10}) - assert.equals(collectionWithA2, numbers) - numbers.removeAllSuchThat({it => it.odd()}) - assert.equals(collectionWithA2, numbers) - numbers.removeAllSuchThat({it => it.even()}) - assert.equals(emptyCollection, numbers) - numbers.removeAllSuchThat({it => it.even()}) - assert.equals(emptyCollection, numbers) - '''.test - } - - @Test - def void removeOnIteration() { - ''' - «instantiateCollectionAsNumbersVariable» - - numbers.forEach({n => numbers.remove(n)}) - assert.that(numbers.isEmpty()) - - '''.test - } - @Test - - def void addOnIteration() { - ''' - «instantiateCollectionAsNumbersVariable» - - numbers.forEach({n => numbers.add(n * 2)}) - assert.that(numbers.contains(2)) - assert.that(numbers.contains(22)) - assert.that(numbers.contains(10)) - assert.that(numbers.contains(44)) - assert.that(numbers.contains(4)) - assert.that(numbers.contains(20)) - '''.test - } - - @Test - def void sortedBy() { - ''' - «instantiateCollectionAsNumbersVariable» - var numbersSet = numbers.asSet() - assert.equals([22,10,2], numbers.sortedBy({a,b=>a>b})) - assert.equals([22,10,2], numbersSet.sortedBy({a,b=>a>b})) - assert.equals([2,10,22], numbers.sortedBy({a,b=>aaa>b})) - assert.equals([5], #{5}.sortedBy({a,b=>a>b})) - assert.equals([], [].sortedBy({a,b=>a>b})) - - '''.test - } - - -} diff --git a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/DictionaryTestCase.xtend b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/DictionaryTestCase.xtend deleted file mode 100644 index daf9a1a1ad..0000000000 --- a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/DictionaryTestCase.xtend +++ /dev/null @@ -1,202 +0,0 @@ -package org.uqbar.project.wollok.tests.interpreter - -import org.junit.Test - -class DictionaryTestCase extends AbstractWollokInterpreterTestCase { - - @Test - def void testGetValue() { - ''' - const mapaTelefonos = new Dictionary() - mapaTelefonos.put("choli", "2142-5980") - mapaTelefonos.put("mario", "5302-6617") - assert.equals("2142-5980", mapaTelefonos.get("choli")) - '''.test - } - - @Test - def void testGetValueNotFound() { - ''' - const mapaTelefonos = new Dictionary() - mapaTelefonos.put("choli", "2142-5980") - mapaTelefonos.put("mario", "5302-6617") - assert.throwsException({ => mapaTelefonos.get("betty") }) - '''.test - } - - @Test - def void testGetOrElseForValueNotFound() { - ''' - const mapaTelefonos = new Dictionary() - mapaTelefonos.put("choli", "2142-5980") - mapaTelefonos.put("mario", "5302-6617") - var notFound = false - mapaTelefonos.getOrElse("betty", { => notFound = true } ) - assert.that(notFound) - '''.test - } - - @Test - def void testSize() { - ''' - const mapaTelefonos = new Dictionary() - mapaTelefonos.put("choli", "2142-5980") - mapaTelefonos.put("mario", "5302-6617") - assert.equals(2, mapaTelefonos.size()) - mapaTelefonos.put("rita", "3923-0029") - assert.equals(3, mapaTelefonos.size()) - '''.test - } - - @Test - def void testEmptyDictionaryIsEmpty() { - ''' - assert.that((new Dictionary()).isEmpty()) - '''.test - } - - @Test - def void testDictionaryWithElementsIsNotEmpty() { - ''' - const mapaTelefonos = new Dictionary() - mapaTelefonos.put("choli", "2142-5980") - mapaTelefonos.put("mario", "5302-6617") - assert.notThat(mapaTelefonos.isEmpty()) - '''.test - } - - @Test - def void testContainsKey() { - ''' - const mapaTelefonos = new Dictionary() - mapaTelefonos.put("choli", "2142-5980") - mapaTelefonos.put("mario", "5302-6617") - assert.that(mapaTelefonos.containsKey("choli")) - assert.notThat(mapaTelefonos.containsKey("cuca")) - '''.test - } - - @Test - def void testContainsValues() { - ''' - const mapaTelefonos = new Dictionary() - mapaTelefonos.put("choli", "2142-5980") - mapaTelefonos.put("mario", "5302-6617") - assert.that(mapaTelefonos.containsValue("2142-5980")) - assert.notThat(mapaTelefonos.containsValue("2142-5280")) - '''.test - } - - @Test - def void testRemove() { - ''' - const mapaTelefonos = new Dictionary() - mapaTelefonos.put("choli", "2142-5980") - mapaTelefonos.put("mario", "5302-6617") - assert.that(mapaTelefonos.containsKey("choli")) - mapaTelefonos.remove("choli") - assert.notThat(mapaTelefonos.containsKey("choli")) - '''.test - } - - @Test - def void testRemoveNonExistentKey() { - ''' - const mapaTelefonos = new Dictionary() - mapaTelefonos.put("choli", "2142-5980") - mapaTelefonos.put("mario", "5302-6617") - mapaTelefonos.remove("pepe") - assert.equals(2, mapaTelefonos.size()) - '''.test - } - - @Test - def void testKeys() { - ''' - const mapa = new Dictionary() - mapa.put(4, "2142-5980") - mapa.put(9, "5302-6617") - assert.that(mapa.keys().contains(4)) - assert.that(mapa.keys().contains(9)) - '''.test - } - - @Test - def void testValues() { - ''' - const mapa = new Dictionary() - mapa.put("2142-5980", 4) - mapa.put("5302-6617", 9) - assert.that(mapa.values().contains(4)) - assert.that(mapa.values().contains(9)) - '''.test - } - - @Test - def void testContainsForEach() { - ''' - const mapaTelefonos = new Dictionary() - mapaTelefonos.put("choli", "2142-5980") - mapaTelefonos.put("mario", "5302-6617") - var result = 0 - mapaTelefonos.forEach({ k, v => result += k.size() + v.size() }) - assert.equals(28, result) - '''.test - } - - @Test - def void testClearEmptiesADictionary() { - ''' - const mapaTelefonos = new Dictionary() - mapaTelefonos.put("choli", "2142-5980") - mapaTelefonos.clear() - assert.that(mapaTelefonos.isEmpty()) - '''.test - } - - @Test - def void testToString() { - ''' - const mapaTelefonos = new Dictionary() - assert.equals(mapaTelefonos.toString(), "a Dictionary []") - mapaTelefonos.put("choli", "2142-5980") - assert.equals(mapaTelefonos.toString(), "a Dictionary [\"choli\" -> \"2142-5980\"]") - mapaTelefonos.put(2, 33) - assert.equals(mapaTelefonos.toString(), "a Dictionary [2 -> 33, \"choli\" -> \"2142-5980\"]") - '''.test - } - - @Test - def void testPutNullKeyShouldThrowAnException() { - ''' - assert.throwsExceptionWithMessage("You cannot add an element with a null key in a Dictionary", { new Dictionary().put(null, 2184) }) - '''.test - } - - @Test - def void testPutNullValueShouldThrowAnException() { - ''' - assert.throwsExceptionWithMessage("You cannot add a null value in a Dictionary", { new Dictionary().put(2145, null) }) - '''.test - } - - @Test - def void addingSeveralSwallowsInAMap() { - ''' - class Golondrina { } - - program a { - var pepa = new Golondrina() - var s = new Dictionary() - s.put(pepa, 0) - - (1..100).forEach({i => s.put(new Golondrina(), i)}) // all objects are not == to pepa - - assert.notEquals(pepa, new Golondrina()) - assert.equals(101, s.size()) - assert.equals(0, s.get(pepa)) - } - '''.interpretPropagatingErrors - } - -} \ No newline at end of file diff --git a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/ListTestCase.xtend b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/ListTestCase.xtend deleted file mode 100644 index f8f2e1cd5e..0000000000 --- a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/ListTestCase.xtend +++ /dev/null @@ -1,243 +0,0 @@ -package org.uqbar.project.wollok.tests.interpreter - -import org.junit.Test - -/** - * @author jfernandes - */ -class ListTestCase extends CollectionTestCase { - - @Test - def void subList() { - ''' - «instantiateCollectionAsNumbersVariable» - assert.equals([22,2], numbers.subList(0,1)) - assert.equals([22,2,10], numbers.subList(0,2)) - assert.equals([2,10], numbers.subList(1,2)) - assert.equals([2], numbers.subList(1,1)) - assert.equals([], numbers.subList(5)) - assert.equals([], numbers.subList(3)) - assert.equals([], numbers.subList(5,6)) - assert.equals([], [].subList(1, 2)) - '''.test - } - - @Test - def void subListUnhappyPath() { - ''' - «instantiateCollectionAsNumbersVariable» - assert.equals([2,22], numbers.subList(1,0)) - assert.equals([22,2,10], numbers.subList(0,25)) - assert.equals([2,10], numbers.subList(1,2)) - assert.equals([2], numbers.subList(1,1)) - '''.test - } - - @Test - def void subListUsingNull() { - ''' - assert.throwsExceptionWithMessage("Operation subList doesn't support null parameters", { => [1, 2].subList(null, 1) }) - assert.throwsExceptionWithMessage("Operation subList doesn't support null parameters", { => [1, 2].subList(1, null) }) - '''.test - } - - @Test - def void takeUsingNull() { - ''' - assert.throwsExceptionWithMessage("Operation take doesn't support null parameters", { => [1, 2].take(null) }) - '''.test - } - - @Test - def void take() { - ''' - «instantiateCollectionAsNumbersVariable» - assert.equals([], numbers.take(-1)) - assert.equals([], numbers.take(0)) - assert.equals([22], numbers.take(1)) - assert.equals([22,2], numbers.take(2)) - assert.equals([22,2,10], numbers.take(3)) - assert.equals([22,2,10], numbers.take(4)) - assert.equals([22,2,10], numbers) - '''.test - } - - @Test - def void takeUnhappyPath() { - ''' - «instantiateCollectionAsNumbersVariable» - assert.equals([], [].take(-1)) - assert.equals([], [].take(0)) - assert.equals([], [].take(1)) - assert.equals([], [].take(2)) - '''.test - } - - @Test - def void drop() { - ''' - «instantiateCollectionAsNumbersVariable» - assert.equals([22,2,10], numbers.drop(-1)) - assert.equals([22,2,10], numbers.drop(0)) - assert.equals([2,10], numbers.drop(1)) - assert.equals([10], numbers.drop(2)) - assert.equals([], numbers.drop(3)) - assert.equals([], numbers.drop(4)) - assert.equals([22,2,10], numbers) - '''.test - } - - @Test - def void dropUnhappyPath() { - ''' - «instantiateCollectionAsNumbersVariable» - assert.equals([], [].drop(-1)) - assert.equals([], [].drop(0)) - assert.equals([], [].drop(1)) - assert.equals([], [].drop(2)) - '''.test - } - - @Test - def void reverse() { - ''' - «instantiateCollectionAsNumbersVariable» - assert.equals([10,2,22], numbers.reverse()) - assert.equals([], [].reverse()) - assert.equals([2], [2].reverse()) - '''.test - } - - @Test - def void printingDuplicatedElements(){ - ''' - const l1 = [[3,5,2], [4,2,6]].flatten() - assert.equals("[3, 5, 2, 4, 2, 6]", l1.toString()) - - - const l2 = [1,2,3].flatMap({x => [x, x * 2, x * 3]}) - assert.equals("[1, 2, 3, 2, 4, 6, 3, 6, 9]", l2.toString()) - - const l3 = [1,1,1] - assert.equals("[1, 1, 1]", l3.toString()) - '''.test - } - - @Test - def void equalityCaseTrue() { - ''' - assert.equals(['Hello'], ['Hello']) - assert.equals([4, 5, 9], [4, 5, 9]) - assert.equals([true], [true]) - assert.equals([], []) - '''.test - } - - @Test - def void equalityCaseFalse() { - ''' - assert.notEquals(['Hello'], ['Hellou']) - assert.notEquals([4, 5, 9], [5, 4, 9]) - assert.notEquals([4, 5, 9], [5, 4]) - assert.notThat([4, 5, 9].equals([5, 4])) - assert.notThat([4, 5, 9].equals([5, 4, 9])) - assert.notEquals([4, 5, 9], #{4, 5, 9}) - assert.notThat([5, 4].equals([4, 5, 9])) - assert.notThat([5, 4].equals([5, 4, 9])) - assert.notThat([5, 4].equals([])) - assert.notThat([].equals([5, 4])) - '''.test - } - - @Test - def void withoutDuplicates() { - ''' - assert.equals([1, 3, 1, 5, 1, 3, 2, 5].withoutDuplicates(), [1, 3, 5, 2]) - assert.equals([1, 3, 5, 2].withoutDuplicates(), [1, 3, 5, 2]) - '''.test - } - - @Test - def void sortByUsingNull() { - ''' - assert.throwsExceptionWithMessage("Operation sortBy doesn't support null parameters", { => [1, 2].sortBy(null) }) - '''.test - } - - @Test - def void sortBy() { - ''' - «instantiateCollectionAsNumbersVariable» - numbers.sortBy({a,b=>a>b}) - assert.equals([22,10,2], numbers) - numbers.sortBy({a,b=>a [1, 2].get(null) }) - '''.test - } - - @Test - def void getHappyPath() { - ''' - «instantiateCollectionAsNumbersVariable» - assert.equals(22, numbers.get(0)) - '''.test - } - - @Test - def void getUnhappyPath() { - ''' - «instantiateCollectionAsNumbersVariable» - assert.throwsExceptionWithMessage("-1 must be a positive integer value", { numbers.get(-1) }) - '''.test - } - - // #1305 vs. #1401 - Infinite loop forces this test to change - @Test - def void elementsToString() { - ''' - object a { - override method printString() = "es un a" - } - - class B { - override method printString() = "cierto que era un b!" - } - - program c { - /* - assert.throwsExceptionWithMessage( - "Expected [[es un a]] but found [[cierto que era un b!]]", - { assert.equals([ a ], [ new B() ]) } - ) - */ - assert.throwsExceptionWithMessage( - "Expected [[a[]]] but found [[a B[]]]", - { assert.equals([ a ], [ new B() ]) } - ) - } - '''.interpretPropagatingErrors - } - - @Test - def void elementsToStringForLongLists() { - ''' - const unList = [] - (1..70).forEach { i => unList.add(i) } - assert.equals("[...70 elements]", unList.toString()) - '''.test - } - - @Test - def void maxSentToEmptyList() { - ''' - assert.throwsExceptionWithMessage("Message max sent to an empty collection. It must have at least one element.", { [].max() }) - '''.test - } -} \ No newline at end of file diff --git a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/SetTestCase.xtend b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/SetTestCase.xtend deleted file mode 100644 index b994f254eb..0000000000 --- a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/SetTestCase.xtend +++ /dev/null @@ -1,340 +0,0 @@ -package org.uqbar.project.wollok.tests.interpreter - -import org.junit.Test - -/** - * @author matifreyre - * @author nicoviotti - * @author fdodino - * - */ -class SetTestCase extends CollectionTestCase { - - @Test - def void aSetWithObjectsOfSameClassAreNotAddedIfEqualEqualSetToTrue() { - ''' - class C { - override method ==(other) = true - } - - test "issue 1771" { - const aSet = #{new C(), new C()} - assert.equals(1, aSet.size()) - } - '''.interpretPropagatingErrors - } - - @Test - def void aSetWithObjectsOfSameClassAreNotAddedIfEqualsSetToTrue() { - ''' - class C { - override method equals(other) = true - } - - test "issue 1771" { - const aSet = #{new C(), new C()} - assert.equals(1, aSet.size()) - } - '''.interpretPropagatingErrors - } - - @Test - def void aSetWithObjectsInDifferentHierarchyAreNotAddedIfEqualsSetToTrue() { - ''' - class Animal { - override method equals(other) = true - } - - class Perro inherits Animal { - } - - class Gato inherits Animal { - - } - - test "issue 1771" { - const aSet = #{new Perro(), new Perro(), new Gato()} - assert.equals(1, aSet.size()) - } - '''.interpretPropagatingErrors - } - - @Test - def void aSetWithObjectsInDifferentHierarchyAreNotAddedIfEqualEqualSetToTrue() { - ''' - class Animal { - override method ==(other) = true - } - - class Perro inherits Animal { - } - - class Gato inherits Animal { - - } - - test "issue 1771" { - const aSet = #{new Perro(), new Perro(), new Gato()} - assert.equals(1, aSet.size()) - } - '''.interpretPropagatingErrors - } - - @Test - def void unionWithEmptySet() { - ''' - const aSet = #{1, 2, 3} - - assert.equals(aSet, aSet.union(#{})) - assert.equals(aSet, #{}.union(aSet)) - '''.test - } - - @Test - def void unionWithNonEmptySets() { - ''' - const aSet = #{1, 2, 3} - const anotherSet = #{3, 4, 5} - const unionSet = #{1, 2, 3, 4, 5} - - assert.equals(aSet, aSet.union(aSet)) - assert.equals(unionSet, aSet.union(anotherSet)) - assert.equals(unionSet, anotherSet.union(aSet)) - '''.test - } - - @Test - def void intersectionWithEmptySet() { - ''' - const aSet = #{1, 2, 3} - - assert.equals(#{}, aSet.intersection(#{})) - assert.equals(#{}, #{}.intersection(aSet)) - '''.test - } - - @Test - def void intersectionWithNonEmptySets() { - ''' - const aSet = #{1, 2, 3} - const anotherSet = #{3, 4, 5} - const intersectionSet = #{3} - - assert.equals(aSet, aSet.intersection(aSet)) - assert.equals(intersectionSet, aSet.intersection(anotherSet)) - assert.equals(intersectionSet, anotherSet.intersection(aSet)) - '''.test - } - - @Test - def void differenceWithEmptySet() { - ''' - const aSet = #{1, 2, 3} - - assert.equals(aSet, aSet.difference(#{})) - assert.equals(#{}, #{}.difference(aSet)) - '''.test - } - - @Test - def void differenceWithNonEmptySets() { - ''' - const aSet = #{1, 2, 3} - const anotherSet = #{3, 4, 5} - - assert.equals(#{}, aSet.difference(aSet)) - assert.equals(#{1, 2}, aSet.difference(anotherSet)) - assert.equals(#{4, 5}, anotherSet.difference(aSet)) - '''.test - } - - @Test - def void equalityCaseTrue() { - ''' - assert.equals(#{'Hello'}, #{'Hello'}) - assert.equals(#{5, 4, 9}, #{4, 5, 9}) - assert.equals(#{true}, #{true}) - assert.equals(#{}, #{}) - '''.test - } - - @Test - def void equalitySpecialCases() { - ''' - assert.notEquals(#{3, 4}, #{3}) - assert.notThat(#{3, 4}.equals(#{3})) - assert.notThat(#{3, 4}.equals(#{3, 8})) - assert.notThat(#{3, 4}.equals(#{3})) - assert.notThat(#{3}.equals(#{3, 4})) - assert.notThat(#{2, 3}.equals(#{3, 4})) - assert.notThat(#{2, 3, 4}.equals(#{3, 4})) - assert.notThat(#{3, 4}.equals(#{3.01, 4})) - assert.that(#{3, 4}.equals(#{2.00 + 1, 4})) - assert.notThat(#{}.equals(#{3})) - assert.notThat(#{5}.equals(#{3})) - assert.notThat(#{5}.equals(#{})) - '''.test - } - @Test - def void equalityCaseFalse() { - ''' - assert.notEquals(#{'Hello'}, #{'Hellou'}) - assert.notEquals(#{5, 4, 9}, #{4, 5, 3}) - assert.notEquals(#{4, 5, 9}, [4, 5, 9]) - '''.test - } - - @Test - def void elementsAreUnique() { - ''' - assert.equals(2, #{"melon", "tomate", "melon"}.size()) - assert.equals(2, #{5, 7, 7, 5, 5, 5, 7, 7, 5, 5, 7}.size()) - '''.test - } - - @Test - def void elementsAreUniqueWithCommonRepresentations() { - ''' - assert.equals(4, #{"4", 4.01, 4, "Cuatro"}.size()) - '''.test - } - - @Test - def void elementsAreUniqueForClasses() { - ''' - class Alumno { - var nombre - constructor(_nombre) { nombre = _nombre } - } - - program a { - assert.equals(3, #{new Alumno("juan"), new Alumno("manuel"), new Alumno("juan")}.size()) - }'''.interpretPropagatingErrors - } - - @Test - def void elementsAreUniqueForClassesAndObjects() { - ''' - class Alumno { - var nombre - constructor(_nombre) { nombre = _nombre } - } - - object manuel { - var nombre = "ElManu" - } - - program a { - var juancete = new Alumno("juan") - assert.equals(2, #{juancete, manuel, juancete, manuel, manuel}.size()) - }'''.interpretPropagatingErrors - } - - @Test - def void anyOneOnSetThrowsExceptionWhenEmpty() { - ''' - assert.equals(1, #{1}.anyOne()) - assert.throwsExceptionWithMessage( - "Illegal operation 'anyOne' on empty collection", - { #{}.anyOne() }) - '''.test - } - - // #1305 vs. #1401 - Infinite loop forces this test to change - @Test - def void elementsToString() { - ''' - object a { - override method printString() = "es un a" - } - - class B { - override method printString() = "cierto que era un b!" - } - - program c { - /* - assert.throwsExceptionWithMessage( - "Expected [#{es un a}] but found [#{cierto que era un b!}]", - { assert.equals(#{a}, #{new B()}) } - ) - */ - assert.throwsExceptionWithMessage( - "Expected [#{a[]}] but found [#{a B[]}]", - { assert.equals(#{a}, #{new B()}) } - ) - } - '''.interpretPropagatingErrors - } - - @Test - def void elementsToStringForLongSets() { - ''' - const unSet = #{} - (1..70).forEach { i => unSet.add(i) } - assert.equals("#{...70 elements}", unSet.toString()) - '''.test - } - - @Test - def void maxSentToEmptySet() { - ''' - assert.throwsExceptionWithMessage("Message max sent to an empty collection. It must have at least one element.", { #{}.max() }) - '''.test - } - - @Test - def void equalsForObjectsOverridingEquals() { - ''' - class AveLoca { - var property energia = 0 - var property nombre = "pepita" - - method volar() { - energia -= 50 - } - - method comer(gramos) { - energia += gramos * 2 - } - - override method ==(otraAve) { - return energia == otraAve.energia() - } - - } - - test "two sets are equals because of the definition of their objects" { - const pepita = new AveLoca() - const unSet = #{ pepita } - const otroSet = #{ new AveLoca() } - assert.equals(unSet, otroSet) - } - '''.interpretPropagatingErrors - } - - @Test - def void equalsForObjectsNotOverridingEquals() { - ''' - class AveLoca { - var property energia = 0 - var property nombre = "pepita" - - method volar() { - energia -= 50 - } - - method comer(gramos) { - energia += gramos * 2 - } - } - - test "two sets are different because of the definition of their objects" { - const pepita = new AveLoca() - const unSet = #{ pepita } - const otroSet = #{ new AveLoca() } - assert.notThat(unSet == otroSet) - } - '''.interpretPropagatingErrors - } -} \ No newline at end of file diff --git a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/classes/InstanceVariableInitializationTest.xtend b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/classes/InstanceVariableInitializationTest.xtend deleted file mode 100644 index 3acc905d31..0000000000 --- a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/classes/InstanceVariableInitializationTest.xtend +++ /dev/null @@ -1,72 +0,0 @@ -package org.uqbar.project.wollok.tests.interpreter.classes - -import org.uqbar.project.wollok.tests.interpreter.AbstractWollokInterpreterTestCase -import org.junit.Test - -/** - * Tests inst var initializations with different values and scenarios - * - * @author jfernandes - */ -class InstanceVariableInitializationTest extends AbstractWollokInterpreterTestCase { - - @Test - def void testNumberInitialization() { - ''' - class A { - var i = 10 - var j = 0.10 - - method getI() = i - method getJ() = j - } - - program p { - const a = new A() - assert.equals(10, a.getI()) - assert.equals(0.10, a.getJ()) - } - '''.interpretPropagatingErrors - } - - @Test - def void testCrossReferenceInitialization() { - ''' - object abc { - var x = 20 - var y = x * 2 - - method getY() { - return y - } - } - program p { - assert.equals(40, abc.getY()) - } - '''.interpretPropagatingErrors - } - - @Test - def void assignmentToWKODeclared() { - ''' - object before { method get() = "before" } - - class A { - const b = before - const a = after - - method getB() = b - method getA() = a - } - - object after { method get() = "before" } - - program p { - const a = new A() - assert.equals(before, a.getB()) - assert.equals(after, a.getA()) - } - '''.interpretPropagatingErrors - } - -} \ No newline at end of file diff --git a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/classes/MethodTest.xtend b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/classes/MethodTest.xtend deleted file mode 100644 index ca7dc9b7cd..0000000000 --- a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/classes/MethodTest.xtend +++ /dev/null @@ -1,93 +0,0 @@ -package org.uqbar.project.wollok.tests.interpreter.classes - -import org.junit.Test -import org.uqbar.project.wollok.tests.interpreter.AbstractWollokInterpreterTestCase - -/** - * - * @author jfernandes, tesonep - */ -class MethodTest extends AbstractWollokInterpreterTestCase { - - @Test - def void shortSyntaxForMethodsReturningAValue() { ''' - class Golondrina { - var energia = 100 - - method energia() = energia - method capacidadDeVuelo() = 10 - } - program p { - const pepona = new Golondrina() - assert.equals(pepona.energia(), 100) - assert.equals(pepona.capacidadDeVuelo(), 10) - }'''.interpretPropagatingErrors - } - - @Test - def void varArgsInMethod() { ''' - class Sample { - method preffix(preffix, numbers...) { - if (numbers.size() > 0) - return numbers.map{n=> preffix + n} - else - return [] - } - } - test "Var args method must automatically box params as a list" { - const p = new Sample() - assert.equals("#1, #2, #3, #4", p.preffix("#", 1, 2, 3, 4).join(", ")) - } - test "Var args in method with just 1" { - const p = new Sample() - assert.equals("#1", p.preffix("#", 1).join(", ")) - } - - test "Var args in method without elements" { - const p = new Sample() - assert.equals("", p.preffix("#").join(", ")) - } - '''.interpretPropagatingErrors - } - - @Test - def void varArgsInConstructor() { ''' - class Sample { - var result - constructor(preffix, numbers...) { - result = if (numbers.size() > 0) numbers.map{n=> preffix + n} else [] - } - method getResult() = result - } - test "Var arg in constructor with 4 elements" { - const p = new Sample("#", 1, 2, 3, 4) - assert.equals("#1, #2, #3, #4", p.getResult().join(", ")) - } - test "Var arg in constructor with just 1 element" { - const p = new Sample("#", 1) - assert.equals("#1", p.getResult().join(", ")) - } - test "Var args in method without elements" { - const p = new Sample("#") - assert.equals("", p.getResult().join(", ")) - } - '''.interpretPropagatingErrors - } - - @Test - def void initOfVariables(){ - ''' - class Subject{ - var x = 4 - var y = x * 2 - - method getY() = y - } - - test "Init of variables" { - var obj = new Subject() - assert.equals(8, obj.getY()) - } - '''.interpretPropagatingErrors - } -} diff --git a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/classes/ObjectTest.xtend b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/classes/ObjectTest.xtend deleted file mode 100644 index a4b5efdf9a..0000000000 --- a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/classes/ObjectTest.xtend +++ /dev/null @@ -1,23 +0,0 @@ -package org.uqbar.project.wollok.tests.interpreter.classes - -import org.junit.Test -import org.uqbar.project.wollok.tests.interpreter.AbstractWollokInterpreterTestCase - -/** - * Tests automatic inheritance of wollok Object class - * - * @author jfernandes - */ -class ObjectTest extends AbstractWollokInterpreterTestCase { - - @Test - def void testSimpleMethodInheritedFromObject() { - ''' - class MyClass { - } - program p { - const myObject = new MyClass() - assert.that(myObject.identity() != null) - }'''.interpretPropagatingErrors - } -} \ No newline at end of file diff --git a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/sdk/CollectionTest.xtend b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/sdk/CollectionTest.xtend deleted file mode 100644 index 3b377d3332..0000000000 --- a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/sdk/CollectionTest.xtend +++ /dev/null @@ -1,152 +0,0 @@ -package org.uqbar.project.wollok.tests.sdk - -import org.junit.Test -import org.uqbar.project.wollok.tests.interpreter.AbstractWollokInterpreterTestCase - -/** - * - * @author tesonep - * @author jfernandes - */ -class CollectionTest extends AbstractWollokInterpreterTestCase { - - @Test - def void testCollectionAsInstanceVariable() { #[''' - object pajarera{ - const pajaros = [] - method agregar(unPajaro){ - pajaros.add(unPajaro) - } - method quitar(unPajaro){ - pajaros.remove(unPajaro) - } - method cantidad(){ - return pajaros.size() - } - } - - object pepita{ - - } - - program p { - pajarera.agregar(pepita) - pajarera.quitar(pepita) - assert.that(pajarera.cantidad() == 0) - }'''].interpretPropagatingErrors - } - - @Test - def void test_issue_40() { - ''' - object pajarera { - var energiaMenor = 100 - var pajaros = [pepita, pepe] - method menorValor(){ - pajaros.forEach{a => a.sosMenor(energiaMenor)} - return energiaMenor - } - - method setEnergiaMenor(valor){ - energiaMenor = valor - } - } - - object pepe { - method sosMenor(energiaMenor){ - pajarera.setEnergiaMenor(10) - } - } - - object pepita { - method sosMenor(energiaMenor){ - pajarera.setEnergiaMenor(25) - } - } - program p { - const menor = pajarera.menorValor() - assert.equals(10, menor) - } - '''.interpretPropagatingErrors - } - - @Test - def void testAddAll() { - ''' - program p { - const unos = [1,2,3,4] - const otros = [5,6,7,8] - - const todos = [] - todos.addAll(unos) - todos.addAll(otros) - assert.equals(8, todos.size()) - }'''.interpretPropagatingErrors - } - - @Test - def void testFlatMap() { - ''' - program p { - assert.equals([1,2,3,4], [[1,2], [3,4]].flatten()) - assert.equals([1,2,3,4], [[1,2], [], [3,4]].flatten()) - assert.equals([], [].flatten()) - assert.equals([], [[]].flatten()) - }'''.interpretPropagatingErrors - } - - @Test - def void copyWithoutDontMutateTheCollection(){ - ''' - const unList = [1,2,3,4,5] - const newList = unList.copyWithout(3) - assert.equals(unList, [1,2,3,4,5]) - '''.test - } - - @Test - def void whenPassANumberAtCopyWithoutMethodReturnANewCollectionWithoutThisNumber() { - ''' - const unList = [1,2,3,4,5] - const newList = unList.copyWithout(3) - assert.equals(newList, [1,2,4,5]) - '''.test - } - - @Test - def void whenPassAStringAtCopyWithoutMethodReturnANewCollectionWithoutThisString() { - ''' - const unList = ["hola","como","estas"] - const newList = unList.copyWithout("como") - assert.equals(newList, ["hola","estas"]) - '''.test - } - - @Test - def void copyWithDontMutateTheCollection(){ - ''' - const unList = [1,2,3,4,5] - const newList = unList.copyWith(3) - assert.equals(unList, [1,2,3,4,5]) - '''.test - } - - @Test - def void whenPassANumberAtCopyWithMethodReturnANewCollectionWithThisNumber() { - ''' - const unList = [1,2,3,4,5] - const newList = unList.copyWith(6) - assert.equals(newList, [1,2,3,4,5,6]) - '''.test - } - - @Test - def void whenPassAStringAtCopyWithMethodReturnANewCollectionWithThisString() { - ''' - const unList = ["hola","como"] - const newList = unList.copyWith("estas") - assert.equals(newList, ["hola","como","estas"]) - '''.test - } - -} diff --git a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/sdk/ListTest.xtend b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/sdk/ListTest.xtend deleted file mode 100644 index 0abfa54798..0000000000 --- a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/sdk/ListTest.xtend +++ /dev/null @@ -1,447 +0,0 @@ -package org.uqbar.project.wollok.tests.sdk - -import org.junit.Test -import org.uqbar.project.wollok.tests.interpreter.ListTestCase - -/** - * Tests the wollok List class included in the Wollok SDK. - * - * @author jfernandes - * @author PalumboN - * @author tesonep - */ -class ListTest extends ListTestCase { - - override instantiateCollectionAsNumbersVariable() { - "const numbers = new List() - numbers.add(22) - numbers.add(2) - numbers.add(10)" - } - - override instantiateStrings() { - "const strings = new List(); " + System.lineSeparator + " ['hello', 'hola', 'bonjour', 'ciao', 'hi'].forEach{e=> strings.add(e) }" - } - - @Test - def void toStringOnEmptyCollection() { - ''' - const numbers = new List() - assert.equals("[]", numbers.toString()) - '''.test - } - - @Test - def void identityOnMap() { - ''' - «instantiateCollectionAsNumbersVariable» - const strings = numbers.map{e=> e.toString()} - - assert.notEquals(numbers.identity(), strings.identity()) - - assert.that(strings.contains("22")) - assert.that(strings.contains("2")) - '''.test - } - - @Test - def void testContainsWithComplexObjects() { - ''' - object o1 {} - object o2 {} - - program p { - const list = [o1, o2] - - assert.that(list.contains(o1)) - assert.that(list.contains(o2)) - }'''.interpretPropagatingErrors - } - - @Test - def void testAsListConversion() { - ''' - const list = [1,2,3] - assert.equals([1,2,3], list.asList()) - '''.test - } - - @Test - def void testAsSetConversion() { - ''' - const set = #{} - set.add(1) - set.add(2) - set.add(3) - assert.equals(set, set.asSet()) - '''.test - } - - @Test - def void testListOfNumberAsSetConversion() { - ''' - assert.equals(3, [1, 2/2, 3, 4, 6/2].asSet().size()) - '''.test - } - - @Test - def void testListOfStringAsSetConversion() { - ''' - assert.equals(3, ["hola", "chau", "ho" + "la", "c" + "hau", "bye"].asSet().size()) - '''.test - } - - @Test - def void testListOfBooleanAsSetConversion() { - ''' - assert.equals(2, [true, 1==2, 2==2, 3==4 ].asSet().size()) - '''.test - } - - @Test - def void testListOfDateAsSetConversion() { - ''' - assert.equals(2, [new Date(day=1, month=4, year=2018),new Date(day=12, month=7, year=2020), - new Date(day=1, month=4, year=2018)].asSet().size()) - '''.test - } - - @Test - def void testListOfListAsSetConversion() { - ''' - var list = [[1,2,3],[5,6],[7,8],[1,2,3],[5,6]] - assert.equals(3, list.asSet().size()) - '''.test - } - - @Test - def void testListOfEmptyListAsSetConversion() { - ''' - assert.equals(1, [[], []].asSet().size()) - '''.test - } - - @Test - def void testListOfSetAsSetConversion() { - ''' - var list = [#{1,2,3},#{5,6},#{7,8},#{1,2,3},#{5,6}] - assert.equals(3, list.asSet().size()) - '''.test - } - - @Test - def void testListOfEmptySetAsSetConversion() { - ''' - assert.equals(1, [#{}, #{}].asSet().size()) - '''.test - } - - @Test - def void testListOfEmptyDictionaryAsSetConversion() { - ''' - assert.equals(1, [new Dictionary(), new Dictionary()].asSet().size()) - '''.test - } - - @Test - def void testListOfNonEmptyDictionaryAsSetConversion() { - ''' - const firstDictionary = new Dictionary() - firstDictionary.put(1, "hola") - firstDictionary.put(2, "chau") - const secondDictionary = new Dictionary() - secondDictionary.put(1, "hola") - secondDictionary.put(2, "chau") - assert.equals(1, [firstDictionary, secondDictionary].asSet().size()) - '''.test - } - - @Test - def void testListOfPairAsSetConversion() { - ''' - assert.equals(2, [new Pair(1,2), new Pair(4,5), new Pair(1,2)].asSet().size()) - '''.test - } - - @Test - def void testListOfPositionAsSetConversion() { - ''' - assert.equals(1, [new Position() ,new Position()].asSet().size()) - '''.test - } - - @Test - def void testListOfUserDefinedClassAsSetConversionRedefiningEqualEqual() { - ''' - class Animal { - override method ==(otroAnimal) = self.nombre() == otroAnimal.nombre() - method nombre() - } - - class Perro inherits Animal { - override method nombre() = "Firulais" - } - - class Gato inherits Animal { - override method nombre() = "Garfield" - } - - test "issue 1771" { - assert.equals(2, [new Perro(), new Gato(), new Perro(), new Gato()].asSet().size()) - } - '''.interpretPropagatingErrors - } - - @Test - def void testListOfUserDefinedClassAsSetConversionRedefiningEquals() { - ''' - class Animal { - override method ==(otroAnimal) = self.nombre() == otroAnimal.nombre() - method nombre() - } - - class Perro inherits Animal { - override method nombre() = "Firulais" - } - - class Gato inherits Animal { - override method nombre() = "Garfield" - } - - test "issue 1771" { - assert.equals(2, [new Perro(), new Gato(), new Perro(), new Gato()].asSet().size()) - } - '''.interpretPropagatingErrors - } - - @Test - def void testListOfNumberWithoutDuplicates() { - ''' - const list = [1, 3, 1, 5, 1, 3, 2, 5] - const result = [1, 3, 5, 2] - const withoutDuplicates = list.withoutDuplicates() - assert.equals(4, withoutDuplicates.size()) - (0..result.size()-1).forEach{ i=> assert.that(withoutDuplicates.get(i).equals(result.get(i))) } - '''.test - } - - @Test - def void testListOfStringWithoutDuplicates() { - ''' - const list = ["amigo", "carpeta", "beca", "amigo", "carpeta"] - const result = ["amigo", "carpeta", "beca"] - const withoutDuplicates = list.withoutDuplicates() - assert.equals(3, withoutDuplicates.size()) - (0..result.size()-1).forEach{ i => assert.that(withoutDuplicates.get(i).equals(result.get(i))) } - '''.test - } - - @Test - def void testListOfDateWithoutDuplicates() { - ''' - const list = [new Date(day=22, month=9, year=2020), new Date(day=1, month=4, year=2018), new Date(day=22, month=9, year=2020)] - const result = [new Date(day=22, month=9, year=2020), new Date(day=1, month=4, year=2018)] - const withoutDuplicates = list.withoutDuplicates() - assert.equals(2, withoutDuplicates.size()) - (0..result.size()-1).forEach{ i => assert.that(withoutDuplicates.get(i).equals(result.get(i))) } - '''.test - } - - @Test - def void testListOfBooleanWithoutDuplicates() { - ''' - const result = [true, false] - const withoutDuplicates = [true, false, !false].withoutDuplicates() - assert.equals(2, withoutDuplicates.size()) - (0..result.size()-1).forEach{ i => assert.that(withoutDuplicates.get(i).equals(result.get(i))) } - '''.test - } - - @Test - def void testListOfListWithoutDuplicates() { - ''' - const lista = new List() - lista.addAll([1,2,3]) - const list = [[6,7,8,9,22,12], [1,2,3], [1,2,3,4,5], [1,2,3], [6,7,8,9,22,12]] - const result = [[6,7,8,9,22,12], [1,2,3], [1,2,3,4,5]] - const withoutDuplicates = list.withoutDuplicates() - assert.equals(3, withoutDuplicates.size()) - (0..result.size()-1).forEach{ i => assert.that(withoutDuplicates.get(i).equals(result.get(i))) } - '''.test - } - - @Test - def void testListOfEmptyListWithoutDuplicates() { - ''' - const withoutDuplicates = [[],[]].withoutDuplicates() - assert.equals(1, withoutDuplicates.size()) - assert.equals([[]], withoutDuplicates) - '''.test - } - - @Test - def void testListOfSetWithoutDuplicates() { - ''' - const set = #{1,2,3} - const result = [#{1,44,55,33,27,12}, set, #{1,2,3,4,5,6}] - const list = [#{1,44,55,33,27,12}, set, #{1,2,3,4,5,6}, #{1,2,3}, #{1,2,3,4,5,6}, #{1,44,55,33,27,12}] - const withoutDuplicates = list.withoutDuplicates() - assert.equals(3, withoutDuplicates.size()) - (0..result.size()-1).forEach{ i => assert.that(withoutDuplicates.get(i).equals(result.get(i))) } - '''.test - } - - @Test - def void testListOfEmptySetWithoutDuplicates() { - ''' - const withoutDuplicates = [#{}, #{}].withoutDuplicates() - assert.equals(1, withoutDuplicates.size()) - assert.equals([#{}], withoutDuplicates) - '''.test - } - - @Test - def void testListOfDictionaryWithoutDuplicates() { - ''' - const dictionary = new Dictionary() - dictionary.put(1, "hola") - const result = [dictionary, new Dictionary()] - const withoutDuplicates = [dictionary, new Dictionary(), dictionary, new Dictionary()].withoutDuplicates() - assert.equals(2, withoutDuplicates.size()) - (0..result.size()-1).forEach{ i => assert.that(withoutDuplicates.get(i).equals(result.get(i))) } - '''.test - } - - @Test - def void testListOfPairWithoutDuplicates() { - ''' - const result = [new Pair(1,2), new Pair(5,6)] - const withoutDuplicates = [new Pair(1,2), new Pair(5,6), new Pair(1,2), new Pair(5,6)].withoutDuplicates() - assert.equals(2, withoutDuplicates.size()) - (0..result.size()-1).forEach{ i => assert.that(withoutDuplicates.get(i).equals(result.get(i))) } - '''.test - } - - @Test - def void testListOfPositionWithoutDuplicates() { - ''' - var position = new Position() - position = position.up(2) - const result = [position, new Position()] - const withoutDuplicates = [position, new Position(), position, new Position()].withoutDuplicates() - assert.equals(2, withoutDuplicates.size()) - (0..result.size()-1).forEach{ i => assert.that(withoutDuplicates.get(i).equals(result.get(i))) } - '''.test - } - - @Test - def void testListOfUserDefinedClassWithoutDuplicatesRedefiningEqualEqual() { - ''' - class Animal { - override method ==(otroAnimal) = self.nombre() == otroAnimal.nombre() - method nombre() - } - - class Perro inherits Animal { - override method nombre() = "Firulais" - } - - class Gato inherits Animal { - override method nombre() = "Garfield" - } - - test "issue 1771" { - const list = [new Perro(), new Gato(), new Perro(), new Gato()] - const result = [new Perro(), new Gato()] - const withoutDuplicates = list.withoutDuplicates() - assert.equals(2, withoutDuplicates.size()) - (0..result.size()-1).forEach{ i => assert.that(withoutDuplicates.get(i).equals(result.get(i))) } - } - '''.interpretPropagatingErrors - } - - @Test - def void testListOfUserDefinedClassWithoutDuplicatesRedefiningEquals() { - ''' - class Animal { - override method equals(otroAnimal) = self.nombre() == otroAnimal.nombre() - method nombre() - } - - class Perro inherits Animal { - override method nombre() = "Firulais" - } - - class Gato inherits Animal { - override method nombre() = "Garfield" - } - - test "issue 1771" { - const list = [new Perro(), new Gato(), new Perro(), new Gato()] - const result = [new Perro(), new Gato()] - const withoutDuplicates = list.withoutDuplicates() - assert.equals(2, withoutDuplicates.size()) - (0..result.size()-1).forEach{ i => assert.that(withoutDuplicates.get(i).equals(result.get(i))) } - } - '''.interpretPropagatingErrors - } - - @Test - def void testFirstAndHead() { - ''' - const list = [1,2,3] - assert.equals(1, list.first()) - assert.equals(1, list.head()) - '''.test - } - - @Test - def void testSortBy() { - ''' - var list = [1,2,3] - list.sortBy({x,y => x > y}) - assert.equals([3,2,1], list) - list.sortBy({x,y => x < y}) - assert.equals([1,2,3], list) - '''.test - } - - @Test - def void testSortedBy() { - ''' - const list = [1,2,3] - assert.equals([3,2,1], list.sortedBy({x,y => x > y})) - assert.notThat(list === list.sortedBy({x,y => x < y})) - '''.test - } - - - @Test - def void testEquals() { - ''' - assert.equals([], []) - assert.equals([1,2,1], [1,2,1]) - '''.test - } - - @Test - def void testNotEquals() { - ''' - assert.notEquals([], [1]) - assert.notEquals([1], []) - assert.notEquals([1,2], [1]) - assert.notEquals([1,2], [2,1]) - assert.notEquals([1,3], [1,2]) - '''.test - } - - @Test - def void testEqualityWithOtherObjects(){ - ''' - assert.notEquals(2, []) - assert.notEquals(2, [2]) - assert.notEquals(2, [2,3,4]) - assert.notEquals(console, []) - '''.test - } -} diff --git a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/sdk/SetTest.xtend b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/sdk/SetTest.xtend deleted file mode 100644 index d18f708420..0000000000 --- a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/sdk/SetTest.xtend +++ /dev/null @@ -1,346 +0,0 @@ -package org.uqbar.project.wollok.tests.sdk - -import org.junit.Test -import org.uqbar.project.wollok.tests.interpreter.CollectionTestCase - -/** - * @author jfernandes - * @author palumboN - * @author tesonep - */ -// the inheritance needs to be reviewed if we add list specific tests it won't work here -class SetTest extends CollectionTestCase { - - override instantiateCollectionAsNumbersVariable() { - "const numbers = #{22, 2, 10}" - } - - override instantiateCollectionWithA2() { - "const collectionWithA2 = #{2}" - } - - override instantiateEmptyCollection() { - "const emptyCollection = #{}" - } - - @Test - def void testSizeWithDuplicates() { - ''' - const numbers = #{ 23, 2, 1, 1, 1 } - assert.equals(3, numbers.size()) - '''.test - } - - @Test - def void testSizeAddingDuplicates() { - ''' - const numbers = #{ 23, 2, 1, 1, 1 } - numbers.add(1) - numbers.add(1) - assert.equals(3, numbers.size()) - '''.test - } - - @Test - def void testSizeAddingDuplicatesWithAddAll() { - ''' - const numbers = #{ 23, 2, 1, 1, 1 } - numbers.add(#{1, 1, 1, 1, 4}) - assert.equals(4, numbers.size()) - '''.test - } - - @Test - override def void testToString() { - ''' - const a = #{23, 2, 2} - const s = a.toString() - assert.that("#{2, 23}" == s or "#{23, 2}" == s) - '''.test - } - - override testToStringWithObjectRedefiningToStringInWollok() { - } - - @Test - def void testFlatMap() { - ''' - assert.equals(#{1,2,3,4}, #{#{1,2}, #{1,3,4}}.flatten()) - assert.equals(#{1,2, 3}, #{#{1,2}, #{}, #{1,2, 3}}.flatten()) - assert.equals(#{}, #{}.flatten()) - assert.equals(#{}, #{#{}}.flatten()) - '''.test - } - - @Test - def void testConversions() { - ''' - const set= #{1,2,3} - assert.equals(#{1,2,3}, set.asSet()) - const list = set.asList() - assert.equals(3, list.size()) - [1,2,3].forEach{i=>assert.that(list.contains(i))} - '''.test - } - - @Test - def void testSetOfNumberSize() { - ''' - const set = new Set() - const a = 2 - const b = 1 + 1 - const c = 3 - set.add(a) - set.add(b) - set.add(c) - assert.equals(2, set.size()) - assert.equals(set, #{a,c}) - assert.equals(#{a,c}, #{b,c}) - '''.test - } - - @Test - def void testSetOfStringSize() { - ''' - const set = new Set() - const a = "hola" - const b = "ho" + "la" - const c = "chau" - set.add(a) - set.add(b) - set.add(c) - assert.equals(2, set.size()) - assert.equals(set, #{a,c}) - assert.equals(#{a,c}, #{b,c}) - '''.test - } - - @Test - def void testSetOfBooleanSize() { - ''' - const set = new Set() - const a = true - const b = !false - const c = false - set.add(a) - set.add(b) - set.add(c) - assert.equals(2, set.size()) - assert.equals(set, #{a,c}) - assert.equals(#{a,c}, #{b,c}) - '''.test - } - - @Test - def void testSetOfListSize() { - ''' - const set = #{[1,2,3],[5,6],[7,8],[1,2,3],[5,6]} - assert.equals(3, set.size()) - '''.test - } - - @Test - def void testSetOfEmptyListSize() { - ''' - const set = #{} - const a = [] - const b = new List() - set.add(a) - set.add(b) - assert.equals(1, set.size()) - assert.equals(set, #{a}) - assert.equals(#{a}, #{b}) - '''.test - } - - @Test - def void testSetOfSetSize() { - ''' - const set = #{#{1,2,3},#{5,6},#{7,8},#{1,2,3},#{5,6}} - assert.equals(3, set.size()) - '''.test - } - - @Test - def void testSetOfEmptySetSize() { - ''' - const set = #{} - const a = #{} - const b = #{} - set.add(a) - set.add(b) - assert.equals(1, set.size()) - assert.equals(set, #{a}) - assert.equals(#{a}, #{b}) - '''.test - } - - @Test - def void testSetOfDictionarySize() { - ''' - const set = #{} - const a = new Dictionary() - const b = new Dictionary() - const c = new Dictionary() - c.put(1, "hola") - set.add(a) - set.add(b) - set.add(c) - assert.equals(2, set.size()) - assert.equals(set, #{a,c}) - assert.equals(#{a,c}, #{b,c}) - '''.test - } - - @Test - def void testSetOfPairSize() { - ''' - const set = new Set() - const a = new Pair(x = 1, y = 2) - const b = new Pair(x = 1, y = 2) - const c = new Pair(x = 3, y = 4) - set.add(a) - set.add(b) - set.add(c) - assert.equals(2, set.size()) - assert.equals(set, #{a,c}) - assert.equals(#{a,c}, #{b,c}) - '''.test - } - - @Test - def void testSetOfPositionSize() { - ''' - const set = new Set() - const a = new Position() - const b = new Position() - var c = new Position() - c = c.up(2) - set.add(a) - set.add(b) - set.add(c) - assert.equals(2, set.size()) - assert.equals(set, #{a,c}) - assert.equals(#{a,c}, #{b,c}) - '''.test - } - - @Test - def void testSetOfUserDefinedClassSizeRedefiningEqualEqual() { - ''' - class Animal { - override method ==(otroAnimal) = self.nombre() == otroAnimal.nombre() - method nombre() - } - - class Perro inherits Animal { - override method nombre() = "Firulais" - } - - class Gato inherits Animal { - override method nombre() = "Garfield" - } - - test "issue 1771" { - const set = new Set() - const perro = new Perro() - const otroPerro = new Perro() - const gato = new Gato() - set.add(perro) - set.add(otroPerro) - set.add(gato) - assert.equals(2, set.size()) - assert.equals(set, #{perro,gato}) - assert.equals(#{perro,gato}, #{otroPerro,gato}) - } - '''.interpretPropagatingErrors - } - - @Test - def void testSetOfUserDefinedClassSizeRedefiningEquals() { - ''' - class Animal { - override method equals(otroAnimal) = self.nombre() == otroAnimal.nombre() - method nombre() - } - - class Perro inherits Animal { - override method nombre() = "Firulais" - } - - class Gato inherits Animal { - override method nombre() = "Garfield" - } - - test "issue 1771" { - const set = new Set() - const perro = new Perro() - const otroPerro = new Perro() - const gato = new Gato() - set.add(perro) - set.add(otroPerro) - set.add(gato) - assert.equals(2, set.size()) - assert.equals(set, #{perro,gato}) - assert.equals(#{perro,gato}, #{otroPerro,gato}) - } - '''.interpretPropagatingErrors - } - - @Test - def void testSetOfListAsSetConversion() { - ''' - var list = new List() - list.addAll([1,2,3]) - assert.equals(1, #{list,[1,2,3]}.asSet().size()) - '''.test - } - - @Test - def void testSetOfSetsAsSetConversion() { - ''' - var set = new Set() - set.addAll([1,2,3]) - assert.equals(1, #{set, #{1,2,3}}.asSet().size()) - '''.test - } - - @Test - override removeAll() { - ''' - «instantiateCollectionAsNumbersVariable» - numbers.removeAll(#{2, 10}) - assert.equals(#{22}, numbers) - '''.test - } - - @Test - def void testEquals() { - ''' - assert.equals(#{}, #{}) - assert.equals(#{1,2}, #{2,1}) - assert.equals(#{1,1,2,2}, #{1,2}) - '''.test - } - - @Test - def void testNotEquals() { - ''' - assert.notEquals(#{}, #{1}) - assert.notEquals(#{1}, #{}) - assert.notEquals(#{1,2}, #{1}) - assert.notEquals(#{1,3}, #{1,2}) - '''.test - } - - @Test - def void testEqualityWithOtherObjects(){ - ''' - assert.notEquals(2, #{}) - assert.notEquals(2, #{2}) - assert.notEquals(2, #{2,3,4}) - assert.notEquals(console, #{}) - '''.test - } - -} From 5d912e34cdb3222752187b798d12651bfe496717 Mon Sep 17 00:00:00 2001 From: Fernando Dodino Date: Wed, 23 Oct 2019 18:58:38 -0300 Subject: [PATCH 059/133] Deleting named/unnamed objects sanity tests --- .../NamedObjectInheritanceTest.xtend | 201 ------------------ .../namedobjects/NamedObjectTestCase.xtend | 23 -- .../UnnamedObjectInheritanceTest.xtend | 58 ----- .../namedobjects/UnnamedObjectTestCase.xtend | 33 --- 4 files changed, 315 deletions(-) delete mode 100644 org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/namedobjects/NamedObjectInheritanceTest.xtend delete mode 100644 org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/namedobjects/UnnamedObjectInheritanceTest.xtend delete mode 100644 org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/namedobjects/UnnamedObjectTestCase.xtend diff --git a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/namedobjects/NamedObjectInheritanceTest.xtend b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/namedobjects/NamedObjectInheritanceTest.xtend deleted file mode 100644 index ea26ecf363..0000000000 --- a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/namedobjects/NamedObjectInheritanceTest.xtend +++ /dev/null @@ -1,201 +0,0 @@ -package org.uqbar.project.wollok.tests.interpreter.namedobjects - -import org.uqbar.project.wollok.tests.interpreter.AbstractWollokInterpreterTestCase -import org.junit.Test - -/** - * Tests named objecst inheriting from a class - * - * @author jfernandes - */ -class NamedObjectInheritanceTest extends AbstractWollokInterpreterTestCase { - - @Test - def void noExplicitParentMeansObjectSuperclass() { - ''' - object myObject { - method something() = "abc" - } - - program p { - assert.equals("abc", myObject.something()) - assert.equals(myObject, (myObject->"42").x()) - } - '''.interpretPropagatingErrors - } - - @Test - def void objectInheritFromCustomClass() { - ''' - class MyClass { - method myMethod() = "1234" - } - object myObject inherits MyClass { - method something() = "abc" - } - - program p { - assert.equals("abc", myObject.something()) - assert.equals("1234", myObject.myMethod()) - } - '''.interpretPropagatingErrors - } - - @Test - def void objectInheritFromCustomClassWithInstanceVariable() { - ''' - class MyClass { - var inheritedVariable = "1234" - } - object myObject inherits MyClass { - method something() { - return inheritedVariable - } - method setInheritedVariable(aValue){ - inheritedVariable = aValue - } - } - - program p { - assert.equals("1234", myObject.something()) - myObject.setInheritedVariable("abc") - assert.equals("abc", myObject.something()) - } - '''.interpretPropagatingErrors - } - - @Test - def void objectInheritFromCustomClassAndOverridesMethod() { - ''' - class MyClass { - method myMethod() = "1234" - } - object myObject inherits MyClass { - method something() = "abc" - override method myMethod() = "5678" - } - - program p { - assert.equals("abc", myObject.something()) - assert.equals("5678", myObject.myMethod()) - } - '''.interpretPropagatingErrors - } - - @Test - def void objectInheritFromCustomClassAndOverridesMethodCallingSuper() { - ''' - class MyClass { - method myMethod() = "1234" - } - object myObject inherits MyClass { - method something() = "abc" - override method myMethod() = super() + "5678" - } - - program p { - assert.equals("abc", myObject.something()) - assert.equals("12345678", myObject.myMethod()) - } - '''.interpretPropagatingErrors - } - - @Test - def void objectInheritFromClassThatHasConstructor() { - ''' - class Dog { - const name - constructor(param) { - name = param - } - method name() = name - } - object lassie inherits Dog("lassie") { - } - - program p { - assert.equals("lassie", lassie.name()) - } - '''.interpretPropagatingErrors - } - - @Test - def void objectInheritFromClassThatHasConstructorPassingAnotherWKOAsArgument() { - ''' - class Dog { - const owner - constructor(param) { - owner = param - } - method owner() = owner - } - object lassie inherits Dog(jorge) { - } - - object jorge { - method name() = "Jorge" - } - - program p { - assert.equals(jorge, lassie.owner()) - } - '''.interpretPropagatingErrors - } - - @Test - def void objectInheritFromClassThatHasConstructorPassingAnotherWKOMessageReturnValue() { - ''' - class Dog { - const owner - constructor(param) { - owner = param - } - method owner() = owner - } - object lassie inherits Dog(jorge.name()) { - } - - object jorge { - method name() = "Jorge" - } - - program p { - assert.equals("Jorge", lassie.owner()) - } - '''.interpretPropagatingErrors - } - - @Test - def void testObjectInheritingFromAClass() { - ''' - class Auto { - var property kms - - constructor(_kms) { - kms = _kms - } - } - object bordini inherits Auto(2000) { - method color() = "celeste" - } - program p { - assert.equals(2000, bordini.kms()) - }'''.interpretPropagatingErrors - } - - @Test - def void testObjectInheritingFromAClassNamedParameters() { - ''' - class Auto { - var property kms - var property owner - } - object bordini inherits Auto(owner = 'dodain', kms = 2000) { - method color() = "celeste" - } - program p { - assert.equals(2000, bordini.kms()) - }'''.interpretPropagatingErrors - } - -} \ No newline at end of file diff --git a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/namedobjects/NamedObjectTestCase.xtend b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/namedobjects/NamedObjectTestCase.xtend index 9a97787e75..ffe0e039bc 100644 --- a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/namedobjects/NamedObjectTestCase.xtend +++ b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/namedobjects/NamedObjectTestCase.xtend @@ -9,29 +9,6 @@ import org.uqbar.project.wollok.tests.interpreter.AbstractWollokInterpreterTestC */ class NamedObjectTestCase extends AbstractWollokInterpreterTestCase { - @Test - def void testMultipleReferencesToSameObjectCreatesJustOneInstance() { ''' - object pp { - var ps = [pepita] - method unMethod(){ - var x = pepita - return x - } - - method getPs() { - return ps - } - } - - object pepita { } - - program p { - pp.unMethod() - - assert.equals(pepita, pp.getPs().get(0)) - }'''.interpretPropagatingErrors - } - @Test def void testObjectScopingWithClassesFailsOnLinking() { try { diff --git a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/namedobjects/UnnamedObjectInheritanceTest.xtend b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/namedobjects/UnnamedObjectInheritanceTest.xtend deleted file mode 100644 index e64aa88e5f..0000000000 --- a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/namedobjects/UnnamedObjectInheritanceTest.xtend +++ /dev/null @@ -1,58 +0,0 @@ -package org.uqbar.project.wollok.tests.interpreter.namedobjects - -import org.uqbar.project.wollok.tests.interpreter.AbstractWollokInterpreterTestCase -import org.junit.Test - -/** - * Tests named objecst inheriting from a class - * - * @author jfernandes - */ -class UnnamedObjectInheritanceTest extends AbstractWollokInterpreterTestCase { - - @Test - def void testObjectInheritingFromAClass() { - ''' - class Auto { - var property kms - - constructor(_kms) { - kms = _kms - } - } - - program p { - var n = 33 - - const o = object inherits Auto(2000) { - method getN() { - return n - } - } - - assert.equals(2000, o.kms()) - }'''.interpretPropagatingErrors - } - - @Test - def void testObjectInheritingFromAClassNamedParameters() { - ''' - class Auto { - var property kms - var property owner - } - - program p { - var n = 33 - - const o = object inherits Auto(owner = 'dodain', kms = 2000) { - method getN() { - return n - } - } - - assert.equals(2000, o.kms()) - }'''.interpretPropagatingErrors - } - -} \ No newline at end of file diff --git a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/namedobjects/UnnamedObjectTestCase.xtend b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/namedobjects/UnnamedObjectTestCase.xtend deleted file mode 100644 index 209bcbea4c..0000000000 --- a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/namedobjects/UnnamedObjectTestCase.xtend +++ /dev/null @@ -1,33 +0,0 @@ -package org.uqbar.project.wollok.tests.interpreter.namedobjects - -import org.junit.Test -import org.uqbar.project.wollok.tests.interpreter.AbstractWollokInterpreterTestCase - -/** - * - * @author jfernandes - */ -class UnnamedObjectTestCase extends AbstractWollokInterpreterTestCase { - - @Test - def void testObjectScopingUsingVariableDefinedOutsideOfIt() { - ''' - program p { - var n = 33 - - const o = object { - method getN() { - return n - } - } - - assert.that(33 == o.getN()) - - // change N - n = 34 - - assert.that(34 == o.getN()) - }'''.interpretPropagatingErrors - } - -} \ No newline at end of file From 7d4d3f51d32ccbd8039ed654def43026073e1b68 Mon Sep 17 00:00:00 2001 From: Fernando Dodino Date: Wed, 23 Oct 2019 23:38:37 -0300 Subject: [PATCH 060/133] Removing null tests => to sanity tests --- .../tests/interpreter/NullTestCase.xtend | 178 ------------------ 1 file changed, 178 deletions(-) delete mode 100644 org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/NullTestCase.xtend diff --git a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/NullTestCase.xtend b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/NullTestCase.xtend deleted file mode 100644 index a6c5ee92a5..0000000000 --- a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/NullTestCase.xtend +++ /dev/null @@ -1,178 +0,0 @@ -package org.uqbar.project.wollok.tests.interpreter - -import org.junit.Test - -class NullTestCase extends AbstractWollokInterpreterTestCase { - - def defineAssertWithMessage() { - ''' - object extendedAssert { - method assertException(closure, msg) { - try { - closure.apply() - } catch e: Exception { - var message = e.message() - if (e.cause() != null) { - message = e.cause().message() - } - assert.equals(msg, message) - } - } - } - ''' - } - - @Test - def void messageSentToNull() { - ''' - «defineAssertWithMessage» - program a { - var a = null - extendedAssert.assertException({ a.sayHi() }, "Reference a is not initialized") - } - '''.interpretPropagatingErrors - } - - @Test - def void numberOperatorsSentToNull() { - ''' - «defineAssertWithMessage» - program a { - extendedAssert.assertException({ null + 3 }, "null does not understand +") - extendedAssert.assertException({ null - 3 }, "null does not understand -") - extendedAssert.assertException({ null * 3 }, "null does not understand *") - extendedAssert.assertException({ null / 3 }, "null does not understand /") - } - '''.interpretPropagatingErrors - } - - @Test - def void booleanOperatorsSentToNull() { - ''' - «defineAssertWithMessage» - program a { - extendedAssert.assertException({ null || null }, "null does not understand ||") - extendedAssert.assertException({ null && null }, "null does not understand &&") - } - '''.interpretPropagatingErrorsWithoutStaticChecks - } - - @Test - def void equalEqualOperatorSentToNull() { - ''' - class Golondrina { var energia = 0 } - - program a { - var valorNulo - //Just to check if the null can be tested against a WKO - //Cannot be performed directly because you should not use comparison over WKO - var x = assert - - assert.notThat(null == 8) - assert.notThat(null == "pepe") - assert.notThat(null == 3.0) - assert.notThat(null == 1..2) - assert.notThat(null == [1,2,3]) - assert.notThat(null == #{1,2,3}) - assert.notThat(null == x) - assert.notThat(null == new Golondrina()) - assert.notThat(valorNulo == 8) - assert.that(valorNulo == null) - assert.notThat(valorNulo != null) - } - '''.interpretPropagatingErrors - } - - @Test - def void equalEqualOperatorWithANullArgument() { - interpretPropagatingErrorsWithoutStaticChecks(''' - class Golondrina { var energia = 0 } - - program a { - assert.notThat(8 == null) - assert.notThat("pepe" == null) - assert.notThat(false == null) - assert.notThat(2.0 == null) - assert.notThat(1..2 == null) - assert.notThat([1,2,3] == null) - assert.notThat(#{1,2,3} == null) - assert.notThat(assert == null) - assert.notThat(new Golondrina() == null) - } - ''') - } - - @Test - def void ifInANullExpression() { - ''' - var expresionNula - var mensajeError - try { - if (expresionNula) { - assert.fail("Null Expression didn't fail!") - } - } catch e: Exception { - mensajeError = e.message() - } - assert.equals("Cannot use null in 'if' expression", mensajeError) - '''.test - } - - @Test - def void nullInAOpMultiAndPostFix() { - - ''' - «definePepitaAndAlpiste» - program a { - assert.throwsException({ pepita.comer(alpiste)}) - } - '''.interpretPropagatingErrors - } - - @Test - def void nullInAOpMultiAndPostFix2() { - - ''' - «definePepitaAndAlpiste» - program a { - assert.throwsException({ pepita.volar(10)}) - } - '''.interpretPropagatingErrors - } - - @Test - def void checkNullByIdentity(){ - ''' - program a { - var a = null - assert.that(a == null) - assert.notThat(a != null) - assert.that(a === null) - assert.notThat(a !== null) - assert.notThat(1 === null) - assert.that(1 !== null) - - assert.notThat(1 === 2) - assert.that(1 !== 2) - } - '''.interpretPropagatingErrors - } - - private def String definePepitaAndAlpiste() { - ''' - object pepita { - var energia - method energia() { return energia } - - method volar(metros) { energia -= metros * 10 } - method comer(comida) { - energia += comida.energia() - } - } - - object alpiste { - method energia() = 2 - } - ''' - } -} \ No newline at end of file From bff4693ee5b2a5a1f91751f0c78aebb0c84d6ff6 Mon Sep 17 00:00:00 2001 From: Fernando Dodino Date: Thu, 24 Oct 2019 00:29:27 -0300 Subject: [PATCH 061/133] Language & global constants moved to wollok-language sanity tests --- .../wollok/tests/interpreter/IfTestCase.xtend | 30 ------------- .../tests/interpreter/MethodsTestCase.xtend | 39 ----------------- .../interpreter/MultiOpAssignTestCase.xtend | 36 ++-------------- .../interpreter/PolymorphismTestCase.xtend | 40 ----------------- .../interpreter/SuperInvocationTest.xtend | 43 ------------------- 5 files changed, 4 insertions(+), 184 deletions(-) delete mode 100644 org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/IfTestCase.xtend delete mode 100644 org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/MethodsTestCase.xtend delete mode 100644 org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/PolymorphismTestCase.xtend delete mode 100644 org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/SuperInvocationTest.xtend diff --git a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/IfTestCase.xtend b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/IfTestCase.xtend deleted file mode 100644 index d8971a19ef..0000000000 --- a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/IfTestCase.xtend +++ /dev/null @@ -1,30 +0,0 @@ -package org.uqbar.project.wollok.tests.interpreter - -import org.junit.Test - -/** - * Tests for if conditions - * - * @author dodain - */ -class IfTestCase extends AbstractWollokInterpreterTestCase { - - @Test - def void ifConditionAsANumber() { - ''' - object numeroLoco { - method calculoLoco(n) { - if (n) { - return 0 - } - return n - } - } - - test "if condition as a number" { - assert.throwsExceptionWithMessage("Expression in 'if' must evaluate to a boolean. Instead got: 3 (Number)", { => numeroLoco.calculoLoco(3) }) - } - '''.interpretPropagatingErrors - } - -} \ No newline at end of file diff --git a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/MethodsTestCase.xtend b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/MethodsTestCase.xtend deleted file mode 100644 index f234823bc1..0000000000 --- a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/MethodsTestCase.xtend +++ /dev/null @@ -1,39 +0,0 @@ -package org.uqbar.project.wollok.tests.interpreter - -import org.junit.Test - -/** - * Basic Tests for methods writting - * - * @author tesonep - */ -class MethodsTestCase extends AbstractWollokInterpreterTestCase { - - @Test - def void inLineOk() { - #["objects" -> ''' - class A { - method method1(asd) { - return asd + 1 - } - method method2(asd) = asd + 1 - method method3(asd) = 4 - method method4(asd) = return 4 - } - ''', - "pgm" -> ''' - import objects.A - - program xxx { - const x = new A() - - assert.equals(x.method1(2), 3) - assert.equals(x.method2(2), 3) - assert.equals(x.method3(2), 4) - assert.equals(x.method4(2), 4) - } - ''' - ].interpretPropagatingErrors - } - -} diff --git a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/MultiOpAssignTestCase.xtend b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/MultiOpAssignTestCase.xtend index 010c3438b1..b0efbb375a 100644 --- a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/MultiOpAssignTestCase.xtend +++ b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/MultiOpAssignTestCase.xtend @@ -6,41 +6,12 @@ import static org.uqbar.project.wollok.WollokConstants.* /** * Test cases for operators such as: +=, -=, etc. - * + * + * This tests should remain as part of Wollok-Xtext implementation + * * @author jfernandes */ class MultiOpAssignTestCase extends AbstractWollokInterpreterTestCase { - @Test - def void testPlusEquals() {''' - program p { - var n = 1 - n += 1 - - assert.that(n == 2) - }'''.interpretPropagatingErrors - } - - @Test - def void testMultiplyEquals() {''' - program p { - var n = 2 - n *= 3 - - assert.that(n == 6) - }'''.interpretPropagatingErrors - } - - @Test - def void testSubstractEquals() {''' - program p { - var n = 2 - n -= 1 - - assert.that(n == 1) - }'''.interpretPropagatingErrors - } - - // helper for impl @Test def void testMatches() { @@ -53,4 +24,5 @@ class MultiOpAssignTestCase extends AbstractWollokInterpreterTestCase { assertFalse(s.matches(MULTIOPS_REGEXP)) ] } + } \ No newline at end of file diff --git a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/PolymorphismTestCase.xtend b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/PolymorphismTestCase.xtend deleted file mode 100644 index a5f6b03760..0000000000 --- a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/PolymorphismTestCase.xtend +++ /dev/null @@ -1,40 +0,0 @@ -package org.uqbar.project.wollok.tests.interpreter - -import org.junit.Test - -/** - * Tests polymorphism in different cases: object literals, - * classes, etc. - * - * @author jfernandes - */ -class PolymorphismTestCase extends AbstractWollokInterpreterTestCase { - - @Test - def void testPolymorphicParameterWithObjectLiterals() { - ''' - program p { - const pepona = object { - var energia = 100 - method comer(comida) { - energia = energia + comida.energia() - } - method energia() { - return energia - } - } - - const alpiste = object { - method energia() { - return 5 - } - } - - pepona.comer(alpiste) - - assert.that(105 == pepona.energia()) - } - '''.interpretPropagatingErrors - } - -} \ No newline at end of file diff --git a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/SuperInvocationTest.xtend b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/SuperInvocationTest.xtend deleted file mode 100644 index b7419d0a6a..0000000000 --- a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/SuperInvocationTest.xtend +++ /dev/null @@ -1,43 +0,0 @@ -package org.uqbar.project.wollok.tests.interpreter - -import org.junit.Test - -/** - * - * @author npasserini - */ -class SuperInvocationTest extends AbstractWollokInterpreterTestCase { - - @Test - def void testSuperInvocation() { - ''' - class Golondrina { - var energia = 100 - - method energia() { - return energia - } - - method volar(kms) { - energia = energia - self.gastoParaVolar(kms) // Invocacion a método que se va a sobreescribir - } - - method gastoParaVolar(kms) { - return kms - } - } - - class SeCansaMucho inherits Golondrina { - override method gastoParaVolar(kms) { - return 2 * super(kms) - } - } - - program p { - const pepona = new SeCansaMucho() - pepona.volar(50) - assert.that(pepona.energia() == 0) // Gastó el doble de energia - } - '''.interpretPropagatingErrors - } -} From 28b256a37e494176bb9d801489b1270bc368f0ce Mon Sep 17 00:00:00 2001 From: PalumboN Date: Thu, 24 Oct 2019 17:34:40 -0300 Subject: [PATCH 062/133] Testing collisions with removed objects --- .../tests/game/CollisionListenerTest.xtend | 81 +++++++++++-------- 1 file changed, 47 insertions(+), 34 deletions(-) diff --git a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/game/CollisionListenerTest.xtend b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/game/CollisionListenerTest.xtend index d22e884418..279cee9e1d 100644 --- a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/game/CollisionListenerTest.xtend +++ b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/game/CollisionListenerTest.xtend @@ -11,7 +11,6 @@ import org.uqbar.project.wollok.game.gameboard.Gameboard import org.uqbar.project.wollok.game.listeners.CollisionListener import org.uqbar.project.wollok.game.listeners.InstantCollisionListener -import static org.junit.Assert.* import static org.mockito.Mockito.* class CollisionListenerTest { @@ -22,92 +21,106 @@ class CollisionListenerTest { VisualComponent aCoin VisualComponent otherCoin (VisualComponent)=>Object block - + @Before def void init() { gameboard = new Gameboard - + var image = new Image("path") mario = new WGVisualComponent(new WGPosition(2, 2), image) aCoin = new WGVisualComponent(new WGPosition(3, 3), image) otherCoin = new WGVisualComponent(new WGPosition(4, 4), image) - + gameboard.addComponents(newArrayList(mario, aCoin, otherCoin)) - + block = mock(Function1) listener = new CollisionListener(mario, block) instantListener = new InstantCollisionListener(mario, block) } - + @Test - def void nothing_happens_when_components_dont_collide_with_itself(){ + def void nothing_happens_when_components_dont_collide_with_itself() { listener.notify(gameboard) verifyZeroInteractions(block) } - + @Test - def void block_is_called_on_each_notify(){ + def void block_is_called_on_each_notify() { aCoin.position = mario.position - + listener.notify(gameboard) listener.notify(gameboard) - + verify(block, times(2)).apply(aCoin) } - + @Test - def void block_is_called_with_each_colliding_component(){ + def void block_is_called_with_each_colliding_component() { aCoin.position = mario.position otherCoin.position = mario.position - + listener.notify(gameboard) - + verify(block).apply(aCoin) verify(block).apply(otherCoin) } - + @Test - def void nothing_happens_when_non_observed_components_are_colliding(){ + def void nothing_happens_when_non_observed_components_are_colliding() { aCoin.position = otherCoin.position - + + listener.notify(gameboard) + + verifyZeroInteractions(block) + } + + @Test + def void collision_when_observed_component_is_removed() { + gameboard.addListener(listener) + aCoin.position = mario.position + + gameboard.remove(mario) + listener.notify(gameboard) - + verifyZeroInteractions(block) } - + @Test - def void should_keep_board_listener_when_observed_component_is_removed(){ + def void collision_when_observed_component_is_removed_and_added_again() { gameboard.addListener(listener) + aCoin.position = mario.position + gameboard.remove(mario) - assertTrue(containsListener) + gameboard.addComponent(mario) + + listener.notify(gameboard) + + verify(block, only).apply(aCoin) } - + @Test - def void instant_block_is_called_once(){ + def void instant_block_is_called_once() { aCoin.position = mario.position - + instantListener.notify(gameboard) instantListener.notify(gameboard) - + verify(block, only).apply(aCoin) } - + @Test - def void instant_block_is_called_when_components_stop_colliding_and_collide_again(){ + def void instant_block_is_called_when_components_stop_colliding_and_collide_again() { aCoin.position = mario.position instantListener.notify(gameboard) // Collide - aCoin.position = otherCoin.position instantListener.notify(gameboard) - + aCoin.position = mario.position instantListener.notify(gameboard) // Collide again - verify(block, times(2)).apply(aCoin) } - - - + def containsListener() { gameboard.listeners.contains(listener) } From 64e66f8a0cc38a7aed2c4a2cfe3000fcc58e91c8 Mon Sep 17 00:00:00 2001 From: PalumboN Date: Thu, 24 Oct 2019 18:37:51 -0300 Subject: [PATCH 063/133] CollisionListeners only works for objects in game --- .../project/wollok/game/VisualComponent.xtend | 28 +-------------- .../game/listeners/CollisionListener.xtend | 3 +- .../wollok/tests/game/ArrowListenerTest.xtend | 1 - .../tests/game/CollisionListenerTest.xtend | 1 - .../wollok/tests/game/GameboardTest.xtend | 1 - .../project/wollok/tests/game/Mocks.xtend | 36 +++++++++++++++++++ 6 files changed, 39 insertions(+), 31 deletions(-) create mode 100644 org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/game/Mocks.xtend diff --git a/org.uqbar.project.wollok.game/src/org/uqbar/project/wollok/game/VisualComponent.xtend b/org.uqbar.project.wollok.game/src/org/uqbar/project/wollok/game/VisualComponent.xtend index 56e9624290..b6e7ee2e52 100644 --- a/org.uqbar.project.wollok.game/src/org/uqbar/project/wollok/game/VisualComponent.xtend +++ b/org.uqbar.project.wollok.game/src/org/uqbar/project/wollok/game/VisualComponent.xtend @@ -147,30 +147,4 @@ class VisualComponent { if (position.x < Gameboard.instance.width - 1) setPosition(getPosition.right()) } -} - -@Accessors -class WGVisualComponent extends VisualComponent { - Position _position - Image image - List attributes - - new(Position position, Image image) { - super(null) - this._position = position - this.image = image - } - - override Image getImage() { - image - } - - override Position getPosition() { - _position - } - - override setPosition(Position position) { - _position = position - } - -} +} \ No newline at end of file diff --git a/org.uqbar.project.wollok.game/src/org/uqbar/project/wollok/game/listeners/CollisionListener.xtend b/org.uqbar.project.wollok.game/src/org/uqbar/project/wollok/game/listeners/CollisionListener.xtend index b1e3d7953a..d292129452 100644 --- a/org.uqbar.project.wollok.game/src/org/uqbar/project/wollok/game/listeners/CollisionListener.xtend +++ b/org.uqbar.project.wollok.game/src/org/uqbar/project/wollok/game/listeners/CollisionListener.xtend @@ -14,7 +14,8 @@ class CollisionListener extends GameboardListener { } override notify(Gameboard gameboard) { - gameboard.colliders.forEach[collide] + if (gameboard.alreadyInGame(component.WObject)) + gameboard.colliders.forEach[collide] } def colliders(Gameboard gameboard) { // TODO: Move to Gameboard diff --git a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/game/ArrowListenerTest.xtend b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/game/ArrowListenerTest.xtend index fd2a9a3880..265cefae36 100644 --- a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/game/ArrowListenerTest.xtend +++ b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/game/ArrowListenerTest.xtend @@ -6,7 +6,6 @@ import org.junit.Test import org.uqbar.project.wollok.game.Image import org.uqbar.project.wollok.game.VisualComponent import org.uqbar.project.wollok.game.WGPosition -import org.uqbar.project.wollok.game.WGVisualComponent import org.uqbar.project.wollok.game.gameboard.Gameboard import org.uqbar.project.wollok.game.helpers.Keyboard import org.uqbar.project.wollok.game.listeners.ArrowListener diff --git a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/game/CollisionListenerTest.xtend b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/game/CollisionListenerTest.xtend index 279cee9e1d..bb3630d4a1 100644 --- a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/game/CollisionListenerTest.xtend +++ b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/game/CollisionListenerTest.xtend @@ -6,7 +6,6 @@ import org.junit.Test import org.uqbar.project.wollok.game.Image import org.uqbar.project.wollok.game.VisualComponent import org.uqbar.project.wollok.game.WGPosition -import org.uqbar.project.wollok.game.WGVisualComponent import org.uqbar.project.wollok.game.gameboard.Gameboard import org.uqbar.project.wollok.game.listeners.CollisionListener import org.uqbar.project.wollok.game.listeners.InstantCollisionListener diff --git a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/game/GameboardTest.xtend b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/game/GameboardTest.xtend index f9acfeb641..11dd79b59f 100644 --- a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/game/GameboardTest.xtend +++ b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/game/GameboardTest.xtend @@ -7,7 +7,6 @@ import org.uqbar.project.wollok.game.Messages import org.uqbar.project.wollok.game.Position import org.uqbar.project.wollok.game.VisualComponent import org.uqbar.project.wollok.game.WGPosition -import org.uqbar.project.wollok.game.WGVisualComponent import org.uqbar.project.wollok.game.gameboard.Background import org.uqbar.project.wollok.game.gameboard.CellsBackground import org.uqbar.project.wollok.game.gameboard.FullBackground diff --git a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/game/Mocks.xtend b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/game/Mocks.xtend new file mode 100644 index 0000000000..bc93880b90 --- /dev/null +++ b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/game/Mocks.xtend @@ -0,0 +1,36 @@ +package org.uqbar.project.wollok.tests.game + +import java.util.List +import org.eclipse.xtend.lib.annotations.Accessors +import org.uqbar.project.wollok.game.Image +import org.uqbar.project.wollok.game.Position +import org.uqbar.project.wollok.game.VisualComponent +import org.uqbar.project.wollok.interpreter.core.WollokObject + +import static org.mockito.Mockito.* + +@Accessors +class WGVisualComponent extends VisualComponent { + Position _position + Image image + List attributes + + new(Position position, Image image) { + super(mock(WollokObject)) + this._position = position + this.image = image + } + + override Image getImage() { + image + } + + override Position getPosition() { + _position + } + + override setPosition(Position position) { + _position = position + } + +} From 5bfca9255e99c5cebd1ff4a17b537922b6ec74e1 Mon Sep 17 00:00:00 2001 From: Fernando Dodino Date: Fri, 25 Oct 2019 00:16:34 -0300 Subject: [PATCH 064/133] Fix #1850 - JEST-ish style for wollok-cli console test reporter --- .../tests/WollokConsoleTestsReporter.xtend | 32 ++++++++++++++++--- 1 file changed, 28 insertions(+), 4 deletions(-) diff --git a/org.uqbar.project.wollok.launch/src/org/uqbar/project/wollok/launch/tests/WollokConsoleTestsReporter.xtend b/org.uqbar.project.wollok.launch/src/org/uqbar/project/wollok/launch/tests/WollokConsoleTestsReporter.xtend index 0736b1dc5f..3317793ac4 100644 --- a/org.uqbar.project.wollok.launch/src/org/uqbar/project/wollok/launch/tests/WollokConsoleTestsReporter.xtend +++ b/org.uqbar.project.wollok.launch/src/org/uqbar/project/wollok/launch/tests/WollokConsoleTestsReporter.xtend @@ -15,6 +15,7 @@ import static org.fusesource.jansi.Ansi.Color.* import static extension org.uqbar.project.wollok.errorHandling.WollokExceptionExtensions.* import static extension org.uqbar.project.wollok.utils.StringUtils.* +import org.fusesource.jansi.Ansi /** * Logs the events to the console output. @@ -27,6 +28,9 @@ import static extension org.uqbar.project.wollok.utils.StringUtils.* */ class WollokConsoleTestsReporter extends DefaultWollokTestsReporter { + public static int MIN_PERFORMANCE_TIME_ACCEPTED = 50 + public static int MAX_PERFORMANCE_TIME_ACCEPTED = 100 + int totalTestsRun = 0 int totalTestsFailed = 0 int totalTestsErrored = 0 @@ -42,10 +46,12 @@ class WollokConsoleTestsReporter extends DefaultWollokTestsReporter { override testsToRun(String suiteName, WFile file, List tests) { AnsiConsole.systemInstall + val fileSegments = file.eResource.URI.segments + val filename = fileSegments.get(fileSegments.length - 1) if (suiteName ?: '' !== '') { - println('''Running all tests from describe «suiteName»''') + println(ansi.bold.a('''Describe «suiteName» from «filename»''').reset) } else { - println('''Running «tests.size.singularOrPlural("test")» ...''') + println(ansi.bold.a('''Individual tests from «filename»''').reset) } testsRun += tests.size testsGroupRun += tests.size @@ -61,9 +67,9 @@ class WollokConsoleTestsReporter extends DefaultWollokTestsReporter { override reportTestOk(WTest test) { test.testFinished - println(ansi.a(" ").fg(GREEN).a(test.name).a(": √ OK (").a(test.totalTime).a("ms)").reset) + println(ansi.a(" ").bold.green("√ ").reset.gray(test.name).time(test.totalTime).reset) } - + override reportTestError(WTest test, Exception exception, int lineNumber, URI resource) { test.testFinished incrementTestsErrored @@ -191,6 +197,24 @@ class WollokConsoleTestsReporter extends DefaultWollokTestsReporter { ] } + def green(Ansi ansi, String text) { + ansi.displayInColor(text, GREEN) + } + + def gray(Ansi ansi, String text) { + ansi.displayInColor(text, WHITE) + } + + def displayInColor(Ansi ansi, String text, Ansi$Color color) { + ansi.fg(color).a(text).reset + } + + def time(Ansi ansi, long time) { + if (time > MAX_PERFORMANCE_TIME_ACCEPTED) return ansi.displayInColor(" (" + time + "ms)", RED) + if (time >= MIN_PERFORMANCE_TIME_ACCEPTED && time < MAX_PERFORMANCE_TIME_ACCEPTED) return ansi.displayInColor(" (" + time + "ms)", YELLOW) + ansi + } + } @Accessors From b5e95b9329c8db401427ec74477a1278793be079 Mon Sep 17 00:00:00 2001 From: ivan Date: Sat, 26 Oct 2019 17:42:27 -0300 Subject: [PATCH 065/133] getters for volume, play, loop and pause --- .../wollok/game/gameboard/GameSound.xtend | 55 ++++++++++++++++--- .../src/wollok/game.wlk | 37 ++++++++++--- .../src/wollok/game/WSound.xtend | 20 ++++++- 3 files changed, 93 insertions(+), 19 deletions(-) diff --git a/org.uqbar.project.wollok.game/src/org/uqbar/project/wollok/game/gameboard/GameSound.xtend b/org.uqbar.project.wollok.game/src/org/uqbar/project/wollok/game/gameboard/GameSound.xtend index ef518d1bf8..d04debb6b2 100644 --- a/org.uqbar.project.wollok.game/src/org/uqbar/project/wollok/game/gameboard/GameSound.xtend +++ b/org.uqbar.project.wollok.game/src/org/uqbar/project/wollok/game/gameboard/GameSound.xtend @@ -9,33 +9,70 @@ import org.uqbar.project.wollok.game.Messages @Accessors class GameSound { String file - long soundID + Long soundID Sound sound + Boolean looped = false + Float volume = 1.0f + Boolean paused = false - def play() { - soundID = fetchSound.play() + def play() { + if(looped) + soundID = fetchSound.play(volume) + else + soundID=fetchSound.loop(volume) + } + + def played() { + soundID !== null } def stop() { fetchSound.stop() + fetchSound.dispose() } def pause() { fetchSound.pause() + paused = true } def resume() { fetchSound.resume() + paused = false + } + + def isPaused(){ + paused } - def volume(float newVolume) { - fetchSound.setVolume(soundID, newVolume) + def volume(Float newVolume) { + volume = newVolume + syncVolume() } -// def volume(){ -// } - def loop(boolean looping) { - fetchSound.setLooping(soundID, looping) + def volume() { + volume + } + + def syncVolume() { + if (played()) { + fetchSound.setVolume(soundID, volume) + } + } + + def shouldLoop(Boolean looping) { + looped = looping + syncLoop() + } + + def shouldLoop() { + looped + } + + def syncLoop() { + if (played()) { + fetchSound.setLooping(soundID, looped) + } } def fetchSound() { diff --git a/org.uqbar.project.wollok.lib/src/wollok/game.wlk b/org.uqbar.project.wollok.lib/src/wollok/game.wlk index b26ce26021..6ec7da2500 100644 --- a/org.uqbar.project.wollok.lib/src/wollok/game.wlk +++ b/org.uqbar.project.wollok.lib/src/wollok/game.wlk @@ -330,7 +330,7 @@ class Position { override method ==(other) = x == other.x() && y == other.y() /** - * String representation of a position + * String representation of a position. */ override method toString() = "(" + x + "," + y + ")" @@ -477,26 +477,37 @@ class Sound { const property file /** - * Plays the file's sound + * Plays the file's sound. Throws exception if played twice. */ method play() native + /** + * Answers whether the sound has been played or not. + */ + method played() native + /** - * Stops playing the sound without saving the state + * Stops playing the sound and disposes resources. */ method stop() native /** - * Pauses the sound + * Pauses the sound. Throws exception if the sound is already paused. */ method pause() native /** - * Resumes the sound + * Resumes playing the sound. Throws exception if the sound is already playing */ method resume() native - /** Changes absolute volume, values should be between 0 and 1 + /** + * Answers whether the sound is paused or not. + */ + method isPaused() native + + /** + * Changes absolute volume, values should be between 0 and 1. * * Examples: * mySound.volume(0.5) New volume is half of the original sound's volume @@ -504,8 +515,18 @@ class Sound { */ method volume(newVolume) native + /** + * Answers the volume of the sound. + */ + method volume() native + /** - * Now plays as a loop + * Whether the sound is set to loop or not. + */ + method shouldLoop(looping) native + + /** + * Answers whether the sound is set to loop or not. */ - method loop(looping) native + method shouldLoop() native } \ No newline at end of file diff --git a/org.uqbar.project.wollok.lib/src/wollok/game/WSound.xtend b/org.uqbar.project.wollok.lib/src/wollok/game/WSound.xtend index b664934618..3523ffb2a2 100644 --- a/org.uqbar.project.wollok.lib/src/wollok/game/WSound.xtend +++ b/org.uqbar.project.wollok.lib/src/wollok/game/WSound.xtend @@ -14,6 +14,10 @@ class WSound extends AbstractJavaWrapper { getWrapped.play() } + def WollokObject played() { + getWrapped.played().convertJavaToWollok + } + def void stop() { getWrapped.stop() } @@ -25,13 +29,25 @@ class WSound extends AbstractJavaWrapper { def void resume() { getWrapped.resume() } + + def WollokObject isPaused(){ + getWrapped.isPaused().convertJavaToWollok + } def void volume(WollokObject newVolume) { getWrapped.volume(newVolume.asNumber.floatValue) } - def void loop(boolean looping) { - getWrapped.loop(looping) + def WollokObject volume() { + getWrapped.volume().doubleValue.convertJavaToWollok //Converts to double since a Float to Wollok convertion doesn't work. + } + + def void shouldLoop(Boolean looping) { + getWrapped.shouldLoop(looping) + } + + def WollokObject shouldLoop() { + getWrapped.shouldLoop().convertJavaToWollok } override getWrapped() { From 04577429b8224a063693dcd345eb116f960e6bc0 Mon Sep 17 00:00:00 2001 From: ivan Date: Sat, 26 Oct 2019 21:03:22 -0300 Subject: [PATCH 066/133] added exceptions according to #1784 --- .../uqbar/project/wollok/game/Messages.java | 7 +++++ .../wollok/game/gameboard/GameSound.xtend | 26 ++++++++++++++----- .../project/wollok/game/messages.properties | 7 +++++ .../wollok/game/messages_es.properties | 9 +++++++ .../src/wollok/game.wlk | 10 ++++--- 5 files changed, 49 insertions(+), 10 deletions(-) diff --git a/org.uqbar.project.wollok.game/src/org/uqbar/project/wollok/game/Messages.java b/org.uqbar.project.wollok.game/src/org/uqbar/project/wollok/game/Messages.java index c223c09e98..16b14eb4bb 100644 --- a/org.uqbar.project.wollok.game/src/org/uqbar/project/wollok/game/Messages.java +++ b/org.uqbar.project.wollok.game/src/org/uqbar/project/wollok/game/Messages.java @@ -10,7 +10,14 @@ public class Messages extends NLS { public static String WollokGame_NoMessage; public static String WollokGame_ObjectAlreadyInGame; + public static String WollokGame_SoundGameNotStarted; + public static String WollokGame_SoundAlreadyPlayed; + public static String WollokGame_PausedANotPlayedSound; + public static String WollokGame_SoundAlreadyPaused; + public static String WollokGame_VolumeOutOfRange; + public static String WollokGame_SoundAlreadyPlaying; + public static String WollokGame_SoundNotYetPlayed; public static String WollokGame_CharacterKeyNotFound; public static String WollokGame_ListenerNotFound; diff --git a/org.uqbar.project.wollok.game/src/org/uqbar/project/wollok/game/gameboard/GameSound.xtend b/org.uqbar.project.wollok.game/src/org/uqbar/project/wollok/game/gameboard/GameSound.xtend index d04debb6b2..5e157d9c40 100644 --- a/org.uqbar.project.wollok.game/src/org/uqbar/project/wollok/game/gameboard/GameSound.xtend +++ b/org.uqbar.project.wollok.game/src/org/uqbar/project/wollok/game/gameboard/GameSound.xtend @@ -15,37 +15,51 @@ class GameSound { Float volume = 1.0f Boolean paused = false - def play() { - if(looped) + def play() { + if (played) + throw new RuntimeException(Messages.WollokGame_SoundAlreadyPlayed) + if (looped) soundID = fetchSound.play(volume) else - soundID=fetchSound.loop(volume) + soundID = fetchSound.loop(volume) } def played() { - soundID !== null + soundID !== null } def stop() { + if(!played) + throw new RuntimeException(Messages.WollokGame_SoundNotYetPlayed) fetchSound.stop() fetchSound.dispose() } def pause() { + if (!played) + throw new RuntimeException(Messages.WollokGame_PausedANotPlayedSound) + if (paused) + throw new RuntimeException(Messages.WollokGame_SoundAlreadyPaused) fetchSound.pause() paused = true } def resume() { + if (!played) + throw new RuntimeException(Messages.WollokGame_PausedANotPlayedSound) + if (!paused) + throw new RuntimeException(Messages.WollokGame_SoundAlreadyPlaying) fetchSound.resume() paused = false } - - def isPaused(){ + + def isPaused() { paused } def volume(Float newVolume) { + if (newVolume < 0 || newVolume > 1) + throw new RuntimeException(Messages.WollokGame_VolumeOutOfRange) volume = newVolume syncVolume() } diff --git a/org.uqbar.project.wollok.game/src/org/uqbar/project/wollok/game/messages.properties b/org.uqbar.project.wollok.game/src/org/uqbar/project/wollok/game/messages.properties index ad690be210..be1945e91d 100644 --- a/org.uqbar.project.wollok.game/src/org/uqbar/project/wollok/game/messages.properties +++ b/org.uqbar.project.wollok.game/src/org/uqbar/project/wollok/game/messages.properties @@ -3,7 +3,14 @@ # WollokGame_NoMessage = NO MESSAGE WollokGame_ObjectAlreadyInGame = {0} is already in the game. + WollokGame_SoundGameNotStarted = You cannot play sounds until the game has started. Try using it inside an onTick / onPressDo block. +WollokGame_SoundAlreadyPlayed = You cannot play a sound more than once. +WollokGame_PausedANotPlayedSound = You cannot pause a sound that hasn't been played. +WollokGame_SoundAlreadyPaused = You cannot pause or resume a sound that's already paused. +WollokGame_VolumeOutOfRange = Volume value must be between 0 and 1. +WollokGame_SoundAlreadyPlaying = You cannot resume a sound if that isn't paused. +WollokGame_SoundNotYetPlayed = You cannot stop a sound that hasn't been played yet. WollokGame_CharacterKeyNotFound = Character key [{0}] not found. WollokGame_ListenerNotFound = There is no tick event called {0}. diff --git a/org.uqbar.project.wollok.game/src/org/uqbar/project/wollok/game/messages_es.properties b/org.uqbar.project.wollok.game/src/org/uqbar/project/wollok/game/messages_es.properties index f4fbb20ca0..4d750666ee 100644 --- a/org.uqbar.project.wollok.game/src/org/uqbar/project/wollok/game/messages_es.properties +++ b/org.uqbar.project.wollok.game/src/org/uqbar/project/wollok/game/messages_es.properties @@ -3,7 +3,16 @@ # WollokGame_NoMessage = FALTA MENSAJE WollokGame_ObjectAlreadyInGame = {0} ya se encuentra en el juego. + WollokGame_SoundGameNotStarted = No se puede pedir un sonido hasta que el juego comience. Pruebe definirlo dentro de un bloque onTick / onPressDo. +WollokGame_SoundAlreadyPlayed = No se puede reproducir un sonido mas de una vez. +WollokGame_PausedANotPlayedSound = No se puede pausar o resumir un sonido si no esta reprudiciendose. +WollokGame_SoundAlreadyPaused = No se puede pausar un sonido si este ya esta pausado. +WollokGame_VolumeOutOfRange = El valor del volumen debe estar entre 0 y 1. +WollokGame_SoundAlreadyPlaying = No se puede resumir un sonido que no esta pausado. +WollokGame_SoundNotYetPlayed = No se puede detener un sonido que todavia no se reprodujo. + + WollokGame_CharacterKeyNotFound = No se encuentra el caracter {0} . WollokGame_ListenerNotFound = No existe el evento de nombre {0}. diff --git a/org.uqbar.project.wollok.lib/src/wollok/game.wlk b/org.uqbar.project.wollok.lib/src/wollok/game.wlk index 6ec7da2500..5bf8cb2d0c 100644 --- a/org.uqbar.project.wollok.lib/src/wollok/game.wlk +++ b/org.uqbar.project.wollok.lib/src/wollok/game.wlk @@ -477,7 +477,7 @@ class Sound { const property file /** - * Plays the file's sound. Throws exception if played twice. + * Plays the file's sound. A sound can't be played more than once. */ method play() native @@ -492,12 +492,14 @@ class Sound { method stop() native /** - * Pauses the sound. Throws exception if the sound is already paused. + * Pauses the sound. + * Throws exception if the sound is already paused or if the sound hasn't been played yet. */ method pause() native /** - * Resumes playing the sound. Throws exception if the sound is already playing + * Resumes playing the sound. + * Throws exception if the sound is not paused. */ method resume() native @@ -507,7 +509,7 @@ class Sound { method isPaused() native /** - * Changes absolute volume, values should be between 0 and 1. + * Changes absolute volume, values must be between 0 and 1. * * Examples: * mySound.volume(0.5) New volume is half of the original sound's volume From 895d3d6c34c9fa2f3c56fdcb7ac862c879d5023a Mon Sep 17 00:00:00 2001 From: Fernando Dodino Date: Sun, 27 Oct 2019 23:41:33 -0300 Subject: [PATCH 067/133] Fix #1855 - stack overflow exception for references defined inside a try in a describe --- .../project/wollok/launch/WollokChecker.xtend | 6 +++-- .../WollokInterpreterEvaluator.xtend | 3 ++- .../interpreter/core/ToStringBuilder.xtend | 10 ++++---- .../interpreter/core/WollokObject.xtend | 5 ++-- .../model/WMethodContainerExtensions.xtend | 23 ++++++++++++++++--- 5 files changed, 35 insertions(+), 12 deletions(-) diff --git a/org.uqbar.project.wollok.launch/src/org/uqbar/project/wollok/launch/WollokChecker.xtend b/org.uqbar.project.wollok.launch/src/org/uqbar/project/wollok/launch/WollokChecker.xtend index 9c3d28c456..5db2bc166b 100644 --- a/org.uqbar.project.wollok.launch/src/org/uqbar/project/wollok/launch/WollokChecker.xtend +++ b/org.uqbar.project.wollok.launch/src/org/uqbar/project/wollok/launch/WollokChecker.xtend @@ -76,9 +76,11 @@ class WollokChecker { } catch (WollokTestsFailedException e) { System.exit(1) } catch (Throwable t) { - log.error("Checker error : " + t.class.name) + log.error("Checker error") + log.error("Parameters: " + args.map [ it ].join(", ")) + if (t.message !== null) log.error(t.message) else log.error(t.class.name) t.stackTrace.forEach [ ste | - log.error('''«ste.methodName» («ste.fileName»:«ste.lineNumber»)''') + log.error(''' «ste.methodName» («ste.fileName»:«ste.lineNumber»)''') ] System.exit(1) } diff --git a/org.uqbar.project.wollok/src/org/uqbar/project/wollok/interpreter/WollokInterpreterEvaluator.xtend b/org.uqbar.project.wollok/src/org/uqbar/project/wollok/interpreter/WollokInterpreterEvaluator.xtend index 9102c9099c..0258bb6c75 100644 --- a/org.uqbar.project.wollok/src/org/uqbar/project/wollok/interpreter/WollokInterpreterEvaluator.xtend +++ b/org.uqbar.project.wollok/src/org/uqbar/project/wollok/interpreter/WollokInterpreterEvaluator.xtend @@ -200,8 +200,9 @@ class WollokInterpreterEvaluator implements XInterpreterEvaluator cach.evaluate(e) } else throw e - } finally + } finally { t.alwaysExpression?.eval + } } def evaluate(WCatch it, WollokProgramExceptionWrapper e) { diff --git a/org.uqbar.project.wollok/src/org/uqbar/project/wollok/interpreter/core/ToStringBuilder.xtend b/org.uqbar.project.wollok/src/org/uqbar/project/wollok/interpreter/core/ToStringBuilder.xtend index 00be1eb380..6755592e36 100644 --- a/org.uqbar.project.wollok/src/org/uqbar/project/wollok/interpreter/core/ToStringBuilder.xtend +++ b/org.uqbar.project.wollok/src/org/uqbar/project/wollok/interpreter/core/ToStringBuilder.xtend @@ -1,25 +1,27 @@ package org.uqbar.project.wollok.interpreter.core +import org.uqbar.project.wollok.interpreter.MixedMethodContainer import org.uqbar.project.wollok.wollokDsl.WClass +import org.uqbar.project.wollok.wollokDsl.WMixin import org.uqbar.project.wollok.wollokDsl.WNamedObject import org.uqbar.project.wollok.wollokDsl.WObjectLiteral +import org.uqbar.project.wollok.wollokDsl.WSuite import static org.uqbar.project.wollok.Messages.* -import org.uqbar.project.wollok.wollokDsl.WMixin -import org.uqbar.project.wollok.interpreter.MixedMethodContainer /** * @author tesonep * @author jfernandes */ class ToStringBuilder { - + def static shortLabel(WollokObject obj) { obj.behavior.objectDescription } + def static dispatch objectDescription(WSuite suite) { suite.name } def static dispatch objectDescription(WClass clazz) { OBJECT_DESCRIPTION_ARTICLE + clazz.name } def static dispatch objectDescription(WObjectLiteral obj) { OBJECT_DESCRIPTION_AN_OBJECT } def static dispatch objectDescription(WNamedObject namedObject) { namedObject.name } def static dispatch objectDescription(WMixin mixin) { mixin.name } def static dispatch objectDescription(MixedMethodContainer mmc) { mmc.toString } - + } \ No newline at end of file diff --git a/org.uqbar.project.wollok/src/org/uqbar/project/wollok/interpreter/core/WollokObject.xtend b/org.uqbar.project.wollok/src/org/uqbar/project/wollok/interpreter/core/WollokObject.xtend index ab3076a9d0..8c94775edb 100644 --- a/org.uqbar.project.wollok/src/org/uqbar/project/wollok/interpreter/core/WollokObject.xtend +++ b/org.uqbar.project.wollok/src/org/uqbar/project/wollok/interpreter/core/WollokObject.xtend @@ -176,8 +176,9 @@ class WollokObject extends AbstractWollokCallable implements EvaluationContext variableDeclarations(EObject o) { newArrayList } + def static dispatch List variableDeclarations(WBlockExpression b) { b.expressions.filter(WVariableDeclaration).toList } + def static dispatch List variableDeclarations(WMethodContainer c) { c.members.filter(WVariableDeclaration).toList } + def static dispatch List variableDeclarations(WVariableDeclaration e) { + #[e] + } + def static dispatch List variableDeclarations(WCatch c) { + c.expression.variableDeclarations + } + def static dispatch List variableDeclarations(WTry t) { + t.expression.variableDeclarations + } + def static dispatch List variableDeclarations(WTest test) { + test.elements.flatMap [ variableDeclarations ].toList + } def static dispatch EObject fixture(WMethodContainer c) { null } def static dispatch EObject fixture(WSuite s) { s.fixture } From 0156f8d9755663d282d3e66923ce77d1463c1766 Mon Sep 17 00:00:00 2001 From: Fernando Dodino Date: Mon, 28 Oct 2019 01:22:18 -0300 Subject: [PATCH 068/133] Enhancing Sanity Check in Eclipse --- .../launch/WollokLauncherParameters.xtend | 1 + .../launch/setup/WollokLauncherModule.xtend | 5 +- .../tests/WollokConsoleTestsReporter.xtend | 32 +- .../WollokTestInjectorProvider.xtend | 15 +- .../AbstractWollokInterpreterTestCase.xtend | 6 +- .../tests/interpreter/ExceptionTestCase.xtend | 505 +----------------- .../numbers/CollectionsMinMaxTest.xtend | 47 -- .../tests/sanityTests/SanityTestCase.xtend | 48 +- .../WollokExceptionExtensions.xtend | 9 +- .../project/wollok/utils/StringUtils.xtend | 8 +- 10 files changed, 91 insertions(+), 585 deletions(-) delete mode 100644 org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/numbers/CollectionsMinMaxTest.xtend diff --git a/org.uqbar.project.wollok.launch/src/org/uqbar/project/wollok/launch/WollokLauncherParameters.xtend b/org.uqbar.project.wollok.launch/src/org/uqbar/project/wollok/launch/WollokLauncherParameters.xtend index 24ccf5d676..8785b39473 100644 --- a/org.uqbar.project.wollok.launch/src/org/uqbar/project/wollok/launch/WollokLauncherParameters.xtend +++ b/org.uqbar.project.wollok.launch/src/org/uqbar/project/wollok/launch/WollokLauncherParameters.xtend @@ -35,6 +35,7 @@ class WollokLauncherParameters { boolean validate = true boolean exitOnBuildFailure = false boolean saveFile = false + boolean colored = true Integer numberOfDecimals = null String printingStrategy = null diff --git a/org.uqbar.project.wollok.launch/src/org/uqbar/project/wollok/launch/setup/WollokLauncherModule.xtend b/org.uqbar.project.wollok.launch/src/org/uqbar/project/wollok/launch/setup/WollokLauncherModule.xtend index 3aecb8b0f7..762d8c4698 100644 --- a/org.uqbar.project.wollok.launch/src/org/uqbar/project/wollok/launch/setup/WollokLauncherModule.xtend +++ b/org.uqbar.project.wollok.launch/src/org/uqbar/project/wollok/launch/setup/WollokLauncherModule.xtend @@ -9,6 +9,7 @@ import org.uqbar.project.wollok.launch.WollokLauncherParameters import org.uqbar.project.wollok.launch.tests.DefaultWollokTestsReporter import org.uqbar.project.wollok.launch.tests.WollokConsoleTestsReporter import org.uqbar.project.wollok.launch.tests.WollokRemoteTestReporter +import org.uqbar.project.wollok.launch.tests.WollokSimpleConsoleTestsReporter import org.uqbar.project.wollok.launch.tests.WollokTestsReporter import org.uqbar.project.wollok.launch.tests.json.WollokJSONTestsReporter import org.uqbar.project.wollok.launch.tests.json.WollokLauncherIssueHandlerJSON @@ -52,7 +53,9 @@ class WollokLauncherModule extends WollokDslRuntimeModule { return WollokRemoteTestReporter if (params.jsonOutput) return WollokJSONTestsReporter - return WollokConsoleTestsReporter + if (params.colored) + return WollokConsoleTestsReporter + return WollokSimpleConsoleTestsReporter } else { return DefaultWollokTestsReporter } diff --git a/org.uqbar.project.wollok.launch/src/org/uqbar/project/wollok/launch/tests/WollokConsoleTestsReporter.xtend b/org.uqbar.project.wollok.launch/src/org/uqbar/project/wollok/launch/tests/WollokConsoleTestsReporter.xtend index 3317793ac4..d65861e350 100644 --- a/org.uqbar.project.wollok.launch/src/org/uqbar/project/wollok/launch/tests/WollokConsoleTestsReporter.xtend +++ b/org.uqbar.project.wollok.launch/src/org/uqbar/project/wollok/launch/tests/WollokConsoleTestsReporter.xtend @@ -10,12 +10,13 @@ import org.uqbar.project.wollok.wollokDsl.WFile import org.uqbar.project.wollok.wollokDsl.WTest import wollok.lib.AssertionException +import org.fusesource.jansi.Ansi + import static org.fusesource.jansi.Ansi.* import static org.fusesource.jansi.Ansi.Color.* import static extension org.uqbar.project.wollok.errorHandling.WollokExceptionExtensions.* import static extension org.uqbar.project.wollok.utils.StringUtils.* -import org.fusesource.jansi.Ansi /** * Logs the events to the console output. @@ -43,9 +44,17 @@ class WollokConsoleTestsReporter extends DefaultWollokTestsReporter { List reportTestsFailed = newArrayList public static String FINAL_SEPARATOR = "=====================================================================================================" - - override testsToRun(String suiteName, WFile file, List tests) { + + new() { AnsiConsole.systemInstall + } + + override folderStarted(String folder) { + super.folderStarted(folder) + this.resetTotalTestsCount + } + + override testsToRun(String suiteName, WFile file, List tests) { val fileSegments = file.eResource.URI.segments val filename = fileSegments.get(fileSegments.length - 1) if (suiteName ?: '' !== '') { @@ -124,6 +133,12 @@ class WollokConsoleTestsReporter extends DefaultWollokTestsReporter { testsGroupErrored = 0 } + def resetTotalTestsCount() { + totalTestsRun = 0 + totalTestsFailed = 0 + totalTestsErrored = 0 + } + def incrementTestsFailed() { testsFailed++ testsGroupFailed++ @@ -217,6 +232,17 @@ class WollokConsoleTestsReporter extends DefaultWollokTestsReporter { } +/** + * Internal console for sanity tests in Eclipse/Xtext build - without colors + */ +class WollokSimpleConsoleTestsReporter extends WollokConsoleTestsReporter { + + new() { + super() + Ansi.setEnabled = false + } +} + @Accessors @Data class WTestFailed { diff --git a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/injectors/WollokTestInjectorProvider.xtend b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/injectors/WollokTestInjectorProvider.xtend index ea82ccc979..466eb6e720 100644 --- a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/injectors/WollokTestInjectorProvider.xtend +++ b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/injectors/WollokTestInjectorProvider.xtend @@ -10,7 +10,20 @@ class WollokTestInjectorProvider extends WollokDslInjectorProvider { new WollokTestSetup(params).createInjectorAndDoEMFRegistration } - def protected createParameters(){ + def protected createParameters() { new WollokLauncherParameters } } + +class WollokSanityTestInjectorProvider extends WollokTestInjectorProvider { + + override createParameters() { + new WollokLauncherParameters => [ + severalFiles = true + tests = true + jsonOutput = false + exitOnBuildFailure = false + colored = false + ] + } +} diff --git a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/AbstractWollokInterpreterTestCase.xtend b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/AbstractWollokInterpreterTestCase.xtend index af7b12d480..e8bee9c0ef 100644 --- a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/AbstractWollokInterpreterTestCase.xtend +++ b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/AbstractWollokInterpreterTestCase.xtend @@ -126,9 +126,13 @@ abstract class AbstractWollokInterpreterTestCase extends Assert { } def interpretPropagatingErrors(File fileToRead, boolean validate) { + fileToRead.interpretPropagatingErrors(validate, true) + } + + def interpretPropagatingErrors(File fileToRead, boolean validate, boolean propagatingErrors) { new FileInputStream(fileToRead).parse(URI.createFileURI(fileToRead.path), null, resourceSet) => [ if (validate) assertNoErrors - interpret(true, !validate) + it.interpret(propagatingErrors) ] } diff --git a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/ExceptionTestCase.xtend b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/ExceptionTestCase.xtend index 952e0b55a2..ab181e7bef 100644 --- a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/ExceptionTestCase.xtend +++ b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/ExceptionTestCase.xtend @@ -11,474 +11,6 @@ import static extension org.uqbar.project.wollok.interpreter.nativeobj.WollokJav */ class ExceptionTestCase extends AbstractWollokInterpreterTestCase { - @Test - def void testThrowAndCatch() { - #[ - ''' - class MyException inherits Exception {} - class A { - method m1() { throw new MyException() } - } - program p { - const a = new A() - var counter = 0 - - try { - a.m1() - counter = counter + 1 - } - catch e : MyException { - console.println("Exception raised!") // OK! - e.printStackTrace() - } - } - '''].interpretPropagatingErrors - - val counter = interpreter.currentContext.resolve("counter") as WollokObject - assertEquals(0, counter.asInteger) - } - - @Test - def void testThenAlwaysExcecutedOnException() { - ''' - class MyException inherits wollok.lang.Exception {} - class A { method m1() { throw new MyException() } } - - program p { - const a = new A() - var counter = 0 - - try { - a.m1() - } - catch e : MyException - console.println("Exception raised!") // OK! - then always - counter = counter + 1 - }'''. - interpretPropagatingErrors - val counter = interpreter.currentContext.resolve("counter") as WollokObject - assertEquals(1, counter.asInteger) - } - - @Test - def void testThenAlwaysExcecutedEvenWithoutAnExceptionRaised() { - ''' - class MyException inherits wollok.lang.Exception {} - class A { - method m1() { - } - } - - program p { - const a = new A() - var counter = 0 - - try { - a.m1() - counter = counter + 1 - } - catch e : MyException - console.println("Exception raised!") // OK! - then always - counter = counter + 1 - } - '''. - interpretPropagatingErrors - val counter = interpreter.currentContext.resolve("counter") as WollokObject - assertEquals(2, counter.asInteger) - } - - @Test - def void testCatchUsingTheExceptionVariable() { - ''' - class MyException inherits wollok.lang.Exception { - method customMessage() { - return "Something went wrong" - } - } - class A { method m1() { throw new MyException() } } - - program p { - const a = new A() - var result = null - - try { - a.m1() - } - catch e : MyException - result = e.customMessage() - } - '''.interpretPropagatingErrors - val result = interpreter.currentContext.resolve("result") - assertEquals("Something went wrong", result.toString) - } - - @Test - def void testCatchMatchesSubtype() { - ''' - class MyException inherits wollok.lang.Exception {} - class MySubclassException inherits MyException {} - class A { method m1() { throw new MySubclassException() } } - - program p { - const a = new A() - var result = 0 - - try { - a.m1() - } - catch e : MyException - result = 3 - - assert.that(3 == result) - } - '''.interpretPropagatingErrors - } - - @Test - def void testFirstCatchMatches() { - ''' - class MyException inherits wollok.lang.Exception {} - class MySubclassException inherits MyException {} - class A { method m1() { throw new MySubclassException() } } - - program p { - const a = new A() - var result = 0 - - try - a.m1() - - catch e : MySubclassException - result = 3 - catch e : MyException - result = 2 - assert.that(3 == result) - } - '''.interpretPropagatingErrors - } - - @Test - def void testMessageNotUnderstood() { - ''' - class A { - method m1() { throw new Exception(message = "hello you see") } - } - - program p { - const a = new A() - - try { - a.m2() - assert.fail("Should have thrown message not understood") - } - catch e : MessageNotUnderstoodException { - // ok ! - assert.equals("a A[] does not understand m2()", e.message()) - } - } - '''.interpretPropagatingErrors - - // TODO: we need to add tests for the stacktrace generation. I'm not able to match the expected - // actual stack trace string e.getStackTraceAsString() - } - - @Test - def void testMessageNotUnderstoodHowever1() { - ''' - class A { - method m1(a) { return a + 1 } - } - - program p { - const a = new A() - - try { - a.m1() - assert.fail("Should have thrown message not understood") - } - catch e : MessageNotUnderstoodException { - // ok ! - assert.equals("a A[] does not understand m1(). However other methods exist with different argument count: m1(a)", e.message()) - } - } - '''.interpretPropagatingErrors - - // TODO: we need to add tests for the stacktrace generation. I'm not able to match the expected - // actual stack trace string e.getStackTraceAsString() - } - - @Test - def void testMessageNotUnderstoodCaseSensitive() { - ''' - class A { - method m1(a) { return a + 1 } - } - - program p { - const a = new A() - - try { - a.M1(3) - assert.fail("Should have thrown message not understood") - } - catch e : MessageNotUnderstoodException { - // ok ! - assert.equals("a A[] does not understand M1(param1). However other similar methods exist: m1(a)", e.message()) -// assert.equals("Wrong case-sensitive message M1(param1) sent to a A[]. Use m1(a)", e.message()) - } - } - '''.interpretPropagatingErrors - - // TODO: we need to add tests for the stacktrace generation. I'm not able to match the expected - // actual stack trace string e.getStackTraceAsString() - } - - @Test - def void testMessageNotUnderstoodHowever2() { - ''' - class A { - method m1(a) { return a + 1 } - } - - program p { - const a = new A() - - try { - a.m1(2, new Date()) - assert.fail("Should have thrown message not understood") - } - catch e : MessageNotUnderstoodException { - // ok ! - assert.equals("a A[] does not understand m1(param1, param2). However other methods exist with different argument count: m1(a)", e.message()) - } - } - '''.interpretPropagatingErrors - - // TODO: we need to add tests for the stacktrace generation. I'm not able to match the expected - // actual stack trace string e.getStackTraceAsString() - } - - @Test - def void testMessageNotUnderstoodWithLiteralsHowever() { - ''' - program p { - try { - 4.truncate() - assert.fail("Should have thrown message not understood") - } - catch e : MessageNotUnderstoodException { - // ok ! - assert.equals("4 does not understand truncate(). However other methods exist with different argument count: truncate(_decimals)", e.message()) - } - } - '''.interpretPropagatingErrors - - // TODO: we need to add tests for the stacktrace generation. I'm not able to match the expected - // actual stack trace string e.getStackTraceAsString() - } - - @Test - def void testMessageNotUnderstoodWithLiteralsCaseSensitive() { - ''' - program p { - try { - 4.truncATE(2) - assert.fail("Should have thrown message not understood") - } - catch e : MessageNotUnderstoodException { - // ok ! - assert.equals("4 does not understand truncATE(param1). However other similar methods exist: truncate(_decimals)", e.message()) - } - } - '''.interpretPropagatingErrors - - // TODO: we need to add tests for the stacktrace generation. I'm not able to match the expected - // actual stack trace string e.getStackTraceAsString() - } - - @Test - def void testMessageNotUnderstoodWithParams() { - ''' - class A { - method m1() { throw new Exception(message = "hello you see") } - } - - program p { - const a = new A() - - try { - a.m2(2, 4) - assert.fail("Should have thrown message not understood") - } - catch e : MessageNotUnderstoodException { - // ok ! - assert.equals("a A[] does not understand m2(param1, param2)", e.message()) - } - } - '''.interpretPropagatingErrors - } - - @Test - def void testCatchWithoutType() { - ''' - class A { - method m1() { throw new Exception(message = "hello you see") } - } - - program p { - const a = new A() - - try { - a.m1() - assert.fail("Should have thrown exception") - } - catch e { - // ok ! - assert.equals("hello you see", e.message()) - } - } - '''.interpretPropagatingErrors - } - - @Test - def void testMultipleMatchingCatchesWillOnlyExecuteTheFirstOne() { - ''' - class AException inherits wollok.lang.Exception {} - class BException inherits AException {} - class CException inherits wollok.lang.Exception {} - - class A { - method m1() { throw new BException(message = "hello you see") } - } - - program p { - const a = new A() - - try { - a.m1() - assert.fail("Should have thrown exception") - } - catch e : BException { - // OK ! - } - catch e : AException { - assert.fail("incorrenct catch !") - } - catch e { - assert.fail("incorrenct catch !") - } - } - '''.interpretPropagatingErrors - } - - @Test - def void testCatchWithoutTypeMatchingJustTheFirstCatch() { - ''' - class AException inherits wollok.lang.Exception {} - class BException inherits wollok.lang.Exception {} - - class A { - method m1() { throw new AException(message = "hello you see") } - } - - program p { - const a = new A() - - try { - a.m1() - assert.fail("Should have thrown exception") - } - catch e : AException { - // OK ! - } - catch e : BException { - assert.fail("incorrenct catch !") - } - catch e { - assert.fail("incorrenct catch !") - } - } - '''.interpretPropagatingErrors - } - - @Test - def void testCatchWithoutTypeMatchingJustTheSecondCatch() { - ''' - class AException inherits wollok.lang.Exception {} - class BException inherits wollok.lang.Exception {} - - class A { - method m1() { throw new BException(message = "hello you see") } - } - - program p { - const a = new A() - - try { - a.m1() - assert.fail("Should have thrown exception") - } - catch e : AException { - assert.fail("incorrenct catch !") - } - catch e : BException { - // OK ! - } - catch e { - assert.fail("incorrect catch !") - } - } - '''.interpretPropagatingErrors - } - - @Test - def void testCatchWithoutTypeMatchingTheLastCatch() { - ''' - class AException inherits wollok.lang.Exception {} - class BException inherits wollok.lang.Exception {} - class CException inherits wollok.lang.Exception {} - - class A { - method m1() { throw new CException(message = "hello you see") } - } - - program p { - const a = new A() - - try { - a.m1() - assert.fail("Should have thrown exception") - } - catch e : AException { - assert.fail("incorrect catch !") - } - catch e : BException { - assert.fail("incorrect catch !") - } - catch e { - // OK ! - } - } - '''.interpretPropagatingErrors - } - - @Test - def void testExceptionFromNativeMethodGetsWrappedIntoAWollokException() { - ''' - program p { - try { - console.println(2 / 0) - } - catch e : Exception { - // OK ! - e.printStackTrace() - } - } - '''.interpretPropagatingErrors - } - @Test def void testErrorMethodOnWollokObject() { ''' @@ -488,47 +20,14 @@ class ExceptionTestCase extends AbstractWollokInterpreterTestCase { } } program p { - const f = new C() try { + const f = new C() f.foo() } catch e { // OK ! assert.equals("Gently failing!", e.message()) - assert.equals(f, e.source()) - } - } - '''.interpretPropagatingErrors - } - - @Test - def void testExceptionWithMessage(){ - ''' - class UserException inherits wollok.lang.Exception { - var property valorInvalido = 0 - } - - object monedero { - var plata = 500 - - method plata() = return plata - - method poner(cantidad) { - if (cantidad < 0) { - throw new UserException(message = "La cantidad debe ser positiva", valorInvalido = cantidad) - } - plata += cantidad - } - - method sacar(cantidad) { plata -= cantidad } - } - - program p { - try{ - monedero.poner(-2) - assert.fail('No should get here') - } catch e { - assert.equals("La cantidad debe ser positiva", e.message()) + // assert.equals(f, e.source()) } } '''.interpretPropagatingErrors diff --git a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/numbers/CollectionsMinMaxTest.xtend b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/numbers/CollectionsMinMaxTest.xtend deleted file mode 100644 index b7c3632c72..0000000000 --- a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/numbers/CollectionsMinMaxTest.xtend +++ /dev/null @@ -1,47 +0,0 @@ -package org.uqbar.project.wollok.tests.interpreter.numbers - -import org.junit.Test -import org.uqbar.project.wollok.tests.interpreter.AbstractWollokInterpreterTestCase - -class CollectionsMinMaxTest extends AbstractWollokInterpreterTestCase { - - @Test - def void testMin() { - ''' - object x1 { - method value(){ return 1 } - } - object x2 { - method value(){ return 2 } - } - object x3 { - method value(){ return 3 } - } - - program a { - assert.equals(x1, [x1, x2, x3].min{ o => o.value()}) - } - ''' - .interpretPropagatingErrors - } - - @Test - def void testMax() { - ''' - object x1 { - method value(){ return 1 } - } - object x2 { - method value(){ return 2 } - } - object x3 { - method value(){ return 3 } - } - - program a { - assert.equals(x3, [x1, x2, x3].max{ o => o.value()}) - } - ''' - .interpretPropagatingErrors - } -} diff --git a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/sanityTests/SanityTestCase.xtend b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/sanityTests/SanityTestCase.xtend index 36d3aaca38..040349677f 100644 --- a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/sanityTests/SanityTestCase.xtend +++ b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/sanityTests/SanityTestCase.xtend @@ -3,51 +3,53 @@ package org.uqbar.project.wollok.tests.sanityTests import java.io.File import java.nio.file.Files import java.nio.file.Paths -import java.util.Map +import java.time.format.DateTimeFormatter +import org.eclipse.xtext.testing.InjectWith +import org.eclipse.xtext.testing.XtextRunner import org.junit.Test +import org.junit.runner.RunWith +import org.uqbar.project.wollok.tests.injectors.WollokSanityTestInjectorProvider import org.uqbar.project.wollok.tests.interpreter.AbstractWollokInterpreterTestCase +import wollok.lang.WDate import static org.uqbar.project.wollok.WollokConstants.* +import static wollok.lang.WDate.* + +import static extension org.uqbar.project.wollok.utils.StringUtils.* /** * Executes Sanity Tests from wollok-language * + * Prints output in the console without colors + * Succeeds if no files have errors. Looks for all .wtest files in sibling wollok-language folder. + * * @author dodain */ +@RunWith(XtextRunner) +@InjectWith(WollokSanityTestInjectorProvider) class SanityTestCase extends AbstractWollokInterpreterTestCase { val path = "../wollok-language/test/sanity" @Test def void run() { - val Map allErrors = newHashMap - // TODO: Meter Logger.log - println(''' - =================================================================================== - BEGIN SANITY TESTS - =================================================================================== - ''') + // TODO: We should find a better way instead of forcing locale + WDate.FORMATTER = DateTimeFormatter.ofPattern("M/d/yyyy") + + val failed = newArrayList Files.walk(Paths.get(path)) .filter([ path | !Files.isDirectory(path) && path.toString.endsWith(TEST_EXTENSION) ]) .forEach [ file | try { new File(file.toString).interpretPropagatingErrors(false) - println('''√ OK «file»''') - } catch (AssertionError e) { - allErrors.put(file.toString, e) - println( - ''' - ✗ ERRORED «file» - «e.message» - ''' - ) + } catch (Exception e) { + failed.add(file.toString) } ] - println(''' - =================================================================================== - END SANITY TESTS - =================================================================================== - ''') - assertEquals(newHashMap, allErrors) + assertTrue(''' + There were «failed.size.singularOrPlural("file", "files")» with errors in the sanity tests. + Check your log for details. + «failed.join("\n")» + ''', failed.isEmpty) } } diff --git a/org.uqbar.project.wollok/src/org/uqbar/project/wollok/errorHandling/WollokExceptionExtensions.xtend b/org.uqbar.project.wollok/src/org/uqbar/project/wollok/errorHandling/WollokExceptionExtensions.xtend index 91ed9b1d1f..0753c71e54 100644 --- a/org.uqbar.project.wollok/src/org/uqbar/project/wollok/errorHandling/WollokExceptionExtensions.xtend +++ b/org.uqbar.project.wollok/src/org/uqbar/project/wollok/errorHandling/WollokExceptionExtensions.xtend @@ -6,9 +6,11 @@ import org.uqbar.project.wollok.Messages import org.uqbar.project.wollok.interpreter.WollokInterpreterException import org.uqbar.project.wollok.interpreter.core.WollokObject import org.uqbar.project.wollok.interpreter.core.WollokProgramExceptionWrapper + +import static org.uqbar.project.wollok.sdk.WollokSDK.* + import static extension org.uqbar.project.wollok.interpreter.nativeobj.WollokJavaConversions.* import static extension org.uqbar.project.wollok.ui.utils.XTendUtilExtensions.* -import static org.uqbar.project.wollok.sdk.WollokSDK.* /** * Extension methods for handling Wollok errors. @@ -220,6 +222,9 @@ class WollokExceptionExtensions { def static dispatch shouldShowStackTraceInJava(WollokProgramExceptionWrapper e) { false } def static dispatch shouldShowStackTraceInJava(WollokInterpreterException e) { false } - def static dispatch shouldShowStackTraceInJava(Throwable t) { true } + def static dispatch shouldShowStackTraceInJava(Throwable t) { + // !t.class.name.equals(ASSERTION_EXCEPTION_FQN) + true + } } diff --git a/org.uqbar.project.wollok/src/org/uqbar/project/wollok/utils/StringUtils.xtend b/org.uqbar.project.wollok/src/org/uqbar/project/wollok/utils/StringUtils.xtend index 8f4f759351..9d79ef919c 100644 --- a/org.uqbar.project.wollok/src/org/uqbar/project/wollok/utils/StringUtils.xtend +++ b/org.uqbar.project.wollok/src/org/uqbar/project/wollok/utils/StringUtils.xtend @@ -56,11 +56,11 @@ class StringUtils { } static def singularOrPlural(int amount, String text) { - "" + amount + " " + amount.singularOrPlural(text, text + "s") - } + amount.singularOrPlural(text, text + "s") + } static def singularOrPlural(int amount, String text, String pluralText) { - if (amount === 1) text else pluralText + "" + amount + " " + if (amount === 1) text else pluralText } - + } From 722fc9567b79107deca634f77ef8130644f358b2 Mon Sep 17 00:00:00 2001 From: ivan Date: Mon, 28 Oct 2019 14:07:58 -0300 Subject: [PATCH 069/133] tests for errors that dont depend on starting the game --- .../project/wollok/game/messages.properties | 2 +- .../src/wollok/game.wlk | 10 ++-- .../project/wollok/tests/sdk/GameTest.xtend | 46 +++++++++++++++++++ 3 files changed, 52 insertions(+), 6 deletions(-) diff --git a/org.uqbar.project.wollok.game/src/org/uqbar/project/wollok/game/messages.properties b/org.uqbar.project.wollok.game/src/org/uqbar/project/wollok/game/messages.properties index be1945e91d..3e50e66110 100644 --- a/org.uqbar.project.wollok.game/src/org/uqbar/project/wollok/game/messages.properties +++ b/org.uqbar.project.wollok.game/src/org/uqbar/project/wollok/game/messages.properties @@ -10,7 +10,7 @@ WollokGame_PausedANotPlayedSound = You cannot pause a sound that hasn't been pla WollokGame_SoundAlreadyPaused = You cannot pause or resume a sound that's already paused. WollokGame_VolumeOutOfRange = Volume value must be between 0 and 1. WollokGame_SoundAlreadyPlaying = You cannot resume a sound if that isn't paused. -WollokGame_SoundNotYetPlayed = You cannot stop a sound that hasn't been played yet. +WollokGame_SoundNotYetPlayed = You cannot stop a sound that hasn't been played. WollokGame_CharacterKeyNotFound = Character key [{0}] not found. WollokGame_ListenerNotFound = There is no tick event called {0}. diff --git a/org.uqbar.project.wollok.lib/src/wollok/game.wlk b/org.uqbar.project.wollok.lib/src/wollok/game.wlk index 5bf8cb2d0c..ec094be4d3 100644 --- a/org.uqbar.project.wollok.lib/src/wollok/game.wlk +++ b/org.uqbar.project.wollok.lib/src/wollok/game.wlk @@ -493,13 +493,13 @@ class Sound { /** * Pauses the sound. - * Throws exception if the sound is already paused or if the sound hasn't been played yet. + * Throws error if the sound is already paused or if the sound hasn't been played yet. */ method pause() native /** * Resumes playing the sound. - * Throws exception if the sound is not paused. + * Throws error if the sound is not paused. */ method resume() native @@ -511,9 +511,9 @@ class Sound { /** * Changes absolute volume, values must be between 0 and 1. * - * Examples: - * mySound.volume(0.5) New volume is half of the original sound's volume - * mySound.volume(mySound.volume()*0.5) New volume is half of the current volume + * Examples + *#mySound.volume(0.5) => New volume is half of the original sound's volume + *#mySound.volume(mySound.volume()*0.5) => New volume is half of the current volume */ method volume(newVolume) native diff --git a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/sdk/GameTest.xtend b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/sdk/GameTest.xtend index bec46b7e0b..20e882c4d5 100644 --- a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/sdk/GameTest.xtend +++ b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/sdk/GameTest.xtend @@ -187,6 +187,52 @@ class GameTest extends AbstractWollokInterpreterTestCase { '''.interpretPropagatingErrors } + @Test + def void volumeCantBeHigherThan1() { + ''' + assert.throwsExceptionWithMessage("Volume value must be between 0 and 1.", { => sound.volume(2.5) }) + '''.soundTest + } + + @Test + def void volumeCantBeLowerThan0() { + ''' + assert.throwsExceptionWithMessage("Volume value must be between 0 and 1.", { => sound.volume(-3) }) + '''.soundTest + } + + @Test + def void soundCantBePlayedIfGameHasntBeenStarted() { + ''' + assert.throwsExceptionWithMessage("You cannot play sounds until the game has started. Try using it inside an onTick / onPressDo block.", { => sound.play() }) + '''.soundTest + } + + @Test + def void soundCantBePausedIfItHasntBePlayed() { + ''' + assert.throwsExceptionWithMessage("You cannot pause a sound that hasn't been played.", { => sound.pause() }) + '''.soundTest + } + + @Test + def void soundCantBeStoppedIfItHasntBeenPlayed() { + ''' + assert.throwsExceptionWithMessage("You cannot stop a sound that hasn't been played.", { => sound.stop() }) + '''.soundTest + } + + def soundTest(CharSequence test) { + ''' + import wollok.game.* + + program a { + var sound = game.sound("testSound.mp3") + «test» + } + '''.interpretPropagatingErrors + } + def gameTest(CharSequence test) { ''' import wollok.game.* From dfdbbcc8a16b640357a264f525ee18fbb6fdd5e9 Mon Sep 17 00:00:00 2001 From: ivan Date: Mon, 28 Oct 2019 15:06:15 -0300 Subject: [PATCH 070/133] Fixed type declarations and descriptions --- .../src/org/uqbar/project/wollok/game/Messages.java | 2 +- .../project/wollok/game/gameboard/GameSound.xtend | 10 +++++----- .../org/uqbar/project/wollok/game/messages.properties | 8 ++++---- .../uqbar/project/wollok/game/messages_es.properties | 4 ++-- org.uqbar.project.wollok.lib/src/wollok/game.wlk | 10 ++++++---- .../org/uqbar/project/wollok/tests/sdk/GameTest.xtend | 2 +- .../annotations/WollokGameTypeDeclarations.xtend | 6 ++++-- 7 files changed, 23 insertions(+), 19 deletions(-) diff --git a/org.uqbar.project.wollok.game/src/org/uqbar/project/wollok/game/Messages.java b/org.uqbar.project.wollok.game/src/org/uqbar/project/wollok/game/Messages.java index 16b14eb4bb..5c764297b0 100644 --- a/org.uqbar.project.wollok.game/src/org/uqbar/project/wollok/game/Messages.java +++ b/org.uqbar.project.wollok.game/src/org/uqbar/project/wollok/game/Messages.java @@ -13,7 +13,7 @@ public class Messages extends NLS { public static String WollokGame_SoundGameNotStarted; public static String WollokGame_SoundAlreadyPlayed; - public static String WollokGame_PausedANotPlayedSound; + public static String WollokGame_PausedOrResumedANotPlayedSound; public static String WollokGame_SoundAlreadyPaused; public static String WollokGame_VolumeOutOfRange; public static String WollokGame_SoundAlreadyPlaying; diff --git a/org.uqbar.project.wollok.game/src/org/uqbar/project/wollok/game/gameboard/GameSound.xtend b/org.uqbar.project.wollok.game/src/org/uqbar/project/wollok/game/gameboard/GameSound.xtend index 5e157d9c40..cfe4cac60e 100644 --- a/org.uqbar.project.wollok.game/src/org/uqbar/project/wollok/game/gameboard/GameSound.xtend +++ b/org.uqbar.project.wollok.game/src/org/uqbar/project/wollok/game/gameboard/GameSound.xtend @@ -18,7 +18,7 @@ class GameSound { def play() { if (played) throw new RuntimeException(Messages.WollokGame_SoundAlreadyPlayed) - if (looped) + if (!looped) soundID = fetchSound.play(volume) else soundID = fetchSound.loop(volume) @@ -37,7 +37,7 @@ class GameSound { def pause() { if (!played) - throw new RuntimeException(Messages.WollokGame_PausedANotPlayedSound) + throw new RuntimeException(Messages.WollokGame_PausedOrResumedANotPlayedSound) if (paused) throw new RuntimeException(Messages.WollokGame_SoundAlreadyPaused) fetchSound.pause() @@ -46,7 +46,7 @@ class GameSound { def resume() { if (!played) - throw new RuntimeException(Messages.WollokGame_PausedANotPlayedSound) + throw new RuntimeException(Messages.WollokGame_PausedOrResumedANotPlayedSound) if (!paused) throw new RuntimeException(Messages.WollokGame_SoundAlreadyPlaying) fetchSound.resume() @@ -69,7 +69,7 @@ class GameSound { } def syncVolume() { - if (played()) { + if (played) { fetchSound.setVolume(soundID, volume) } } @@ -84,7 +84,7 @@ class GameSound { } def syncLoop() { - if (played()) { + if (played) { fetchSound.setLooping(soundID, looped) } } diff --git a/org.uqbar.project.wollok.game/src/org/uqbar/project/wollok/game/messages.properties b/org.uqbar.project.wollok.game/src/org/uqbar/project/wollok/game/messages.properties index 3e50e66110..1cedebac1f 100644 --- a/org.uqbar.project.wollok.game/src/org/uqbar/project/wollok/game/messages.properties +++ b/org.uqbar.project.wollok.game/src/org/uqbar/project/wollok/game/messages.properties @@ -5,11 +5,11 @@ WollokGame_NoMessage = NO MESSAGE WollokGame_ObjectAlreadyInGame = {0} is already in the game. WollokGame_SoundGameNotStarted = You cannot play sounds until the game has started. Try using it inside an onTick / onPressDo block. -WollokGame_SoundAlreadyPlayed = You cannot play a sound more than once. -WollokGame_PausedANotPlayedSound = You cannot pause a sound that hasn't been played. -WollokGame_SoundAlreadyPaused = You cannot pause or resume a sound that's already paused. +WollokGame_SoundAlreadyPlayed = You can only play a sound once. +WollokGame_PausedOrResumedANotPlayedSound = You cannot pause or resume a sound that hasn't been played. +WollokGame_SoundAlreadyPaused = You cannot pause a sound that's already paused. WollokGame_VolumeOutOfRange = Volume value must be between 0 and 1. -WollokGame_SoundAlreadyPlaying = You cannot resume a sound if that isn't paused. +WollokGame_SoundAlreadyPlaying = You cannot resume a sound that isn't paused. WollokGame_SoundNotYetPlayed = You cannot stop a sound that hasn't been played. WollokGame_CharacterKeyNotFound = Character key [{0}] not found. diff --git a/org.uqbar.project.wollok.game/src/org/uqbar/project/wollok/game/messages_es.properties b/org.uqbar.project.wollok.game/src/org/uqbar/project/wollok/game/messages_es.properties index 4d750666ee..4f06d211d0 100644 --- a/org.uqbar.project.wollok.game/src/org/uqbar/project/wollok/game/messages_es.properties +++ b/org.uqbar.project.wollok.game/src/org/uqbar/project/wollok/game/messages_es.properties @@ -5,8 +5,8 @@ WollokGame_NoMessage = FALTA MENSAJE WollokGame_ObjectAlreadyInGame = {0} ya se encuentra en el juego. WollokGame_SoundGameNotStarted = No se puede pedir un sonido hasta que el juego comience. Pruebe definirlo dentro de un bloque onTick / onPressDo. -WollokGame_SoundAlreadyPlayed = No se puede reproducir un sonido mas de una vez. -WollokGame_PausedANotPlayedSound = No se puede pausar o resumir un sonido si no esta reprudiciendose. +WollokGame_SoundAlreadyPlayed = Un sonido solo se puede reproducir una vez. +WollokGame_PausedOrResumedANotPlayedSound = No se puede pausar o resumir un sonido si no esta reproduciendose. WollokGame_SoundAlreadyPaused = No se puede pausar un sonido si este ya esta pausado. WollokGame_VolumeOutOfRange = El valor del volumen debe estar entre 0 y 1. WollokGame_SoundAlreadyPlaying = No se puede resumir un sonido que no esta pausado. diff --git a/org.uqbar.project.wollok.lib/src/wollok/game.wlk b/org.uqbar.project.wollok.lib/src/wollok/game.wlk index ec094be4d3..10d9cc48f7 100644 --- a/org.uqbar.project.wollok.lib/src/wollok/game.wlk +++ b/org.uqbar.project.wollok.lib/src/wollok/game.wlk @@ -477,7 +477,8 @@ class Sound { const property file /** - * Plays the file's sound. A sound can't be played more than once. + * Plays the file's sound. + * A sound can only be played once. */ method play() native @@ -512,8 +513,9 @@ class Sound { * Changes absolute volume, values must be between 0 and 1. * * Examples - *#mySound.volume(0.5) => New volume is half of the original sound's volume - *#mySound.volume(mySound.volume()*0.5) => New volume is half of the current volume + * mySound.volume(0) => The sound is now muted. + * mySound.volume(0.5) => New volume is half of the original sound's volume + * mySound.volume(mySound.volume()*0.5) => New volume is half of the current volume */ method volume(newVolume) native @@ -523,7 +525,7 @@ class Sound { method volume() native /** - * Whether the sound is set to loop or not. + * Sets whether the sound should loop or not. */ method shouldLoop(looping) native diff --git a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/sdk/GameTest.xtend b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/sdk/GameTest.xtend index 20e882c4d5..38f52545a5 100644 --- a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/sdk/GameTest.xtend +++ b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/sdk/GameTest.xtend @@ -211,7 +211,7 @@ class GameTest extends AbstractWollokInterpreterTestCase { @Test def void soundCantBePausedIfItHasntBePlayed() { ''' - assert.throwsExceptionWithMessage("You cannot pause a sound that hasn't been played.", { => sound.pause() }) + assert.throwsExceptionWithMessage("You cannot pause or resume a sound that hasn't been played.", { => sound.pause() }) '''.soundTest } diff --git a/org.uqbar.project.wollok.typeSystem/src/org/uqbar/project/wollok/typesystem/annotations/WollokGameTypeDeclarations.xtend b/org.uqbar.project.wollok.typeSystem/src/org/uqbar/project/wollok/typesystem/annotations/WollokGameTypeDeclarations.xtend index 57eedab2b1..5bae9d11a7 100644 --- a/org.uqbar.project.wollok.typeSystem/src/org/uqbar/project/wollok/typesystem/annotations/WollokGameTypeDeclarations.xtend +++ b/org.uqbar.project.wollok.typeSystem/src/org/uqbar/project/wollok/typesystem/annotations/WollokGameTypeDeclarations.xtend @@ -64,11 +64,13 @@ class WollokGameTypeDeclarations extends TypeDeclarations { Sound.variable("file",String) Sound.fakeProperty("volume",Number) + Sound.fakeProperty("shouldLoop",Boolean) Sound >> "play" === #[] => Void + Sound >> "played" === #[] => Boolean Sound >> "stop" === #[] => Void Sound >> "pause" === #[] => Void - Sound >> "loop" === #[] => Void - + Sound >> "isPaused" === #[] => Boolean + Sound >> "resume" === #[] => Void Key >> "onPressDo" === #[closure(#[], Void)] => Void } From 572e70873562fa68446c32a835cc6fc0b0df678c Mon Sep 17 00:00:00 2001 From: Fernando Dodino Date: Mon, 28 Oct 2019 22:56:33 -0300 Subject: [PATCH 071/133] Fixing wollok examples test --- .../tests/interpreter/ExceptionTestCase.xtend | 115 ------------------ .../src/wollok/classes/natives/MyNative.class | Bin 0 -> 320 bytes .../src/wollok/classes/natives/MyNative.java | 0 .../natives/DefaultNativeObjectFactory.xtend | 8 +- wollok-tests/META-INF/MANIFEST.MF | 2 - .../src/basic/10_collection_literals.wpgm | 95 +++++++-------- .../src/basic/1_variables_and_numbers.wpgm | 16 +-- wollok-tests/src/basic/6_custom_toString.wpgm | 11 +- wollok-tests/src/bugs/b40.wlk | 1 - wollok-tests/src/bugs/b44.wtest | 8 +- wollok-tests/src/bugs/recursiveToString.wpgm | 2 +- .../src/wollok/classes/basics/simpleClass.wlk | 2 +- .../classes/basics/simpleClass_program.wpgm | 2 +- .../basics/simpleInheritance_program.wpgm | 9 +- .../src/wollok/classes/mixins/mixins.wtest | 13 +- .../classes/natives/sample_program.wpgm | 6 + .../src/wollok/classes/natives/wollok.wlk | 1 - .../classes/natives/wollok/MyNative.class | Bin 0 -> 320 bytes .../classes/natives/wollok/MyNative.java | 12 ++ .../src/wollok/debugger/withClasses.wpgm | 1 - .../examples/monstersinc/monstersInc.wtest | 4 +- .../examples/monstersinc/workspace.wpgm | 6 +- .../src/wollok/examples/trenes/trenes.wlk | 11 +- .../src/wollok/examples/trenes/workspace.wpgm | 70 +++++------ 24 files changed, 126 insertions(+), 269 deletions(-) delete mode 100644 org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/ExceptionTestCase.xtend create mode 100644 org.uqbar.project.wollok.tests/src/wollok/classes/natives/MyNative.class rename {wollok-tests => org.uqbar.project.wollok.tests}/src/wollok/classes/natives/MyNative.java (100%) create mode 100644 wollok-tests/src/wollok/classes/natives/wollok/MyNative.class create mode 100644 wollok-tests/src/wollok/classes/natives/wollok/MyNative.java diff --git a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/ExceptionTestCase.xtend b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/ExceptionTestCase.xtend deleted file mode 100644 index ab181e7bef..0000000000 --- a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/ExceptionTestCase.xtend +++ /dev/null @@ -1,115 +0,0 @@ -package org.uqbar.project.wollok.tests.interpreter - -import org.junit.Test -import org.uqbar.project.wollok.interpreter.core.WollokObject -import static extension org.uqbar.project.wollok.interpreter.nativeobj.WollokJavaConversions.* - -/** - * Tests wollok exceptions handling mechanism. - * - * @author jfernandes - */ -class ExceptionTestCase extends AbstractWollokInterpreterTestCase { - - @Test - def void testErrorMethodOnWollokObject() { - ''' - class C { - method foo() { - self.error("Gently failing!") - } - } - program p { - try { - const f = new C() - f.foo() - } - catch e { - // OK ! - assert.equals("Gently failing!", e.message()) - // assert.equals(f, e.source()) - } - } - '''.interpretPropagatingErrors - } - - @Test - def void testCatchWithAReturnStatement() { - ''' - object cuenta { - method sacar() { - try { - throw new Exception(message = "saldo insuficiente") - } - catch e { - return 20 - } - } - } - program p { - assert.equals(20, cuenta.sacar()) - }'''.interpretPropagatingErrors - } - - @Test - def void testCatchWithAReturnStatementReturningFromTryBodyAndFromCatch() { - ''' - object cuenta { - method sacar(c) { - try { - if (c > 0) - throw new Exception(message = "saldo insuficiente") - return 19 - } - catch e { - return 20 - } - } - } - program p { - assert.equals(20, cuenta.sacar(10)) - assert.equals(19, cuenta.sacar(0)) - }'''.interpretPropagatingErrors - } - - @Test - def void testCatchEvaluationInAShortCutMethod() { - ''' - object cuenta { - method sacar(c) = try { - if (c > 0) - throw new Exception(message = "saldo insuficiente") - else 19 - } catch e { - 20 - } - } - program p { - assert.equals(20, cuenta.sacar(10)) - assert.equals(19, cuenta.sacar(0)) - }'''.interpretPropagatingErrors - } - - @Test - def void assertThrowsExceptionFailing() { - ''' - var a = 0 - assert.throwsExceptionLike( - new AssertionException(message = "Block { a + 1 } should have failed"), - { assert.throwsException({ a + 1 }) } - ) - '''.test - } - - @Test - def void testCanCreateExceptionUsingNamedParametersWithoutCause() { - ''' - object unObjeto { - method prueba() { - throw new Exception(message = "Saraza") - } - } - '''.interpretPropagatingErrors - } - -} \ No newline at end of file diff --git a/org.uqbar.project.wollok.tests/src/wollok/classes/natives/MyNative.class b/org.uqbar.project.wollok.tests/src/wollok/classes/natives/MyNative.class new file mode 100644 index 0000000000000000000000000000000000000000..ee229f65e1e298ada6e9aacb9630ab43fbfb0637 GIT binary patch literal 320 zcmYjM!A`8jjDMvk6AyfVA7z}S zF*=9$X5PG+$$Wi(?f_ilC`1jNCJqC11M~=uvCegQOYn!ICqnJcESS)p=$vPpbswh)=8qLc>=jjb0oSRLN@V(y8Okb;^E9Y#Zjt1eh zlKM-|GSgqPwJPNS;o`-J@Ej$XvX*U>@6XxjcL$;OckdxyaZ+LcU*2)yf!un*K&o?L m60To n > 18})) -self.assertFalse([20, 22, 34].forAll({n => n > 30})) - -// forEach -const vaca1 = object { - var peso = 1000 - method engordar(cuanto) { - peso = peso + cuanto + const numbers = [2, 23, 25] + + const y = 23 + const z = 2.2 + + const x = "Hola" + const bag = [x,y,z] + + // *************************** + // ** calling native methods + // *************************** + + // size (a forwarded message to java.util.List) + assert.equals(3, numbers.size()) + assert.that(numbers.contains(23)) + assert.notThat(numbers.contains(1)) + + // all + assert.that([20, 22, 34].all({n => n > 18})) + assert.notThat([20, 22, 34].all({n => n > 30})) + + // forEach + const vaca1 = object { + var peso = 1000 + method engordar(cuanto) { + peso = peso + cuanto + } + method peso() = peso } - method peso() = peso -} -const vaca2 = object { - var peso = 1000 - method engordar(cuanto) { - peso = peso + cuanto + const vaca2 = object { + var peso = 1000 + method engordar(cuanto) { + peso = peso + cuanto + } + method peso() = peso } - method peso() = peso -} -const vacas = [vaca1, vaca2] - -vacas.forEach{v => v.engordar(2)} -assert.that(vacas.forAll{v => v.peso() == 1002}) + const vacas = [vaca1, vaca2] -// map -const mapped = vacas.map{v => v.peso()} -assert.that(mapped.forAll{p => p == 1002}) + vacas.forEach{v => v.engordar(2)} + assert.that(vacas.all{v => v.peso() == 1002}) + // map + const mapped = vacas.map{v => v.peso()} + assert.that(mapped.all{p => p == 1002}) -// filter -const r = [10, 20, 30, 40, 50].filter{n=> n > 30} -assert.that(r.size() == 2) -assert.that(r.contains(40)) -assert.that(r.contains(50)) + // filter + const r = [10, 20, 30, 40, 50].filter{n=> n > 30} + assert.that(r.size() == 2) + assert.that(r.contains(40)) + assert.that(r.contains(50)) } \ No newline at end of file diff --git a/wollok-tests/src/basic/1_variables_and_numbers.wpgm b/wollok-tests/src/basic/1_variables_and_numbers.wpgm index 9444ef82e1..8c09e3e66e 100644 --- a/wollok-tests/src/basic/1_variables_and_numbers.wpgm +++ b/wollok-tests/src/basic/1_variables_and_numbers.wpgm @@ -12,31 +12,21 @@ program variablesAndNumbers { var c = 23 c = 24 //OK! - /* - * asdasd - */ - assert.that(b == 24) assert.that(10 - 5 == 5) assert.that(10 * a == 230) assert.that(100 / 10 == 10) assert.that(100 % 10 == 0) - assert.that(2 ** 3 == 8.0) - assert.equals(8.0, 2**3) - + assert.that(2 ** 4 == 16.0) + assert.equals(16.0, 2**4) + assert.that(2 * 2.0 == 2.0 * 2) assert.that(2 + 2.0 == 2.0 + 2) - assert.that("Hola" * 3 == "HolaHolaHola") - assert.that(3 * "Hola" == "HolaHolaHola") - assert.equals(0 - 1, -1) assert.equals(0 - 4, -4) - assert.that("Hola Mundo" - 6 == "Hola") - assert.that("Juan Jose Juan Pepe" - "Juan" == " Jose Pepe") - var d = 1 d++ assert.equals(2, d) diff --git a/wollok-tests/src/basic/6_custom_toString.wpgm b/wollok-tests/src/basic/6_custom_toString.wpgm index 8334b4b5b5..3ff6e76ee9 100644 --- a/wollok-tests/src/basic/6_custom_toString.wpgm +++ b/wollok-tests/src/basic/6_custom_toString.wpgm @@ -1,12 +1,11 @@ program customToString { -const pepe = object { - override method toString() { - return 'Pepe' + const pepe = object { + override method toString() { + return 'Pepe' + } } -} -console.println(pepe) -assert.that(pepe.toString() == 'Pepe') + assert.equals(pepe.toString(), 'Pepe') } \ No newline at end of file diff --git a/wollok-tests/src/bugs/b40.wlk b/wollok-tests/src/bugs/b40.wlk index f667ec0546..e6e3ea98b4 100644 --- a/wollok-tests/src/bugs/b40.wlk +++ b/wollok-tests/src/bugs/b40.wlk @@ -13,7 +13,6 @@ object pajarera { object pepe { method sosMenor(energiaMenor){ - console.println("") pajarera.setEnergiaMenor(10) } } diff --git a/wollok-tests/src/bugs/b44.wtest b/wollok-tests/src/bugs/b44.wtest index e606323ff3..cfc12b2ffd 100644 --- a/wollok-tests/src/bugs/b44.wtest +++ b/wollok-tests/src/bugs/b44.wtest @@ -1,7 +1,7 @@ -test "Testing regretion of Bug #44" { - const aList = [ 1, 2, 3, 4] - const clone = aList.clone() +test "Testing regression of Bug #44" { + const aList = [ 1, 2, 3, 4 ] + const clone = aList.copy() - assert.equals(aList.getClass(), clone.getClass()) + assert.equals(aList.className(), clone.className()) } \ No newline at end of file diff --git a/wollok-tests/src/bugs/recursiveToString.wpgm b/wollok-tests/src/bugs/recursiveToString.wpgm index fe065c314c..420c2e154d 100644 --- a/wollok-tests/src/bugs/recursiveToString.wpgm +++ b/wollok-tests/src/bugs/recursiveToString.wpgm @@ -21,5 +21,5 @@ program a { obj2.setY(obj1) obj1.addX(new Prb()) - assert.equals('obj2[y=obj1[x=[anObject,aPrb]]]', obj2.toString()) + assert.equals('obj2[y=obj1[x=[obj2, a Prb[]]]]', obj2.toString()) } \ No newline at end of file diff --git a/wollok-tests/src/wollok/classes/basics/simpleClass.wlk b/wollok-tests/src/wollok/classes/basics/simpleClass.wlk index 67030be2d8..35b2cd042a 100644 --- a/wollok-tests/src/wollok/classes/basics/simpleClass.wlk +++ b/wollok-tests/src/wollok/classes/basics/simpleClass.wlk @@ -4,7 +4,7 @@ * @author jfernandes */ class Golondrina { - var energia = 100 /** Retorna la energia actual */ + var energia = 50 /** Retorna la energia actual */ method getEnergia() { return energia } diff --git a/wollok-tests/src/wollok/classes/basics/simpleClass_program.wpgm b/wollok-tests/src/wollok/classes/basics/simpleClass_program.wpgm index cb441b0044..0a7af482fc 100644 --- a/wollok-tests/src/wollok/classes/basics/simpleClass_program.wpgm +++ b/wollok-tests/src/wollok/classes/basics/simpleClass_program.wpgm @@ -11,7 +11,7 @@ program simpleClass { // const pepona = new Golondrina() pepona.volar(2) - assert.equals(98, pepona.getEnergia()) + assert.equals(48, pepona.getEnergia()) assert.equals(50, pepita.getEnergia()) // pepita no se altero // // diff --git a/wollok-tests/src/wollok/classes/basics/simpleInheritance_program.wpgm b/wollok-tests/src/wollok/classes/basics/simpleInheritance_program.wpgm index 24c7a36c6f..5554d293d9 100644 --- a/wollok-tests/src/wollok/classes/basics/simpleInheritance_program.wpgm +++ b/wollok-tests/src/wollok/classes/basics/simpleInheritance_program.wpgm @@ -1,12 +1,7 @@ import simpleInheritance.* program simpleInheritance { - const pepita = new Golondrina() - pepita.volar(50) - - pepita.setEnergia(23) - - assert.that(pepita.energia() == 50) // Mando mensaje en superclase - + pepita.volar(40) + assert.equals(pepita.energia(), 60) // Mando mensaje en superclase } \ No newline at end of file diff --git a/wollok-tests/src/wollok/classes/mixins/mixins.wtest b/wollok-tests/src/wollok/classes/mixins/mixins.wtest index e9e975b3c8..c948a85979 100644 --- a/wollok-tests/src/wollok/classes/mixins/mixins.wtest +++ b/wollok-tests/src/wollok/classes/mixins/mixins.wtest @@ -12,7 +12,6 @@ class Birdo mixed with Energy { mixin Flies { method fly() { - console.println("I'm flying") } } @@ -96,12 +95,8 @@ test "Class with simple mixin inherits a method" { test "Class with mixin modifying its own state from the mixin" { const b = new WalkingBird() b.walk(10) -// console.println(b.walkedDistance()) const walked = b.walkedDistance() - console.println("sarasa = " + walked) - assert.that(10 == walked) - - console.println("Y ahora ?") + assert.equals(10, walked) } test "asd" { @@ -114,14 +109,10 @@ test "asd" { test "Mixin method calls a method on the class" { const b = new BirdWithFlyingShortCuts() - b.fly100meters() + b.fly100Meters() assert.equals(100, b.energy()) } test "WKO with mixin" { pepita.fly() } - - - - diff --git a/wollok-tests/src/wollok/classes/natives/sample_program.wpgm b/wollok-tests/src/wollok/classes/natives/sample_program.wpgm index ae9ae1b9d0..c87aca176c 100644 --- a/wollok-tests/src/wollok/classes/natives/sample_program.wpgm +++ b/wollok-tests/src/wollok/classes/natives/sample_program.wpgm @@ -1,5 +1,11 @@ import wollok.classes.natives.MyNative +/** + * If you want to run this test, you have to copy `wollok` folder with MyNative Java + * definitions into your `src` folder (or any other source folder that belongs to the + * classpath) + */ + program nativeSample { const obj = new MyNative() const response = obj.aNativeMethod() diff --git a/wollok-tests/src/wollok/classes/natives/wollok.wlk b/wollok-tests/src/wollok/classes/natives/wollok.wlk index c1abbfb65f..8e74964d61 100644 --- a/wollok-tests/src/wollok/classes/natives/wollok.wlk +++ b/wollok-tests/src/wollok/classes/natives/wollok.wlk @@ -9,4 +9,3 @@ package classes.natives { } } - diff --git a/wollok-tests/src/wollok/classes/natives/wollok/MyNative.class b/wollok-tests/src/wollok/classes/natives/wollok/MyNative.class new file mode 100644 index 0000000000000000000000000000000000000000..ee229f65e1e298ada6e9aacb9630ab43fbfb0637 GIT binary patch literal 320 zcmYjM!A`8jjDMvk6AyfVA7z}S zF*=9$X5PG+$$Wi(?f_ilC`1jNCJqC11M~=uvCegQOYn!ICqnJcESS)p=$vPpbswh)=8qLc>=jjb0oSRLN@V(y8Okb;^E9Y#Zjt1eh zlKM-|GSgqPwJPNS;o`-J@Ej$XvX*U>@6XxjcL$;OckdxyaZ+LcU*2)yf!un*K&o?L m60To t.vagonMasPesado()}).flatten() } + method vagonesMasPesados() { return formaciones.map { t => t.vagonMasPesado()} } } class Tren { @@ -14,9 +14,9 @@ class Tren { method getCantidadVagonesLivianos() = vagones.count{v=> v.esLiviano()} method getVelocidadMaxima() = locomotoras.min{l=> l.getVelocidadMaxima() }.getVelocidadMaxima() method agregarLocomotora(loco) { locomotoras.add(loco) } - method esEficiente() = locomotoras.forAll{l=> l.esEficiente()} + method esEficiente() = locomotoras.all{l=> l.esEficiente()} method puedeMoverse() = self.arrastreUtilTotalLocomotoras() >= self.pesoMaximoTotalDeVagones() - method arrastreUtilTotalLocomotoras() = locomotoras.sum{l=> l.arrastreUtil()} + method arrastreUtilTotalLocomotoras() = locomotoras.sum {l=> l.arrastreUtil() } method pesoMaximoTotalDeVagones() = vagones.sum{v=> v.getPesoMaximo()} method getKilosEmpujeFaltantes() = if (self.puedeMoverse()) @@ -30,7 +30,6 @@ class Locomotora { var peso var pesoMaximoArrastre var velocidadMaxima - constructor(pes, pesoMaxA, veloMax) { peso = pes ; pesoMaximoArrastre = pesoMaxA ; velocidadMaxima = veloMax } method getVelocidadMaxima() = velocidadMaxima method esEficiente() = pesoMaximoArrastre >= 5 * peso @@ -46,7 +45,6 @@ class Vagon { class VagonPasajeros inherits Vagon { var ancho var largo - constructor(a, la) { ancho = a ; largo = la } override method getCantidadPasajeros() { return largo * if (ancho < 2.5) 8 else 10 @@ -58,9 +56,6 @@ class VagonPasajeros inherits Vagon { class VagonCarga inherits Vagon { var cargaMaxima - constructor(cargaM) { - cargaMaxima = cargaM - } override method getCantidadPasajeros() = 0 override method getPesoMaximo() = cargaMaxima + 160 } diff --git a/wollok-tests/src/wollok/examples/trenes/workspace.wpgm b/wollok-tests/src/wollok/examples/trenes/workspace.wpgm index 4b158e07c5..5b6a5070f0 100644 --- a/wollok-tests/src/wollok/examples/trenes/workspace.wpgm +++ b/wollok-tests/src/wollok/examples/trenes/workspace.wpgm @@ -3,56 +3,50 @@ import trenes.* // 1) program trenes { -const tren = new Tren() -tren.agregarVagon(new VagonPasajeros(2, 10)) -assert.equals(80, tren.getCantidadPasajeros()) + const tren = new Tren() + tren.agregarVagon(new VagonPasajeros(ancho = 2, largo = 10)) + assert.equals(80, tren.getCantidadPasajeros()) -tren.agregarVagon(new VagonPasajeros(3, 10)) -assert.equals(180, tren.getCantidadPasajeros()) + tren.agregarVagon(new VagonPasajeros(ancho = 3, largo = 10)) + assert.equals(180, tren.getCantidadPasajeros()) -tren.agregarVagon(new VagonCarga(1000)) -assert.equals(180, tren.getCantidadPasajeros()) + tren.agregarVagon(new VagonCarga(cargaMaxima = 1000)) + assert.equals(180, tren.getCantidadPasajeros()) + // 2) Cuántos vagones livianos tiene una formación; + assert.equals(1, tren.getCantidadVagonesLivianos()) // el de carga -// 2) Cuántos vagones livianos tiene una formación; -assert.equals(1, tren.getCantidadVagonesLivianos()) // el de carga + // 3) La velocidad máxima de una formación, + tren.agregarLocomotora(new Locomotora(peso = 1020, pesoMaximoArrastre = 8100, velocidadMaxima = 60)) // de 60 kpm + tren.agregarLocomotora(new Locomotora(peso = 1400, pesoMaximoArrastre = 10000,velocidadMaxima = 75)) // de 60 kpm -// 3) La velocidad máxima de una formación, -tren.agregarLocomotora(new Locomotora(1020, 8100, 60)) // de 60 kpm -tren.agregarLocomotora(new Locomotora(1400, 10000, 75)) // de 60 kpm + assert.equals(60, tren.getVelocidadMaxima()) -assert.equals(60, tren.getVelocidadMaxima()) + // 4) Si una formación es eficiente; + assert.that(new Locomotora(peso = 10, pesoMaximoArrastre = 50, velocidadMaxima = 0).esEficiente()) + assert.that(new Locomotora(peso = 10, pesoMaximoArrastre = 51, velocidadMaxima = 0).esEficiente()) + assert.notThat(new Locomotora(peso = 10, pesoMaximoArrastre = 49, velocidadMaxima = 0).esEficiente()) -// 4) Si una formación es eficiente; + assert.that(tren.esEficiente()) -assert.that(new Locomotora(10, 50, 0).esEficiente()) -assert.that(new Locomotora(10, 51, 0).esEficiente()) -assert.notThat(new Locomotora(10, 49, 0).esEficiente()) + // 5) Si una formación puede moverse. + assert.that(tren.puedeMoverse()) -assert.that(tren.esEficiente()) + // 6) Cuántos kilos de empuje le faltan a una formación para poder moverse, + assert.equals(0, tren.getKilosEmpujeFaltantes()) -// 5) Si una formación puede moverse. + const trenNoSeMueve = new Tren() + trenNoSeMueve.agregarVagon(new VagonPasajeros(ancho = 3, largo = 12)) + trenNoSeMueve.agregarLocomotora(new Locomotora(peso = 1200, pesoMaximoArrastre = 4000, velocidadMaxima = 55)) + assert.notThat(trenNoSeMueve.puedeMoverse()) + assert.equals(6800, trenNoSeMueve.getKilosEmpujeFaltantes()) -assert.that(tren.puedeMoverse()) + // 7) Dado un depósito, obtener el conjunto formado por el vagón más pesado de cada formación; -// 6) Cuántos kilos de empuje le faltan a una formación para poder moverse, + const deposito = new Deposito() + deposito.agregarFormacion(tren) + deposito.agregarFormacion(trenNoSeMueve) -assert.that(0 == tren.getKilosEmpujeFaltantes()) - -const trenNoSeMueve = new Tren() -trenNoSeMueve.agregarVagon(new VagonPasajeros(3, 12)) -trenNoSeMueve.agregarLocomotora(new Locomotora(1200, 4000, 55)) -assert.that(trenNoSeMueve.puedeMoverse()) -assert.equals(6800, trenNoSeMueve.getKilosEmpujeFaltantes()) - -// 7) Dado un depósito, obtener el conjunto formado por el vagón más pesado de cada formación; - -const deposito = new Deposito() -deposito.agregarFormacion(tren) -deposito.agregarFormacion(trenNoSeMueve) - -assert.that(2 == deposito.vagonesMasPesados().size()) - -console.println("FIIIIN") + assert.equals(2, deposito.vagonesMasPesados().size()) } \ No newline at end of file From 966032dbba8d2cbe27633a50f7aa5c83e702597a Mon Sep 17 00:00:00 2001 From: Fernando Dodino Date: Mon, 28 Oct 2019 23:40:13 -0300 Subject: [PATCH 072/133] Properties Test Case moved to sanity tests --- .../interpreter/PropertiesTestCase.xtend | 278 ------------------ 1 file changed, 278 deletions(-) delete mode 100644 org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/PropertiesTestCase.xtend diff --git a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/PropertiesTestCase.xtend b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/PropertiesTestCase.xtend deleted file mode 100644 index 4e9013d5eb..0000000000 --- a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/PropertiesTestCase.xtend +++ /dev/null @@ -1,278 +0,0 @@ -package org.uqbar.project.wollok.tests.interpreter - -import org.junit.Test - -class PropertiesTestCase extends AbstractWollokInterpreterTestCase { - - @Test - def void getterAndSetterForPropertyVarInClass() { - ''' - class Ave { - var property energia = 100 - - method volar() { - energia -= 10 - } - } - - test "energia inicial de pepita" { - const pepita = new Ave() - assert.equals(100, pepita.energia()) - } - - test "energia seteada de pepita" { - const pepita = new Ave() - pepita.energia(40) - pepita.volar() - assert.equals(30, pepita.energia()) - } - '''.interpretPropagatingErrors - } - - @Test - def void getterForPropertyConstInClass() { - ''' - class Ave { - const property fechaNacimiento = new Date() - var property vecesQueVolo - - constructor() { - vecesQueVolo = 0 - } - - method volar() { - vecesQueVolo++ - } - } - - test "fecha de nacimiento de pepita" { - const pepita = new Ave() - assert.equals(new Date(), pepita.fechaNacimiento()) - } - - test "al volar sigue constante la fecha de nacimiento de pepita" { - const pepita = new Ave() - pepita.volar() - assert.equals(1, pepita.vecesQueVolo()) - } - '''.interpretPropagatingErrors - } - - @Test - def void getterForPropertyConstInWko() { - ''' - object pepita { - const property energia = 100 - const property numerosFavoritos = [1, 3, 5, 8] - var property vecesQueVolo = self.energia() - 100 - - method volar() { - vecesQueVolo++ - } - } - - test "energia inicial de pepita" { - assert.equals(100, pepita.energia()) - } - - test "al volar sigue constante la energia de pepita" { - pepita.volar() - assert.equals(100, pepita.energia()) - assert.equals(1, pepita.vecesQueVolo()) - assert.equals([1, 3, 5, 8], pepita.numerosFavoritos()) - } - '''.interpretPropagatingErrors - } - - @Test - def void getterAndSetterForPropertyVarInWko() { - ''' - object pepita { - var property energia = 100 - - method volar() { - energia -= 10 - } - } - - test "energia inicial de pepita" { - assert.equals(100, pepita.energia()) - } - - test "energia seteada de pepita" { - pepita.energia(40) - pepita.volar() - assert.equals(30, pepita.energia()) - } - '''.interpretPropagatingErrors - } - - @Test - def void setterForPropertyConstInObject() { - ''' - object pepita { - const property energia = 0 - } - program prueba { - try { - pepita.energia(10) - } catch e : Exception { - assert.equals("Cannot modify constant property energia", e.message()) - } - } - '''.interpretPropagatingErrorsWithoutStaticChecks - } - - @Test - def void badSetterForPropertyConstInObject() { - ''' - object pepita { - const property energia = 0 - } - program prueba { - try { - pepita.energia(10, "hola") - } catch e : Exception { - assert.equals("pepita[energia=0] does not understand energia(param1, param2)", e.message()) - } - } - '''.interpretPropagatingErrorsWithoutStaticChecks - } - - @Test - def void setterForPropertyConstInClass() { - ''' - class Ave { - const property energia = 0 - } - program prueba { - const pepita = new Ave() - try { - pepita.energia(10) - } catch e : Exception { - console.println(e.message()) - assert.equals("Cannot modify constant property energia", e.message()) - } - } - '''.interpretPropagatingErrorsWithoutStaticChecks - } - - @Test - def void customGetterForPropertyConstInClass() { - ''' - class Ave { - var property energia = 0 - method energia() = energia / 2 - } - program prueba { - const pepita = new Ave() - pepita.energia(10) - assert.equals(5, pepita.energia()) - } - '''.interpretPropagatingErrors - } - - @Test - def void badSetterForPropertyConstInClass() { - ''' - class Ave { - const property energia = 0 - } - program prueba { - const pepita = new Ave() - try { - pepita.energia(10, [21, 1]) - } catch e : Exception { - assert.equals("a Ave[energia=0] does not understand energia(param1, param2)", e.message()) - } - } - '''.interpretPropagatingErrorsWithoutStaticChecks - } - - @Test - def void propertyGetterOverriddenInSubclass() { - ''' - class MaestroTierra { - var property base = 100 - } - - class MaestroMetal inherits MaestroTierra { - override method base() { - return super() * 2 - } - } - - test "getter overridden" { - assert.equals(200, new MaestroMetal().base()) - } - '''.interpretPropagatingErrors - } - - @Test - def void propertyOverriddenInClassAndOverridenInSubclass() { - ''' - class MaestroTierra { - var property base = 100 - - method base() = 150 - } - - class MaestroMetal inherits MaestroTierra { - override method base() { - return super() * 2 - } - } - - test "getter overridden" { - assert.equals(300, new MaestroMetal().base()) - } - '''.interpretPropagatingErrors - } - - @Test - def void propertySetterOverridenInSubclass() { - ''' - class MaestroTierra { - var property base = 0 - } - - class MaestroMetal inherits MaestroTierra { - override method base(_value) { - return super(_value * 2) - } - } - - test "setter overridden" { - const acdc = new MaestroMetal() - acdc.base(40) - assert.equals(80, acdc.base()) - } - '''.interpretPropagatingErrors - } - - @Test - def void propertySetterOverridenInClassAndOverridenInSubclass() { - ''' - class MaestroTierra { - var property base = 0 - - method base(_value) { - base = _value - 10 - } - } - - class MaestroMetal inherits MaestroTierra { - override method base(_value) { - super(_value * 2) - } - } - - test "setter overridden" { - const acdc = new MaestroMetal() - acdc.base(40) - assert.equals(70, acdc.base()) - } - '''.interpretPropagatingErrors - } - -} \ No newline at end of file From 069528bdf804af27408397af808989d3aaad4c5c Mon Sep 17 00:00:00 2001 From: nicovio Date: Tue, 29 Oct 2019 17:08:25 -0300 Subject: [PATCH 073/133] fix #1836 - Eliminar imports redundantes al importar con quickfix --- .../wollok/ui/quickfix/QuickFixUtils.xtend | 95 +++++++++++++++++-- .../quickfix/WollokDslQuickfixProvider.xtend | 4 +- 2 files changed, 89 insertions(+), 10 deletions(-) diff --git a/org.uqbar.project.wollok.ui/src/org/uqbar/project/wollok/ui/quickfix/QuickFixUtils.xtend b/org.uqbar.project.wollok.ui/src/org/uqbar/project/wollok/ui/quickfix/QuickFixUtils.xtend index b5b243706a..c26c634c14 100644 --- a/org.uqbar.project.wollok.ui/src/org/uqbar/project/wollok/ui/quickfix/QuickFixUtils.xtend +++ b/org.uqbar.project.wollok.ui/src/org/uqbar/project/wollok/ui/quickfix/QuickFixUtils.xtend @@ -1,20 +1,24 @@ package org.uqbar.project.wollok.ui.quickfix +import java.util.Collections +import java.util.List +import java.util.Set import org.eclipse.emf.ecore.EObject - - import org.eclipse.jface.text.IRegion +import org.eclipse.xtend.lib.annotations.Data import org.eclipse.xtext.RuleCall import org.eclipse.xtext.nodemodel.INode import org.eclipse.xtext.nodemodel.util.NodeModelUtils import org.eclipse.xtext.ui.editor.model.IXtextDocument import org.eclipse.xtext.ui.editor.model.edit.IModificationContext +import org.uqbar.project.wollok.wollokDsl.Import import org.uqbar.project.wollok.wollokDsl.WMethodContainer + +import static org.uqbar.project.wollok.WollokConstants.* + import static extension org.uqbar.project.wollok.model.WMethodContainerExtensions.* -import static extension org.uqbar.project.wollok.WollokConstants.* +import static extension org.uqbar.project.wollok.model.WollokModelExtensions.* import static extension org.uqbar.project.wollok.utils.XTextExtensions.* -import org.eclipse.xtend.lib.annotations.Data -import org.uqbar.project.wollok.wollokDsl.Import /** * Provides utilities for quickfixes. @@ -183,6 +187,77 @@ class QuickFixUtils { def static dispatch grammarDescription(EObject it) { it } + def static void insertWildcardImport(IXtextDocument it, EObject declaringContext, String wildcardImport) { + val allImports = declaringContext.allImports.toList + insertImport(declaringContext, wildcardImport.generateNewImportCode) + if (!allImports.empty) { + removeRedundantImports(allImports, wildcardImport) + } + } + + def static void removeRedundantImports(IXtextDocument it, List imports, String importToAdd) { + val withoutRedundant = imports.withoutRedundant(importToAdd) + if (imports.size > withoutRedundant.size) { + if (withoutRedundant.isEmpty) { + removeImports(imports, 2) + } else { + removeImports(imports, 0) + } + relocateImports(withoutRedundant, imports.head.before) + } + } + + def static removeImports(IXtextDocument it, List imports, int extraEspace) { + val firstImportPosition = imports.head.before + replace(firstImportPosition, imports.last.after - firstImportPosition + extraEspace, "") + } + + def static List withoutRedundant(List imports, String importToAdd) { + val importsNames = imports.map[anImport|anImport.importedNamespace] + val Set wildCardImports = wildcardImports(importsNames) + val Set importsNamesSet = newHashSet + wildCardImports.add(importToAdd.substring(0, importToAdd.lastIndexOf("."))) + importsNames.filter [ importName | + val path = importName.substring(0, importName.lastIndexOf(".")) + (!wildCardImports.contains(path) && importsNamesSet.add(importName)) || + importName.substring(importName.lastIndexOf(".")).equals(".*") + ].toList + } + + def static Set wildcardImports(List imports) { + imports.filter [ importName | + importName.substring(importName.lastIndexOf(".")).equals(".*") + ].map [ importName | + importName.substring(0, importName.lastIndexOf(".")) + ].toSet + } + + def static void relocateImports(IXtextDocument xtextDocument, List imports, int position) { + Collections.reverse(imports) + imports.forEach [ anImport, index | + val location = xtextDocument.importToRelocateLocation(index) + val importCode = anImport.generateNewImportCode + xtextDocument.insertImport(new QuickFixLocation(position, location), importCode) + ] + } + + def static Location importToRelocateLocation(IXtextDocument xtextDocument, int index) { + if (index !== 0) { + Location.BEFORE + } else { + Location.NONE + } + } + + def static insertImport(IXtextDocument xtextDocument, EObject declaringContext, String code) { + val importLocation = declaringContext.placeToAddImport(xtextDocument) + insertImport(xtextDocument, importLocation, code) + } + + def static insertImport(IXtextDocument xtextDocument, QuickFixLocation importLocation, String code) { + xtextDocument.replace(importLocation.placeToAdd, 0, importLocation.formatCode(code)) + } + def static insertImport(EObject declaringContext, String code, IModificationContext context) { val xtextDocument = context.getXtextDocument(declaringContext.fileURI) val importLocation = declaringContext.placeToAddImport(xtextDocument) @@ -213,9 +288,8 @@ class QuickFixUtils { def static Location importToAddLocation(IXtextDocument xtextDocument, int position) { val IRegion lineInformation = xtextDocument.getLineInformationOfOffset(position) - val IRegion nextLineInformation = xtextDocument.getLineInformationOfOffset(lineInformation.endOfLine + 2) - val String lineText = xtextDocument.get(lineInformation.offset, lineInformation.length) - val String nextLineText = xtextDocument.get(nextLineInformation.offset, nextLineInformation.length) + val String lineText = xtextDocument.lineText(position) + val String nextLineText = xtextDocument.lineText(lineInformation.endOfLine + 2) var Location result if (position.equals(0)) { @@ -230,6 +304,11 @@ class QuickFixUtils { result } + def static String lineText(IXtextDocument xtextDocument, int position) { + val IRegion lineInformation = xtextDocument.getLineInformationOfOffset(position) + xtextDocument.get(lineInformation.offset, lineInformation.length) + } + def static insertMethod(WMethodContainer declaringContext, String code, IModificationContext context) { val constructorLocation = declaringContext.placeToAddMethod val xtextDocument = context.getXtextDocument(declaringContext.fileURI) diff --git a/org.uqbar.project.wollok.ui/src/org/uqbar/project/wollok/ui/quickfix/WollokDslQuickfixProvider.xtend b/org.uqbar.project.wollok.ui/src/org/uqbar/project/wollok/ui/quickfix/WollokDslQuickfixProvider.xtend index 2a9a5d9aa2..e80d8f77fd 100644 --- a/org.uqbar.project.wollok.ui/src/org/uqbar/project/wollok/ui/quickfix/WollokDslQuickfixProvider.xtend +++ b/org.uqbar.project.wollok.ui/src/org/uqbar/project/wollok/ui/quickfix/WollokDslQuickfixProvider.xtend @@ -644,12 +644,12 @@ class WollokDslQuickfixProvider extends DefaultQuickfixProvider { NLS.bind(Messages.WollokDslQuickFixProvider_add_import_name, nameWithWildcard), NLS.bind(Messages.WollokDslQuickFixProvider_add_import_description, nameWithWildcard), "w.png", [ e, context | - e.insertImport(nameWithWildcard.generateNewImportCode, context) + xtextDocument.insertWildcardImport(e, nameWithWildcard) ], 1) issueResolutionAcceptor.accept(issue, NLS.bind(Messages.WollokDslQuickFixProvider_add_import_name, importName), NLS.bind(Messages.WollokDslQuickFixProvider_add_import_description, importName), icon, [ e, context | - e.insertImport(importName.generateNewImportCode, context) + xtextDocument.insertImport(e, importName.generateNewImportCode) ], 1) ] } From 0f6b68872447f482fbc972c7d5999df06fee2e3d Mon Sep 17 00:00:00 2001 From: Fernando Dodino Date: Tue, 29 Oct 2019 21:40:24 -0300 Subject: [PATCH 074/133] Constructor tests => moved to wollok-language repo! --- .../interpreter/clazz/ConstructorTest.xtend | 1096 ----------------- 1 file changed, 1096 deletions(-) delete mode 100644 org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/clazz/ConstructorTest.xtend diff --git a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/clazz/ConstructorTest.xtend b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/clazz/ConstructorTest.xtend deleted file mode 100644 index 42deec8d57..0000000000 --- a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/clazz/ConstructorTest.xtend +++ /dev/null @@ -1,1096 +0,0 @@ -package org.uqbar.project.wollok.tests.interpreter.clazz - -import org.junit.Assert -import org.junit.Test -import org.uqbar.project.wollok.interpreter.core.WollokProgramExceptionWrapper -import org.uqbar.project.wollok.tests.interpreter.AbstractWollokInterpreterTestCase - -/** - * All tests for constructors functionality in terms of runtime execution. - * For static validations see the X_PECT test. - * This tests - * - having multiple constructors - * - constructor delegation: to self or super - * - automatic delegation for no-args constructors - * - * @author jfernandes - * @author dodain - * - */ -class ConstructorTest extends AbstractWollokInterpreterTestCase { - - @Test - def void defaultConstructorHappyPath() { - ''' - class Point { - var x - var y - } - program t { - const p1 = new Point() - } - '''.interpretPropagatingErrors - } - - @Test - def void defaultConstructorCalledWith1Argument() { - try { - ''' - class Point { - var x - var y - } - program t { - const p2 = new Point(1) - } - '''.interpretPropagatingErrorsWithoutStaticChecks - } catch (WollokProgramExceptionWrapper e) { - val message = e.wollokException.instanceVariables.get("message").toString - Assert.assertEquals("Wrong number of arguments. Should be new Point()", message) - } - } - - @Test - def void defaultConstructorCalledWith2Arguments() { - try { - ''' - class Point { - var x - var y - } - program t { - const p2 = new Point(1, 2) - console.println(p2) - } - '''.interpretPropagatingErrorsWithoutStaticChecks - Assert.fail("Should have thrown an error in new Point(1, 2)") - } catch (WollokProgramExceptionWrapper e) { - val message = e.wollokException.instanceVariables.get("message").toString - Assert.assertEquals("Wrong number of arguments. Should be new Point()", message) - } - } - - @Test - def void oneArgumentConstructorHappyPath() { - ''' - class Ave { - var energia - constructor(_energia) { energia = _energia } - } - program t { - const pepita = new Ave(100) - } - '''.interpretPropagatingErrors - } - - @Test - def void oneArgumentConstructorCalledWithNoArguments() { - try { - ''' - class Ave { - var energia - constructor(_energia) { energia = _energia } - } - program t { - const pepita = new Ave() - } - '''.interpretPropagatingErrorsWithoutStaticChecks - Assert.fail("Should have thrown an error in new Ave()") - } catch (WollokProgramExceptionWrapper e) { - val message = e.wollokException.instanceVariables.get("message").toString - Assert.assertEquals("Wrong number of arguments. Should be new Ave(_energia)", message) - } - } - - @Test - def void oneArgumentConstructorCalledWith2Arguments() { - try { - ''' - class Ave { - var energia - constructor(_energia) { energia = _energia } - } - program t { - const pepita = new Ave(10, "pepita") - } - '''.interpretPropagatingErrorsWithoutStaticChecks - Assert.fail("Should have thrown an error in new Ave(10, \"pepita\")") - } catch (WollokProgramExceptionWrapper e) { - val message = e.wollokException.instanceVariables.get("message").toString - Assert.assertEquals("Wrong number of arguments. Should be new Ave(_energia)", message) - } - } - - @Test - def void singleSimpleConstructor() { - ''' - class C { - var a = 10 - const b - var c - - constructor(anA, aB, aC) { - a = anA - b = aB - c = aC - } - method getA() { return a } - method getB() { return b } - method getC() { return c } - } - program t { - const c = new C (1,2,3) - assert.equals(1, c.getA()) - assert.equals(2, c.getB()) - assert.equals(3, c.getC()) - } - '''.interpretPropagatingErrors - } - - @Test - def void multipleConstructors() { - ''' - class Point { - var x - var y - - constructor () { x = 20 ; y = 20 } - - constructor(ax, ay) { - x = ax - y = ay - } - method getX() { return x } - method getY() { return y } - } - program t { - const p1 = new Point(1,2) - assert.equals(1, p1.getX()) - assert.equals(2, p1.getY()) - - const p2 = new Point() - assert.equals(20, p2.getX()) - assert.equals(20, p2.getY()) - } - '''.interpretPropagatingErrors - } - - @Test - def void wrongNumberOfArgsInConstructorCall() { - try { - #[''' - class Point { - var x - var y - - constructor(ax, ay) { x = ax ; y = ay } - } - program t { - const p1 = new Point() - } - '''].interpretPropagatingErrorsWithoutStaticChecks - Assert.fail("Should have thrown an error in new Point()") - } catch (WollokProgramExceptionWrapper e) { - val message = e.wollokException.instanceVariables.get("message").toString - assertEquals("Wrong number of arguments. Should be new Point(ax, ay)", message) - } - } - - @Test - def void constructorDelegationToSelf() { - ''' - class Point { - var x - var y - constructor(ax, ay) { x = ax ; y = ay } - - constructor() = self(10,15) { - } - - method getX() { return x } - method getY() { return y } - } - program t { - const p = new Point() - assert.equals(10, p.getX()) - assert.equals(15, p.getY()) - } - '''.interpretPropagatingErrors - } - - @Test - def void constructorDelegationToSelfWithoutBody() { - ''' - class Point { - var x - var y - constructor(ax, ay) { x = ax ; y = ay } - - constructor() = self(10,15) - - method getX() { return x } - method getY() { return y } - } - program t { - const p = new Point() - console.println(p) - assert.equals(10, p.getX()) - assert.equals(15, p.getY()) - } - '''.interpretPropagatingErrors - } - - @Test - def void constructorDelegationToSuper() { - ''' - class SuperClass { - var superX - constructor(a) { superX = a } - - method getSuperX() { return superX } - } - class SubClass inherits SuperClass { - constructor(n) = super(n + 1) {} - } - program t { - const o = new SubClass(20) - assert.equals(21, o.getSuperX()) - } - '''.interpretPropagatingErrors - } - - @Test - def void constructorDelegationToSuperNamedParameters1() { - ''' - class SuperClass { - var superX - constructor(a) { superX = a } - - method getSuperX() { return superX } - } - class SubClass inherits SuperClass { - constructor(n) = super(a = n + 1) {} - } - program t { - const o = new SubClass(20) - assert.equals(21, o.getSuperX()) - } - '''.expectsValidationError("Named parameters are not allowed here", false) - } - - @Test - def void constructorDelegationToSuperNamedParameters2() { - ''' - class SuperClass { - var superX - var superY - constructor(a, b) { - superX = a - superY = b - } - - method total() { return superX / superY } - } - class SubClass inherits SuperClass { - constructor(n) = super(b = n - 1, a = n * 2) {} - } - program t { - const o = new SubClass(5) - assert.equals(2.5, o.total()) - } - '''.expectsValidationError("Named parameters are not allowed here", false) - } - - @Test - def void constructorDelegationToSelfNamedParameters1() { - ''' - class Prueba { - var superX - constructor(a) { superX = a } - constructor(n, x) = self(a = n + (x * 2)) {} - method getSuperX() { return superX } - } - program t { - const o = new Prueba(5, 4) - assert.equals(13, o.getSuperX()) - } - '''.expectsValidationError("Named parameters are not allowed here", false) - } - - @Test - def void constructorDelegationToSelfNamedParameters2() { - ''' - class Prueba { - var superX - var superY - constructor(a, b) { - superX = a - superY = b - } - constructor(n) = self(b = n - 1, a = n * 2) {} - method total() { return superX / superY } - } - program t { - const o = new Prueba(5) - assert.equals(2.5, o.total()) - } - '''.expectsValidationError("Named parameters are not allowed here", false) - } - - @Test - def void emptyConstructorDelegationToSuper() { - ''' - class SuperClass { - var superX - constructor(){} - method getSuperX() { return superX } - method setSuperX(value) { superX = value } - } - class SubClass inherits SuperClass { - var anotherVariable - constructor(n) = super() { - anotherVariable = n - } - method getAnotherVariable() = anotherVariable - } - program t { - const o = new SubClass(20) - assert.equals(20, o.getAnotherVariable()) - } - '''.interpretPropagatingErrors - } - - @Test - def void defaultConstructorDelegationToSuper() { - ''' - class SuperClass { - var superX - - method getSuperX() { return superX } - method setSuperX(value) { superX = value } - } - class SubClass inherits SuperClass { - var anotherVariable - constructor(n) { - anotherVariable = n - } - method getAnotherVariable() = anotherVariable - } - program t { - const o = new SubClass(20) - assert.equals(20, o.getAnotherVariable()) - } - '''.interpretPropagatingErrors - } - - @Test - def void twoLevelsDelegationToSuper() { - ''' - class A { - var x - constructor(a) { x = a } - - method getX() { return x } - } - class B inherits A { - constructor(n) = super(n + 1) {} - } - class C inherits B { - constructor(l) = super(l * 2) {} - } - program t { - const o = new C(20) - assert.equals(41, o.getX()) - } - '''.interpretPropagatingErrors - } - - @Test - def void mixedSelfAndSuperDelegation() { - ''' - class A { - var x - var y - constructor(p) = self(p.getX(), p.getY()) {} - constructor(_x,_y) { x = _x ; y = _y } - - method getX() { return x } - method getY() { return y } - } - class B inherits A { - constructor(p) = super(p + 10) {} - } - class C inherits B { - constructor(_x, _y) = self(new Point(_x, _y)) {} - constructor(p) = super(p) {} - } - class Point { - var x - var y - constructor(_x,_y) { x = _x ; y = _y } - method +(delta) { - x += delta - y += delta - return self - } - method getX() { return x } - method getY() { return y } - } - - program t { - const o = new C(10, 20) - assert.equals(20, o.getX()) - assert.equals(30, o.getY()) - } - '''.interpretPropagatingErrors - } - - // *********************** - // ** automatic calls - // *********************** - - @Test - def void emptyConstructorInSuperClassMustBeAutomaticallyCalled() { - ''' - class SuperClass { - var superX - constructor() { superX = 20 } - - method getSuperX() { return superX } - } - class SubClass inherits SuperClass { } - program t { - const o = new SubClass() - assert.equals(20, o.getSuperX()) - } - '''.interpretPropagatingErrors - } - - @Test - def void emptyConstructorInSuperClassMustBeAutomaticallyCalledBeforeCallingSubclassEmptyConstructor() { - ''' - class SuperClass { - var superX - var otherX - constructor() { - superX = 20 - otherX = 30 - } - - method getSuperX() { return superX } - method getOtherX() { return otherX } - method setSuperX(a) { superX = a } - } - class SubClass inherits SuperClass { - var subX - constructor() { - subX = 10 - self.setSuperX(self.getSuperX() + 20) // 20 + 20 - } - method getSubX() { return subX } - } - program t { - const o = new SubClass() - assert.equals(10, o.getSubX()) - assert.equals(40, o.getSuperX()) - assert.equals(30, o.getOtherX()) - } - '''.interpretPropagatingErrors - } - - @Test - def void emptyConstructorAutoCalledMixingImplicitConstructorInHierarchy() { - ''' - class A { - var x - constructor() { x = 20 } - - method getX() { return x } - } - class B inherits A { - } - class C inherits B { - var c1 - constructor() { - c1 = 10 - } - method getC1() { return c1 } - } - class D inherits C {} - program t { - const o = new D() - assert.equals(20, o.getX()) - assert.equals(10, o.getC1()) - } - '''.interpretPropagatingErrors - } - - @Test - def void defaultConstructorInheritedFromObject() { - ''' - class A { - } - class B inherits A { - } - class C inherits B { - } - program t { - const a = new A() - const b = new B() - const c = new C() - } - '''.interpretPropagatingErrors - } - - @Test - def void inheritedOneArgumentConstructorInheritedFromSuperclass() { - ''' - class A { - } - class B inherits A { - var x - constructor(_x) { x = _x } - method x() = x - } - class C inherits B { - } - program t { - const a = new A() - const b = new B(1) - assert.equals(1, b.x()) - const c = new C(1) - assert.equals(1, c.x()) - } - '''.interpretPropagatingErrors - } - - @Test - def void inheritedOneArgumentConstructorInheritedFromSuperclassCallingNoArgumentFails1() { - try { - - ''' - class A { - } - class B inherits A { - var x - constructor(_x) { x = _x } - method x() = x - } - class C inherits B { - } - program t { - const b = new B() - } - '''.interpretPropagatingErrorsWithoutStaticChecks - Assert.fail("Should have thrown an error in new B()") - } catch (WollokProgramExceptionWrapper e) { - val message = e.wollokException.instanceVariables.get("message").toString - assertEquals("Wrong number of arguments. Should be new B(_x)", message) - } - } - - @Test - def void inheritedOneArgumentConstructorInheritedFromSuperclassCallingNoArgumentFails2() { - try { - - ''' - class A { - } - class B inherits A { - var x - constructor(_x) { x = _x } - method x() = x - } - class C inherits B { - } - program t { - const c = new C() - } - '''.interpretPropagatingErrorsWithoutStaticChecks - Assert.fail("Should have thrown an error in new C()") - } catch (WollokProgramExceptionWrapper e) { - val message = e.wollokException.instanceVariables.get("message").toString - assertEquals("Wrong number of arguments. Should be new C(_x)", message) - } - } - - @Test - def void inheritedOneArgumentConstructorInheritedFromSuperclassCallingNoArgumentFails3() { - try { - - ''' - class A { - constructor(_a, _b) { } - } - class B inherits A { - var x - constructor(_x) { x = _x } - method x() = x - } - class C inherits B { - } - program t { - const c = new C(1, 2) - } - '''.interpretPropagatingErrorsWithoutStaticChecks - Assert.fail("Should have thrown an error in new C(1, 2)") - } catch (WollokProgramExceptionWrapper e) { - val message = e.wollokException.instanceVariables.get("message").toString - assertEquals("Wrong number of arguments. Should be new C(_x)", message) - } - } - - @Test - def void inheritedConstructorsHappyPath() { - ''' - class A { - var a - constructor(_a) { a = _a } - method a() = a - } - class B inherits A { - var x - constructor(_y, _x) { x = _x ; a = _y } - method x() = x - } - class C inherits B { - constructor() { a = 2 ; x = 3 } - } - program t { - const a = new A(1) - assert.equals(1, a.a()) - const b = new B(5, 6) - assert.equals(5, b.a()) - assert.equals(6, b.x()) - const c = new C() - assert.equals(2, c.a()) - assert.equals(3, c.x()) - } - '''.interpretPropagatingErrorsWithoutStaticChecks - } - - @Test - def void inheritedConstructorsBadConstructorCallsFromA1() { - try { - ''' - class A { - var a - constructor(_a) { a = _a } - method a() = a - } - class B inherits A { - var x - constructor(_y, _x) { x = _x ; a = _y } - method x() = x - } - class C inherits B { - constructor() { a = 2 ; x = 3 } - } - program t { - const a = new A() - } - '''.interpretPropagatingErrorsWithoutStaticChecks - Assert.fail("Should have thrown an error in new A()") - } catch (WollokProgramExceptionWrapper e) { - val message = e.wollokException.instanceVariables.get("message").toString - assertEquals("Wrong number of arguments. Should be new A(_a)", message) - } - } - - @Test - def void inheritedConstructorsBadConstructorCallsFromA2() { - try { - ''' - class A { - var a - constructor(_a) { a = _a } - method a() = a - } - class B inherits A { - var x - constructor(_y, _x) { x = _x ; a = _y } - method x() = x - } - class C inherits B { - constructor() { a = 2 ; x = 3 } - } - program t { - const a = new A(1, 2) - } - '''.interpretPropagatingErrorsWithoutStaticChecks - Assert.fail("Should have thrown an error in new A(1, 2)") - } catch (WollokProgramExceptionWrapper e) { - val message = e.wollokException.instanceVariables.get("message").toString - assertEquals("Wrong number of arguments. Should be new A(_a)", message) - } - } - - @Test - def void inheritedConstructorsBadConstructorCallsFromB1() { - try { - ''' - class A { - var a - constructor(_a) { a = _a } - method a() = a - } - class B inherits A { - var x - constructor(_y, _x) { x = _x ; a = _y } - method x() = x - } - class C inherits B { - constructor() { a = 2 ; x = 3 } - } - program t { - const b = new B() - } - '''.interpretPropagatingErrorsWithoutStaticChecks - Assert.fail("Should have thrown an error in new B()") - } catch (WollokProgramExceptionWrapper e) { - val message = e.wollokException.instanceVariables.get("message").toString - assertEquals("Wrong number of arguments. Should be new B(_y, _x)", message) - } - } - - @Test - def void inheritedConstructorsBadConstructorCallsFromB2() { - try { - ''' - class A { - var a - constructor(_a) { a = _a } - method a() = a - } - class B inherits A { - var x - constructor(_y, _x) { x = _x ; a = _y } - method x() = x - } - class C inherits B { - constructor() { a = 2 ; x = 3 } - } - program t { - const b = new B(1) - } - '''.interpretPropagatingErrorsWithoutStaticChecks - Assert.fail("Should have thrown an error in new B(1)") - } catch (WollokProgramExceptionWrapper e) { - val message = e.wollokException.instanceVariables.get("message").toString - assertEquals("Wrong number of arguments. Should be new B(_y, _x)", message) - } - } - - @Test - def void inheritedConstructorsBadConstructorCallsFromC1() { - try { - ''' - class A { - var a - constructor(_a) { a = _a } - method a() = a - } - class B inherits A { - var x - constructor(_y, _x) { x = _x ; a = _y } - method x() = x - } - class C inherits B { - constructor() { a = 2 ; x = 3 } - } - program t { - const c = new C(1) - } - '''.interpretPropagatingErrorsWithoutStaticChecks - Assert.fail("Should have thrown an error in new C(1)") - } catch (WollokProgramExceptionWrapper e) { - val message = e.wollokException.instanceVariables.get("message").toString - assertEquals("Wrong number of arguments. Should be new C()", message) - } - } - - @Test - def void inheritedConstructorsBadConstructorCallsFromC2() { - try { - ''' - class A { - var a - constructor(_a) { a = _a } - method a() = a - } - class B inherits A { - var x - constructor(_y, _x) { x = _x ; a = _y } - method x() = x - } - class C inherits B { - constructor() { a = 2 ; x = 3 } - } - program t { - const c = new C(1, 7) - } - '''.interpretPropagatingErrorsWithoutStaticChecks - Assert.fail("Should have thrown an error in new C(1, 7)") - } catch (WollokProgramExceptionWrapper e) { - val message = e.wollokException.instanceVariables.get("message").toString - assertEquals("Wrong number of arguments. Should be new C()", message) - } - } - - /** ****************************************************************** - * - * TESTS BASED ON REAL-WORLD EXAMPLES. THEY HAVE SEVERAL DEFINITIONS - * OF ELEMENTS , SO THEY COMPLEMENT PREVIOUS TESTS. - * - * ****************************************************************** - * */ - @Test - def void issue1288() { - ''' - class Arma { - const mm - - constructor(_mm) { - mm = _mm - } - } - - class Unidad { - var nombre = "Peloton" - } - - class UnidadArmada inherits Unidad { - var arma - - constructor(unArma) { - arma = unArma - } - } - - object armeria { - method arco() = new Arma(25) - } - class Arquero inherits UnidadArmada { - constructor() = super(armeria.arco()) - } - program prueba { - console.println(new Arquero()) - } - '''.interpretPropagatingErrors - } - - @Test - def void multipleInheritanceForConstructors() { - try { - ''' - class Musico { - var habilidadBase - var grupo = '' - const albumes = #{} - constructor() { } - constructor ( _habilidadBase) { - habilidadBase = _habilidadBase - } - } - - class MusicoConRoles inherits Musico { - var rolInterpretador - var rolCobrador - constructor ( _habilidadBase, _rolInterpretador, _rolCobrador) = super ( _habilidadBase) { - rolInterpretador = _rolInterpretador - rolCobrador = _rolCobrador - } - method internalInterpretaBien(cancion) = rolInterpretador.interpretaBien(cancion) - method cobra(presentacion) = rolCobrador.cobra(presentacion) - } - - class VocalistaPopular inherits MusicoConRoles { - method esSolista() = true - method habilidadExtra() = if (self.esSolista()) 0 else -20 - } - - program prueba { - new VocalistaPopular() - } - '''.interpretPropagatingErrorsWithoutStaticChecks - Assert.fail("Should have thrown an error in new VocalistaPopular()") - } catch (WollokProgramExceptionWrapper e) { - val message = e.wollokException.instanceVariables.get("message").toString - Assert.assertEquals("Wrong number of arguments. Should be new VocalistaPopular(_habilidadBase, _rolInterpretador, _rolCobrador)", message) - } - } - - @Test - def void multipleInheritanceForConstructors2() { - try { - ''' - class Musico { - var habilidadBase - var grupo = '' - const albumes = #{} - constructor() { } - constructor ( _habilidadBase) { - habilidadBase = _habilidadBase - } - } - - class MusicoConRoles inherits Musico { - var rolInterpretador - var rolCobrador - constructor ( _habilidadBase, _rolInterpretador, _rolCobrador) = super ( _habilidadBase) { - rolInterpretador = _rolInterpretador - rolCobrador = _rolCobrador - } - method internalInterpretaBien(cancion) = rolInterpretador.interpretaBien(cancion) - method cobra(presentacion) = rolCobrador.cobra(presentacion) - } - - class VocalistaPopular inherits MusicoConRoles { - method esSolista() = true - method habilidadExtra() = if (self.esSolista()) 0 else -20 - } - - program prueba { - new VocalistaPopular(2) - } - '''.interpretPropagatingErrorsWithoutStaticChecks - Assert.fail("Should have thrown an error in new VocalistaPopular(2)") - } catch (WollokProgramExceptionWrapper e) { - val message = e.wollokException.instanceVariables.get("message").toString - Assert.assertEquals(message, "Wrong number of arguments. Should be new VocalistaPopular(_habilidadBase, _rolInterpretador, _rolCobrador)") - } - } - - @Test - def void multipleInheritanceForConstructors3() { - ''' - class Musico { - var habilidadBase - var grupo = '' - const albumes = #{} - constructor() { } - constructor ( _habilidadBase) { - habilidadBase = _habilidadBase - } - } - - class MusicoConRoles inherits Musico { - var rolInterpretador - var rolCobrador - constructor ( _habilidadBase, _rolInterpretador, _rolCobrador) = super ( _habilidadBase) { - rolInterpretador = _rolInterpretador - rolCobrador = _rolCobrador - } - method internalInterpretaBien(cancion) = rolInterpretador.interpretaBien(cancion) - method cobra(presentacion) = rolCobrador.cobra(presentacion) - } - - class VocalistaPopular inherits MusicoConRoles { - method esSolista() = true - method habilidadExtra() = if (self.esSolista()) 0 else -20 - } - - program prueba { - new VocalistaPopular(30, null, null) - } - '''.interpretPropagatingErrorsWithoutStaticChecks - } - - @Test - def void multipleInheritanceForConstructors4() { - ''' - class Musico { - var habilidadBase - var grupo = '' - const albumes = #{} - constructor() { } - constructor ( _habilidadBase) { - habilidadBase = _habilidadBase - } - } - - class MusicoConRoles inherits Musico { - var rolInterpretador - var rolCobrador - method internalInterpretaBien(cancion) = rolInterpretador.interpretaBien(cancion) - method cobra(presentacion) = rolCobrador.cobra(presentacion) - } - - class VocalistaPopular inherits MusicoConRoles { - method esSolista() = true - method habilidadExtra() = if (self.esSolista()) 0 else -20 - } - - program prueba { - new VocalistaPopular(100) - new VocalistaPopular() - } - '''.interpretPropagatingErrorsWithoutStaticChecks - } - - @Test - def void namedParametersWithNumbers() { - ''' - class Point { - var x - var y - } - program t { - console.println(new Point(x = 1, y = 2)) - } - '''.interpretPropagatingErrors - } - - @Test - def void namedParametersWithLiterals() { - ''' - object chayanne { - method nombre() = "Chayanne" - } - class Presentacion { - var fecha - var property cantante - var property localidades - } - program t { - const presentacion = new Presentacion(fecha = new Date(), cantante = chayanne, localidades = [100, 50, 200]) - console.println(presentacion) - assert.equals(chayanne, presentacion.cantante()) - assert.equals(350, presentacion.localidades().sum()) - } - '''.interpretPropagatingErrors - } - - @Test - def void namedParametersWithInheritance() { - ''' - object chayanne { - method nombre() = "Chayanne" - } - object lunaPark {} - class Evento { - var fecha - } - class EventoLocalizado inherits Evento { - var lugar - method lugar() = lugar - } - class Presentacion inherits EventoLocalizado { - var property cantante - var property localidades - } - program t { - const presentacion = new Presentacion( - lugar = lunaPark, - fecha = new Date(), - cantante = chayanne, - localidades = [100, 50, 200] - ) - console.println(presentacion) - assert.equals(chayanne, presentacion.cantante()) - assert.equals(350, presentacion.localidades().sum()) - assert.equals(presentacion.lugar(), lunaPark) - } - '''.interpretPropagatingErrors - } -} From 43b63378b908dce21034cbeeef2aaeae6f2c8534 Mon Sep 17 00:00:00 2001 From: ivan Date: Wed, 30 Oct 2019 13:28:34 -0300 Subject: [PATCH 075/133] float to WollokObject conversion works --- org.uqbar.project.wollok.lib/src/wollok/game/WSound.xtend | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/org.uqbar.project.wollok.lib/src/wollok/game/WSound.xtend b/org.uqbar.project.wollok.lib/src/wollok/game/WSound.xtend index 3523ffb2a2..4c06b23659 100644 --- a/org.uqbar.project.wollok.lib/src/wollok/game/WSound.xtend +++ b/org.uqbar.project.wollok.lib/src/wollok/game/WSound.xtend @@ -39,7 +39,7 @@ class WSound extends AbstractJavaWrapper { } def WollokObject volume() { - getWrapped.volume().doubleValue.convertJavaToWollok //Converts to double since a Float to Wollok convertion doesn't work. + getWrapped.volume().convertJavaToWollok } def void shouldLoop(Boolean looping) { From 64ad705e8a3250bd1fcacc19c9b6aa26bcd23507 Mon Sep 17 00:00:00 2001 From: ivan Date: Wed, 30 Oct 2019 13:37:46 -0300 Subject: [PATCH 076/133] name of paused getter and game.sound() description --- .../org/uqbar/project/wollok/game/gameboard/GameSound.xtend | 2 +- org.uqbar.project.wollok.lib/src/wollok/game.wlk | 4 ++-- org.uqbar.project.wollok.lib/src/wollok/game/WSound.xtend | 4 ++-- .../typesystem/annotations/WollokGameTypeDeclarations.xtend | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/org.uqbar.project.wollok.game/src/org/uqbar/project/wollok/game/gameboard/GameSound.xtend b/org.uqbar.project.wollok.game/src/org/uqbar/project/wollok/game/gameboard/GameSound.xtend index cfe4cac60e..d2492766fc 100644 --- a/org.uqbar.project.wollok.game/src/org/uqbar/project/wollok/game/gameboard/GameSound.xtend +++ b/org.uqbar.project.wollok.game/src/org/uqbar/project/wollok/game/gameboard/GameSound.xtend @@ -53,7 +53,7 @@ class GameSound { paused = false } - def isPaused() { + def paused() { paused } diff --git a/org.uqbar.project.wollok.lib/src/wollok/game.wlk b/org.uqbar.project.wollok.lib/src/wollok/game.wlk index 10d9cc48f7..1e34cc4335 100644 --- a/org.uqbar.project.wollok.lib/src/wollok/game.wlk +++ b/org.uqbar.project.wollok.lib/src/wollok/game.wlk @@ -242,7 +242,7 @@ object game { method errorReporter(visual) native /** - * Returns a sound object + * Returns a sound object. Audio file must be a .mp3, .ogg or .wav file. */ method sound(audioFile) { return new Sound(file=audioFile) @@ -507,7 +507,7 @@ class Sound { /** * Answers whether the sound is paused or not. */ - method isPaused() native + method paused() native /** * Changes absolute volume, values must be between 0 and 1. diff --git a/org.uqbar.project.wollok.lib/src/wollok/game/WSound.xtend b/org.uqbar.project.wollok.lib/src/wollok/game/WSound.xtend index 4c06b23659..53a9b5d779 100644 --- a/org.uqbar.project.wollok.lib/src/wollok/game/WSound.xtend +++ b/org.uqbar.project.wollok.lib/src/wollok/game/WSound.xtend @@ -30,8 +30,8 @@ class WSound extends AbstractJavaWrapper { getWrapped.resume() } - def WollokObject isPaused(){ - getWrapped.isPaused().convertJavaToWollok + def WollokObject paused(){ + getWrapped.paused().convertJavaToWollok } def void volume(WollokObject newVolume) { diff --git a/org.uqbar.project.wollok.typeSystem/src/org/uqbar/project/wollok/typesystem/annotations/WollokGameTypeDeclarations.xtend b/org.uqbar.project.wollok.typeSystem/src/org/uqbar/project/wollok/typesystem/annotations/WollokGameTypeDeclarations.xtend index 5bae9d11a7..9bef271409 100644 --- a/org.uqbar.project.wollok.typeSystem/src/org/uqbar/project/wollok/typesystem/annotations/WollokGameTypeDeclarations.xtend +++ b/org.uqbar.project.wollok.typeSystem/src/org/uqbar/project/wollok/typesystem/annotations/WollokGameTypeDeclarations.xtend @@ -69,7 +69,7 @@ class WollokGameTypeDeclarations extends TypeDeclarations { Sound >> "played" === #[] => Boolean Sound >> "stop" === #[] => Void Sound >> "pause" === #[] => Void - Sound >> "isPaused" === #[] => Boolean + Sound >> "paused" === #[] => Boolean Sound >> "resume" === #[] => Void Key >> "onPressDo" === #[closure(#[], Void)] => Void From 3c51b5a4009a0d6a581da994e5e1ac9e6aa93576 Mon Sep 17 00:00:00 2001 From: Fernando Dodino Date: Wed, 30 Oct 2019 18:00:39 -0300 Subject: [PATCH 077/133] Describe / Test refactored to wollok-language! --- .../interpreter/NamedObjectsTestCase.xtend | 24 -- .../interpreter/TestDescribeTestCase.xtend | 228 +--------------- .../tests/interpreter/TestTestCase.xtend | 250 ------------------ 3 files changed, 1 insertion(+), 501 deletions(-) diff --git a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/NamedObjectsTestCase.xtend b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/NamedObjectsTestCase.xtend index a5d9812a07..9cd0639ea1 100644 --- a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/NamedObjectsTestCase.xtend +++ b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/NamedObjectsTestCase.xtend @@ -54,28 +54,4 @@ class NamedObjectsTestCase extends AbstractWollokInterpreterTestCase { '''.interpretPropagatingErrors } - @Test - def void referencingObject() { - ''' - object pp { - const ps = [pepita] - - method unMethod(){ - var x = pepita - return x - } - - method getPs(){ - return ps - } - } - - object pepita {} - - program xxx{ - pp.unMethod() - assert.equals(pepita, pp.getPs().get(0)) - } - '''.interpretPropagatingErrors - } } diff --git a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/TestDescribeTestCase.xtend b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/TestDescribeTestCase.xtend index 3b02e3c783..25771fb028 100644 --- a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/TestDescribeTestCase.xtend +++ b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/TestDescribeTestCase.xtend @@ -11,93 +11,6 @@ import org.uqbar.project.wollok.interpreter.core.WollokProgramExceptionWrapper */ class TestDescribeTestCase extends AbstractWollokInterpreterTestCase { - @Test - def void testFixture() { - ''' - class Golondrina { - var energia = 100 - method energia() = energia - method volar(metros) { energia -= metros * 4 } - method comer(comida) { energia += comida.energia() } - } - - object alpiste { - method energia() = 5 - } - - describe "pepita cuando está gorda" { - const pepita = new Golondrina() - - fixture { - (1..100).forEach({ n => pepita.comer(alpiste) }) - } - - test "pepita quedo gorda, vuela un poco para bajar de peso" { - assert.equals(600, pepita.energia()) - pepita.volar(25) - assert.equals(500, pepita.energia()) - } - - test "pepita sigue gorda en el proximo test" { - assert.equals(600, pepita.energia()) - } - } - '''.interpretPropagatingErrors - } - - // Test describe tests - @Test - def void describeCanGroupASetOfIsolatedTestsWithoutState() { - ''' - describe "pruebas generales" { - test "Max between 5 and 8" { - assert.equals(8, 5.max(8)) - } - test "Min between 5 and 8" { - assert.equals(5, 5.min(8)) - } - } - '''.interpretPropagatingErrors - } - - @Test - def void describeCanGroupASetOfIsolatedTestsWithLocalVariables() { - ''' - describe "pruebas generales" { - test "Max between 5 and 8" { - const a = 8 - const b = 5 - const result = 5.max(8) - assert.equals(8, result) - } - test "Min between 5 and 8" { - const a = 8 - const b = 5 - const result = 5.min(8) - assert.equals(5, result) - } - } - '''.interpretPropagatingErrors - } - - @Test - def void describeCanGroupASetOfIsolatedTestsWithInstanceVariables() { - ''' - describe "pruebas generales" { - const a = 8 - const b = 5 - - test "Max between 5 and 8" { - const result = 5.max(8) - assert.equals(8, result) - } - test "Min between 5 and 8" { - assert.equals(5, 5.min(8)) - } - } - '''.interpretPropagatingErrors - } - @Test(expected=AssertionError) def void testShouldNotUseSameVariableDefinedInDescribe() { ''' @@ -117,45 +30,7 @@ class TestDescribeTestCase extends AbstractWollokInterpreterTestCase { } '''.interpretPropagatingErrors } - @Test - def void testWithMethodInvocation() { - ''' - describe "pruebas generales" { - const one = 1 - - method uno() = 1 - - test "Uno es one" { - assert.equals(one, self.uno()) - } - } - '''.interpretPropagatingErrors - } - @Test - def void testVariableOfDescribeDoesntHaveSideEffectsBetweenTests() { - ''' - describe "pruebas generales" { - var one = 1 - - method sumarOne() { - one = one + 1 - } - - method uno() = 1 - - test "Dos es one + 1" { - self.sumarOne() - assert.equals(one, self.uno() + 1) - } - - test "Uno es one" { - assert.equals(one, self.uno()) - } - } - '''.interpretPropagatingErrors - } - @Test(expected=WollokProgramExceptionWrapper) def void testFixtureErrorBreaksTestsInDescribe() { ''' @@ -184,105 +59,4 @@ class TestDescribeTestCase extends AbstractWollokInterpreterTestCase { '''.interpretPropagatingErrors } - @Test(expected=AssertionError) - def void testConstReferencesCannotBeDefinedInAFixture() { - ''' - describe "conjunto de tests re locos" { - - fixture { - const uno = 1 - } - - test "uno es uno" { - assert.equals(1, uno) - } - - } - '''.interpretPropagatingErrors - } - - @Test - def void testConstReferencesCannotBeAssignedInAFixture() { - ''' - describe "conjunto de tests que prueban que se puede inicializar adicionalmente en el fixture" { - - const uno = 1 - - fixture { - uno = 1 - } - - test "uno es uno" { - assert.equals(1, uno) - } - - } - '''.interpretPropagatingErrors - } - - @Test - def void testConstReferencesCanBeInitiallyAssignedInAFixture() { - ''' - describe "conjunto de tests re locos" { - - const uno - - fixture { - uno = 1 - } - - test "uno es uno" { - assert.equals(1, uno) - } - - } - '''.interpretPropagatingErrors - } - - @Test - def void testIssue1221NPEForConstDefinedInFixtures() { - ''' - class Enfermo {} - - class Doctor { - var calidad = 0 - method calidad() = calidad - method calidad(_calidad) { calidad = _calidad } - method cura(alguien) { calidad = calidad + 1 } - } - - describe "issue 1223" { - var unDoctorCualquiera - var enfermo - - fixture { - enfermo = new Enfermo() - unDoctorCualquiera = new Doctor() - unDoctorCualquiera.calidad(2) - } - - test "si un doctor cura a un enfermo, la calidad del doctor aumenta" { - const calidadInicial = unDoctorCualquiera.calidad() - unDoctorCualquiera.cura(enfermo) - const calidadFinal = unDoctorCualquiera.calidad() - assert.that(calidadFinal > calidadInicial) - } - - } - '''.interpretPropagatingErrors - } - - @Test - def void failingTestWhenInitializingAllVariablesAtOnce() { - ''' - describe "hola" { - test "hola" { - const unSet = #{} - unSet.add(1) - const seed = unSet.anyOne() - console.println(seed) - } - } - '''.interpretPropagatingErrors - } -} \ No newline at end of file +} diff --git a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/TestTestCase.xtend b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/TestTestCase.xtend index 112df3c481..69667bc99b 100644 --- a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/TestTestCase.xtend +++ b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/TestTestCase.xtend @@ -11,256 +11,6 @@ import static extension org.uqbar.project.wollok.errorHandling.WollokExceptionEx */ class TestTestCase extends AbstractWollokInterpreterTestCase { - @Test - def void simpleTest() { - ''' - test "1 + 1 es 2" { - assert.equals(2, 1 + 1) - } - '''.interpretPropagatingErrors - } - - @Test - def void testWithAssertsOk() { - ''' - object pepita { - var energia = 0 - method come(cantidad){ - energia = energia + cantidad * 10 - } - method energia(){ - return energia - } - } - - program p { - assert.that(pepita.energia() == 0) - assert.equals(0, pepita.energia()) - - pepita.come(10) - assert.equals(100, pepita.energia()) - } - '''.interpretPropagatingErrors - } - - @Test - def void testWithAssertEqualsWithErrors() { - ''' - object pepita { - var energia = 0 - method come(cantidad){ - energia = energia + cantidad * 10 - } - method energia(){ - return energia - } - } - - program pepitao { - try { - assert.equals(7, pepita.energia()) - assert.fail("should have failed") - } - catch e { - assert.equals("Expected [7] but found [0]", e.message()) - } - } - '''.interpretPropagatingErrors - } - - @Test(expected = AssertionError) - def void testWithAssertsWithErrors() { - ''' - object pepita { - var energia = 0 - method come(cantidad){ - energia = energia + cantidad * 10 - } - method energia(){ - return energia - } - } - - program p { - tester.assert(7 == pepita.energia()) - } - '''.interpretPropagatingErrors - } - - @Test(expected = AssertionError) - def void testWithExpectedExceptionWithErrors() { - ''' - program p { - assert.throwsException { 4 } - } - '''.interpretPropagatingErrors - } - - @Test - def void testWithExpectedExceptionWithoutErrors() { - ''' - program p { - assert.throwsException { - const x = null - x.foo() - } - } - '''.interpretPropagatingErrors - } - - @Test - def void testsAreIsolatedInTermsOfStateWKO() { - ''' - object globalin { - var a = 10 - method a(nuevo) { a = nuevo } - method a() = a - } - test "Changing a to 20" { - assert.equals(10, globalin.a()) - globalin.a(20) - assert.equals(20, globalin.a()) - } - test "Is back in 10 and change it to 30" { - // starts with 10 again ! - assert.equals(10, globalin.a()) - globalin.a(30) - assert.equals(30, globalin.a()) - } - test "Changing a to 10" { - // starts with 10 again ! - assert.equals(10, globalin.a()) - } - '''.interpretPropagatingErrors - } - - @Test - def void throwsSpecialKindOfExceptionCatchTheSpecifiedException() { - ''' - class BusinessException inherits wollok.lang.Exception { - constructor() {} - } - test "Use throwsExceptionLike" { - assert.throwsExceptionLike(new BusinessException(), { => throw new BusinessException() }) - } - '''.interpretPropagatingErrors - } - - @Test - def void throwsSpecialKindOfExceptionFailsWhenCatchTheSpecifiedExceptionButWithOtherMessage() { - ''' - class BusinessException inherits wollok.lang.Exception { - constructor(_message) {message = _message} - } - test "Use throwsExceptionLike" { - try { - assert.throwsExceptionLike(new BusinessException("chau"), { => throw new BusinessException("hola") }) - } - catch ex { - assert.equals(ex.message(), 'The Exception expected was a BusinessException[message="chau", cause=null] but got a BusinessException[message="hola", cause=null]') - } - } - '''.interpretPropagatingErrors - } - - @Test - def void throwsSpecialKindOfExceptionDontCatchOtherException() { - ''' - class BusinessException inherits wollok.lang.Exception { - constructor() {} - } - class OtherBusinessException inherits wollok.lang.Exception { - constructor() {} - } - program a { - try { - assert.throwsExceptionLike(new BusinessException(), { => throw new OtherBusinessException() }) - } - catch ex { - assert.equals(ex.message(), "The Exception expected was a BusinessException[message=null, cause=null] but got a OtherBusinessException[message=null, cause=null]") - } - } - '''.interpretPropagatingErrors - } - @Test - - def void throwsSpecialKindOfExceptionFailsWhenBlockDontThrownAnException() { - ''' - class BusinessException inherits wollok.lang.Exception { - constructor() {} - } - program a { - try { - assert.throwsExceptionLike(new BusinessException(), { => console.println("Works great!")}) - } - catch ex { - assert.equals("Should have thrown an exception", ex.message()) - } - } - '''.interpretPropagatingErrors - } - - @Test - def void throwsExceptionExpectsADesiredMessage (){ - ''' - class BusinessException inherits wollok.lang.Exception { - constructor(_message) {message = _message} - } - test "Use throwsExceptionWithMessage" { - assert.throwsExceptionWithMessage("hola!", { => throw new BusinessException("hola!") }) - } - '''.interpretPropagatingErrors - } - - @Test - def void throwsExceptionExpectsADesiredMessageButGotOther (){ - ''' - class BusinessException inherits wollok.lang.Exception { - } - test "Use throwsExceptionWithMessage" { - try { - assert.throwsExceptionWithMessage("hola!", { => throw new BusinessException(message = "Jamaica") }) - } - catch ex { - assert.equals("The error message expected was hola! but got Jamaica", ex.message()) - } - } - '''.interpretPropagatingErrors - } - - @Test - def void throwsExceptionExpectsADesiredExceptionClassWithDifferentMessages (){ - ''' - class BusinessException inherits wollok.lang.Exception { - } - test "Use throwsExceptionWithType" { - assert.throwsExceptionWithType(new BusinessException(message = "lala"), { => throw new BusinessException(message = "hola!") }) - } - '''.interpretPropagatingErrors - } - - @Test - def void throwsExceptionExpectsADesiredExceptionClassButGotOther (){ - #['excepciones' -> ''' - class BusinessException inherits wollok.lang.Exception { - } - class OtherException inherits wollok.lang.Exception { - } - ''', - 'programa' -> ''' - import excepciones.* - test "Use throwsExceptionWithType" { - try { - assert.throwsExceptionWithType(new BusinessException(message = "hola!"), { => throw new OtherException(message = "hola!") }) - } - catch ex { - assert.equals("The exception expected was excepciones.BusinessException but got excepciones.OtherException", ex.message()) - } - } - ''' - ].interpretPropagatingErrors - } - @Test def void cannotResolveReferenceIssue1376() { try { From cb31d5c523061828e4afdaef3914e318469f4cf2 Mon Sep 17 00:00:00 2001 From: nicovio Date: Wed, 30 Oct 2019 21:09:19 -0300 Subject: [PATCH 078/133] PR review changes --- .../wollok/ui/quickfix/QuickFixUtils.xtend | 28 +++++++++---------- .../quickfix/WollokDslQuickfixProvider.xtend | 3 +- .../project/wollok/utils/StringUtils.xtend | 4 +++ .../project/wollok/utils/WEclipseUtils.xtend | 3 +- 4 files changed, 21 insertions(+), 17 deletions(-) diff --git a/org.uqbar.project.wollok.ui/src/org/uqbar/project/wollok/ui/quickfix/QuickFixUtils.xtend b/org.uqbar.project.wollok.ui/src/org/uqbar/project/wollok/ui/quickfix/QuickFixUtils.xtend index c26c634c14..bd8fcebb04 100644 --- a/org.uqbar.project.wollok.ui/src/org/uqbar/project/wollok/ui/quickfix/QuickFixUtils.xtend +++ b/org.uqbar.project.wollok.ui/src/org/uqbar/project/wollok/ui/quickfix/QuickFixUtils.xtend @@ -19,6 +19,7 @@ import static org.uqbar.project.wollok.WollokConstants.* import static extension org.uqbar.project.wollok.model.WMethodContainerExtensions.* import static extension org.uqbar.project.wollok.model.WollokModelExtensions.* import static extension org.uqbar.project.wollok.utils.XTextExtensions.* +import static extension org.uqbar.project.wollok.utils.StringUtils.* /** * Provides utilities for quickfixes. @@ -196,29 +197,26 @@ class QuickFixUtils { } def static void removeRedundantImports(IXtextDocument it, List imports, String importToAdd) { - val withoutRedundant = imports.withoutRedundant(importToAdd) - if (imports.size > withoutRedundant.size) { - if (withoutRedundant.isEmpty) { - removeImports(imports, 2) - } else { - removeImports(imports, 0) - } - relocateImports(withoutRedundant, imports.head.before) + val essentialImports = imports.essentialImports(importToAdd) + val extraSpace = if(essentialImports.isEmpty) 2 else 0 + if (imports.size > essentialImports.size) { + removeImports(imports, extraSpace) + relocateImports(essentialImports, imports.head.before) } } - - def static removeImports(IXtextDocument it, List imports, int extraEspace) { + + def static removeImports(IXtextDocument it, List imports, int extraSpace) { val firstImportPosition = imports.head.before - replace(firstImportPosition, imports.last.after - firstImportPosition + extraEspace, "") + replace(firstImportPosition, imports.last.after - firstImportPosition + extraSpace, "") } - def static List withoutRedundant(List imports, String importToAdd) { + def static List essentialImports(List imports, String importToAdd) { val importsNames = imports.map[anImport|anImport.importedNamespace] val Set wildCardImports = wildcardImports(importsNames) val Set importsNamesSet = newHashSet - wildCardImports.add(importToAdd.substring(0, importToAdd.lastIndexOf("."))) + wildCardImports.add(importToAdd.getPackage) importsNames.filter [ importName | - val path = importName.substring(0, importName.lastIndexOf(".")) + val path = importName.getPackage() (!wildCardImports.contains(path) && importsNamesSet.add(importName)) || importName.substring(importName.lastIndexOf(".")).equals(".*") ].toList @@ -228,7 +226,7 @@ class QuickFixUtils { imports.filter [ importName | importName.substring(importName.lastIndexOf(".")).equals(".*") ].map [ importName | - importName.substring(0, importName.lastIndexOf(".")) + importName.getPackage ].toSet } diff --git a/org.uqbar.project.wollok.ui/src/org/uqbar/project/wollok/ui/quickfix/WollokDslQuickfixProvider.xtend b/org.uqbar.project.wollok.ui/src/org/uqbar/project/wollok/ui/quickfix/WollokDslQuickfixProvider.xtend index e80d8f77fd..e133f4df8d 100644 --- a/org.uqbar.project.wollok.ui/src/org/uqbar/project/wollok/ui/quickfix/WollokDslQuickfixProvider.xtend +++ b/org.uqbar.project.wollok.ui/src/org/uqbar/project/wollok/ui/quickfix/WollokDslQuickfixProvider.xtend @@ -43,6 +43,7 @@ import static extension org.uqbar.project.wollok.model.WMethodContainerExtension import static extension org.uqbar.project.wollok.model.WollokModelExtensions.* import static extension org.uqbar.project.wollok.ui.quickfix.QuickFixUtils.* import static extension org.uqbar.project.wollok.utils.XTextExtensions.* +import static extension org.uqbar.project.wollok.utils.StringUtils.* import org.uqbar.project.wollok.scoping.WollokGlobalScopeProvider import org.eclipse.osgi.util.NLS @@ -639,7 +640,7 @@ class WollokDslQuickfixProvider extends DefaultQuickfixProvider { val objectName = xtextDocument.get(issue.offset, issue.length) scope.matchingImports(objectName).forEach [ importName | - val nameWithWildcard = importName.substring(0, importName.lastIndexOf(".")) + ".*" + val nameWithWildcard = importName.getPackage + ".*" issueResolutionAcceptor.accept(issue, NLS.bind(Messages.WollokDslQuickFixProvider_add_import_name, nameWithWildcard), NLS.bind(Messages.WollokDslQuickFixProvider_add_import_description, nameWithWildcard), diff --git a/org.uqbar.project.wollok/src/org/uqbar/project/wollok/utils/StringUtils.xtend b/org.uqbar.project.wollok/src/org/uqbar/project/wollok/utils/StringUtils.xtend index 8f4f759351..279f10de5d 100644 --- a/org.uqbar.project.wollok/src/org/uqbar/project/wollok/utils/StringUtils.xtend +++ b/org.uqbar.project.wollok/src/org/uqbar/project/wollok/utils/StringUtils.xtend @@ -62,5 +62,9 @@ class StringUtils { static def singularOrPlural(int amount, String text, String pluralText) { if (amount === 1) text else pluralText } + + static def getPackage(String name) { + name.substring(0, name.lastIndexOf(".")) + } } diff --git a/org.uqbar.project.wollok/src/org/uqbar/project/wollok/utils/WEclipseUtils.xtend b/org.uqbar.project.wollok/src/org/uqbar/project/wollok/utils/WEclipseUtils.xtend index 213d7633af..9a84d72866 100644 --- a/org.uqbar.project.wollok/src/org/uqbar/project/wollok/utils/WEclipseUtils.xtend +++ b/org.uqbar.project.wollok/src/org/uqbar/project/wollok/utils/WEclipseUtils.xtend @@ -43,6 +43,7 @@ import org.eclipse.xtext.ui.editor.XtextEditor import org.eclipse.xtext.ui.editor.model.XtextDocumentUtil import static org.uqbar.project.wollok.WollokConstants.* +import static extension org.uqbar.project.wollok.utils.StringUtils.* /** * Utilities on top of eclipse platform. @@ -181,7 +182,7 @@ class WEclipseUtils { def static ObjectInputStream asObjectInputStream(File file) { new ObjectInputStream(new FileInputStream(file)) } def static nameWithoutExtension(IResource it) { - if(name.contains(".")) name.substring(0, name.lastIndexOf('.')) else name + if(name.contains(".")) name.getPackage else name } def static openEditor(ITextEditor textEditor, String fileName, int lineNumber) { From ead356bdda7065adc49582eef955e2cf0e1e7f76 Mon Sep 17 00:00:00 2001 From: nicovio Date: Wed, 30 Oct 2019 21:14:16 -0300 Subject: [PATCH 079/133] refactor getPackage method in StringUtils --- .../src/org/uqbar/project/wollok/utils/StringUtils.xtend | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/org.uqbar.project.wollok/src/org/uqbar/project/wollok/utils/StringUtils.xtend b/org.uqbar.project.wollok/src/org/uqbar/project/wollok/utils/StringUtils.xtend index 279f10de5d..2a9f567b7a 100644 --- a/org.uqbar.project.wollok/src/org/uqbar/project/wollok/utils/StringUtils.xtend +++ b/org.uqbar.project.wollok/src/org/uqbar/project/wollok/utils/StringUtils.xtend @@ -64,7 +64,7 @@ class StringUtils { } static def getPackage(String name) { - name.substring(0, name.lastIndexOf(".")) + name.copyUptoLast(".") } } From 8e8bbd1882029fea76de72bea83abac1b17a7c0f Mon Sep 17 00:00:00 2001 From: PalumboN Date: Thu, 31 Oct 2019 16:54:45 -0300 Subject: [PATCH 080/133] Gamoboard.colliders --- .../uqbar/project/wollok/game/gameboard/Gameboard.xtend | 4 ++++ .../project/wollok/game/listeners/CollisionListener.xtend | 8 ++------ .../src/wollok/game/GameObject.xtend | 5 +---- 3 files changed, 7 insertions(+), 10 deletions(-) diff --git a/org.uqbar.project.wollok.game/src/org/uqbar/project/wollok/game/gameboard/Gameboard.xtend b/org.uqbar.project.wollok.game/src/org/uqbar/project/wollok/game/gameboard/Gameboard.xtend index 7fbcaee662..2914ba28ec 100644 --- a/org.uqbar.project.wollok.game/src/org/uqbar/project/wollok/game/gameboard/Gameboard.xtend +++ b/org.uqbar.project.wollok.game/src/org/uqbar/project/wollok/game/gameboard/Gameboard.xtend @@ -123,6 +123,10 @@ class Gameboard { def alreadyInGame(WollokObject wObject) { findComponentFor(wObject) !== null } + + def colliders(VisualComponent component) { + component.position.getComponentsInPosition.clone.filter[it.WObject != component.WObject] + } // Getters & Setters diff --git a/org.uqbar.project.wollok.game/src/org/uqbar/project/wollok/game/listeners/CollisionListener.xtend b/org.uqbar.project.wollok.game/src/org/uqbar/project/wollok/game/listeners/CollisionListener.xtend index d292129452..19e36e0585 100644 --- a/org.uqbar.project.wollok.game/src/org/uqbar/project/wollok/game/listeners/CollisionListener.xtend +++ b/org.uqbar.project.wollok.game/src/org/uqbar/project/wollok/game/listeners/CollisionListener.xtend @@ -15,11 +15,7 @@ class CollisionListener extends GameboardListener { override notify(Gameboard gameboard) { if (gameboard.alreadyInGame(component.WObject)) - gameboard.colliders.forEach[collide] - } - - def colliders(Gameboard gameboard) { // TODO: Move to Gameboard - gameboard.getComponentsInPosition(component.position).clone.filter[it != component] + gameboard.colliders(component).forEach[collide] } def collide(VisualComponent it) { @@ -42,7 +38,7 @@ class InstantCollisionListener extends CollisionListener { override notify(Gameboard gameboard) { super.notify(gameboard) - lastColliders = gameboard.colliders.toList + lastColliders = gameboard.colliders(component).toList } override collide(VisualComponent it) { diff --git a/org.uqbar.project.wollok.lib/src/wollok/game/GameObject.xtend b/org.uqbar.project.wollok.lib/src/wollok/game/GameObject.xtend index eef1e25750..fce98da8bd 100644 --- a/org.uqbar.project.wollok.lib/src/wollok/game/GameObject.xtend +++ b/org.uqbar.project.wollok.lib/src/wollok/game/GameObject.xtend @@ -126,10 +126,7 @@ class GameObject { def colliders(WollokObject visual) { visual.checkNotNull("colliders") val visualObject = board.findVisual(visual) - board.getComponentsInPosition(visualObject.position) - .filter [ !it.equals(visualObject)] - .map [ it.WObject ] - .toList.javaToWollok + board.colliders(visualObject).map[ WObject ].toList.javaToWollok } def say(WollokObject visual, String message) { From 5fd8a453c065986f47b9f8d50c91ec5ebd44ce64 Mon Sep 17 00:00:00 2001 From: Fernando Dodino Date: Thu, 31 Oct 2019 18:56:52 -0300 Subject: [PATCH 081/133] Mixins test case moved to wollok-language! --- .../interpreter/mixins/MixinsTestCase.xtend | 499 ------------------ 1 file changed, 499 deletions(-) diff --git a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/mixins/MixinsTestCase.xtend b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/mixins/MixinsTestCase.xtend index 60e9d42f52..945885fb46 100644 --- a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/mixins/MixinsTestCase.xtend +++ b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/mixins/MixinsTestCase.xtend @@ -9,505 +9,6 @@ import org.junit.Test */ class MixinsTestCase extends AbstractWollokInterpreterTestCase { - @Test - def void simpleMixinWithMethod() { - ''' - mixin Flies { - method fly() { - console.println("I'm flying") - } - } - class Bird mixed with Flies {} - program t { - const b = new Bird() - b.fly() - } - '''.interpretPropagatingErrors - } - - @Test - def void classWithMixinThatModifiesTheMixinStateFromTheMixin() { - ''' - mixin Walks { - var walkedDistance = 0 - method walk(distance) { - walkedDistance += distance - } - method walkedDistance() = walkedDistance - } - class WalkingBird mixed with Walks {} - - program t { - const b = new WalkingBird() - b.walk(10) - assert.equals(10, b.walkedDistance()) - } - '''.interpretPropagatingErrors - } - - // is it ok to have 'protected' variables ? - // this is inconsistent with the way wollok handles variables in classes in a hierarchy - @Test - def void classModifiesAVariableInheritedFromTheMixin() { - ''' - mixin Energy { - var energy = 100 - } - - class Bird mixed with Energy { - method fly(meters) { - energy -= meters - } - method energy() = energy - } - program t { - const b = new Bird() - b.fly(10) - assert.equals(90, b.energy()) - } - '''.interpretPropagatingErrors - } - - @Test - def void simpleMultipleMixins() { - ''' - mixin M1 {} - mixin M2 {} - - class C mixed with M1 and M2 { - } - program t { - const b = new C() - } - '''.interpretPropagatingErrors - } - - @Test - def void classWithTwoIsolatedMixins() { - ''' - mixin Energy { - var energy = 100 - method energy() = energy - } - - mixin Mojo { - var mojo = 0 - method mojo() = mojo - } - - class Bird mixed with Energy, Mojo { - method fly(meters) { - energy -= meters - mojo += 1 - } - - } - program t { - const b = new Bird() - b.fly(10) - assert.equals(90, b.energy()) - assert.equals(1, b.mojo()) - - b.fly(10) - assert.equals(80, b.energy()) - assert.equals(2, b.mojo()) - } - '''.interpretPropagatingErrors - } - - @Test - def void classWithAMixinThatCallsAnother() { - ''' - mixin Energy { - var energy = 100 - method energy() = energy - method reduceEnergy(amount) { - energy -= amount - } - } - - mixin Flying { - var fliedMeters = 0 - method fly(meters) { - self.reduceEnergy(meters) - fliedMeters += meters - } - method fliedMeters() = fliedMeters - - method reduceEnergy(meters) - } - - class BirdWithEnergyThatFlies mixed with Energy, Flying {} - - // order doesn't matter - - class BirdWithThatFliesWithEnergy mixed with Flying, Energy {} - - program t { - const b = new BirdWithEnergyThatFlies() - b.fly(10) - assert.equals(90, b.energy()) - assert.equals(10, b.fliedMeters()) - - const b2 = new BirdWithThatFliesWithEnergy() - b2.fly(10) - assert.equals(90, b2.energy()) - assert.equals(10, b2.fliedMeters()) - } - '''.interpretPropagatingErrors - } - - @Test - def void mixinMethodCallsAMethodOnTheClass() { - ''' - mixin FlyingShortcuts { - method fly100Meters() { - self.fly(100) - } - method fly(meters) - } - - class BirdWithFlyingShortCuts mixed with FlyingShortcuts { - var energy = 200 - override method fly(meters) { energy -= meters } - method energy() = energy - } - - program t { - const b = new BirdWithFlyingShortCuts() - b.fly100Meters() - assert.equals(100, b.energy()) - } - '''.interpretPropagatingErrors - } - - @Test - def void mixinMethodCallsAMethodOnTheClassThatIsInherited() { - ''' - class Bird { - var energy = 200 - method fly(meters) { energy -= meters } - method energy() = energy - } - - mixin FlyingShortcuts { - method fly100Meters() { - self.fly(100) - } - method fly(meters) - } - - class MockingBird inherits Bird mixed with FlyingShortcuts { - } - - program t { - const b = new MockingBird() - b.fly100Meters() - assert.equals(100, b.energy()) - } - '''.interpretPropagatingErrors - } - - @Test - def void classOverridesMethodFromMixin() { - ''' - mixin Energy { - var energy = 100 - method reduceEnergy(amount) { energy -= amount } - method energy() = energy - } - - class Bird mixed with Energy { - override method reduceEnergy(amount) { - // does nothing - } - } - - program t { - const b = new Bird() - b.reduceEnergy(100) - assert.equals(100, b.energy()) - } - '''.interpretPropagatingErrors - } - - @Test - def void classOverridesMethodFromMixinAndCallSuper() { - ''' - mixin Energy { - var energy = 100 - method reduceEnergy(amount) { energy -= amount } - method energy() = energy - } - - class Bird mixed with Energy { - override method reduceEnergy(amount) { - super(1) - } - } - - program t { - const b = new Bird() - b.reduceEnergy(100) - assert.equals(99, b.energy()) - } - '''.interpretPropagatingErrors - } - - @Test - def void stackableMixinsPattern() { - ''' - mixin M1 { - method doFoo(chain) { super(chain + " > M1") } - } - - mixin M2 { - method doFoo(chain) { super(chain + "> M2") } - } - - class C1 { - var foo = "" - method doFoo(chain) { foo = chain + " > C1" } - method foo() = foo - } - - class C2 inherits C1 mixed with M1, M2 { - } - - program t { - const c = new C2() - c.doFoo("Test ") - assert.equals("Test > M2 > M1 > C1", c.foo()) - } - '''.interpretPropagatingErrors - } - - @Test - def void mixinsCallingSuperMixedInAClassWithoutImplementingItMakesItAbstract() { - ''' - mixin Organic { - method dehydratate() = super() + " an organic" - } - - class Tomato mixed with Organic {} - - program tomatoEater { - const t = new Tomato() - try { - t.dehydratate() - } - catch e:MessageNotUnderstoodException { - assert.equals("a Tomato[] (WollokObject) does not understand dehydratate()", e.message()) - assert.equals("wollok.lang.MessageNotUnderstoodException: a Tomato[] (WollokObject) does not understand dehydratate() - at __synthetic0.Organic.dehydratate() [__synthetic0.wpgm] - at [__synthetic0.wpgm] - ", e.getStackTraceAsString()) - } - } - '''.interpretPropagatingErrorsWithoutStaticChecks - } - - @Test - def void mixinOnAWKO() { - ''' - mixin Flies { - var times = 0 - method fly() { - times = 1 - } - method times() = times - } - - object pepita mixed with Flies {} - - program t { - pepita.fly() - assert.equals(1, pepita.times()) - } - '''.interpretPropagatingErrors - } - - @Test - def void mixinVariablesAreInScopeOnAWKO() { - ''' - mixin Flies { - var times = 0 - method fly() { - times = 1 - } - method times() = times - } - - object pepita mixed with Flies { - method rest() { - times = 0 - } - } - - program t { - pepita.fly() - assert.equals(1, pepita.times()) - pepita.rest() - assert.equals(0, pepita.times()) - } - '''.interpretPropagatingErrors - } - @Test - def void mixinOnAWKOOverridingAMethod() { - ''' - mixin Flies { - var times = 0 - method fly() { - times = 1 - } - method times() = times - } - - object pepita mixed with Flies { - override method fly() {} - } - - program t { - pepita.fly() - assert.equals(0, pepita.times()) - } - '''.interpretPropagatingErrors - } - - @Test - def void classMixedCallsInheritedMethodFromMixinWithSelf() { - ''' - mixin Flies { - var times = 0 - method fly() { - times += 1 - } - method times() = times - } - - class Bird mixed with Flies { - method doubleFly() { - self.fly() - self.fly() - } - } - - program t { - const pepita = new Bird() - pepita.doubleFly() - assert.equals(2, pepita.times()) - } - '''.interpretPropagatingErrors - } - - - // OBJECT LITERALS - - @Test - def void mixinOnObjectLiterals() { - ''' - mixin Flies { - var times = 0 - method fly() { - times = 1 - } - method times() = times - } - - program t { - const pepita = object mixed with Flies {} - pepita.fly() - assert.equals(1, pepita.times()) - } - '''.interpretPropagatingErrors - } - - @Test - def void mixinOnObjectLiteralOverridingAMethod() { - ''' - mixin Flies { - var times = 0 - method fly() { - times = 1 - } - method times() = times - } - - program t { - const pepita = object mixed with Flies { - override method fly() {} - } - pepita.fly() - assert.equals(0, pepita.times()) - } - '''.interpretPropagatingErrors - } - - // mixing at instantiation - - @Test - def void singleMixinAtInstantiationTime() { - ''' - mixin Energy { - var energy = 100 - method energy() = energy - } - class Warrior { - - } - program t { - const w = new Warrior() with Energy - assert.equals(100, w.energy()) - } - '''.interpretPropagatingErrors - } - - - @Test - def void multipleMixinAtInstantiationTime() { - ''' - mixin Energy { - var energy = 100 - method energy() = energy - method energy(e) { energy = e } - } - mixin GetsHurt { - method receiveDamage(amount) { - self.energy(self.energy() - amount) - } - method energy() - method energy(newEnergy) - } - - mixin Attacks { - var power = 10 - method attack(other) { - other.receiveDamage(power) - self.energy(self.energy() - 1) - } - method power() = power - method power(p) { power = p } - - method energy() - method energy(newEnergy) - } - class Warrior { - - } - program t { - const warrior1 = new Warrior() with Attacks with Energy with GetsHurt - assert.equals(100, warrior1.energy()) - - const warrior2 = new Warrior() with Attacks with Energy with GetsHurt - assert.equals(100, warrior2.energy()) - - warrior1.attack(warrior2) - - assert.equals(90, warrior2.energy()) - assert.equals(99, warrior1.energy()) - } - '''.interpretPropagatingErrors - } def String toStringFixture() { ''' From ae74bb347ec6b8903977abd687719e4529b3254b Mon Sep 17 00:00:00 2001 From: Fernando Dodino Date: Thu, 31 Oct 2019 19:33:29 -0300 Subject: [PATCH 082/133] Assert test cases moved to wollok-language! --- .../wollok/tests/asserts/AssertTestCase.xtend | 131 ------------------ 1 file changed, 131 deletions(-) delete mode 100644 org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/asserts/AssertTestCase.xtend diff --git a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/asserts/AssertTestCase.xtend b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/asserts/AssertTestCase.xtend deleted file mode 100644 index 34f34cfdb5..0000000000 --- a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/asserts/AssertTestCase.xtend +++ /dev/null @@ -1,131 +0,0 @@ -package org.uqbar.project.wollok.tests.asserts - -import org.junit.Test -import org.uqbar.project.wollok.tests.interpreter.AbstractWollokInterpreterTestCase -import org.junit.ComparisonFailure - -class AssertTestCase extends AbstractWollokInterpreterTestCase { - - @Test - def void assertUsingPrintString() { - ''' - assert.throwsExceptionWithMessage('Expected [[true]] but found ["[true]"]', { assert.equals([true], "[true]") }) - '''.test - } - - @Test - def void assertWhenNotTrueFails() { - ''' - assert.throwsExceptionLike(new AssertionException(message = "Value was not true"),{ => assert.that(false) } ) - '''.test - } - - @Test - def void assertNotWhenNotFalseFails() { - ''' - assert.throwsExceptionLike(new AssertionException(message = "Value was not false"),{ => assert.notThat(true) } ) - '''.test - } - - @Test - def void assertWithOneParameterShouldFail() { - ''' - assert.throwsExceptionLike( - new AssertionException(message = "assert.equals(expected, actual): missing second parameter"), - { => assert.equals(4) } - ) - '''.test - } - - @Test - def void assertEqualsWhenEqualsWorks() { - ''' - assert.equals(4, 4) - '''.test - } - - @Test - def void assertEqualsWhenNotEqualsFails() { - ''' - assert.throwsExceptionLike(new AssertionException(message = "Expected [2] but found [4]"),{ => assert.equals(2, 4) } ) - '''.test - } - - @Test - def void assertDifferentWhenEqualsFails() { - ''' - assert.throwsExceptionLike(new AssertionException(message = "Expected to be different, but [4] and [4] match"),{ => assert.notEquals(4, 4) } ) - '''.test - } - - @Test - def void assertDifferentWhenDifferentWorks() { - ''' - assert.notEquals(4, 5) - '''.test - } - - @Test - def void failure() { - ''' - assert.throwsExceptionLike(new AssertionException(message = "Kaboom"),{ => assert.fail("Kaboom") } ) - '''.test - } - - @Test(expected = ComparisonFailure) - def void assertIsTranslatedToComparisonFailure(){ - ''' - assert.equals(1, "hola") - '''.test - } - - @Test - def void thatUsingNullMustFail() { - ''' - assert.throwsExceptionWithMessage("Operation that doesn't support null parameters", { => assert.that(null) }) - '''.test - } - - @Test - def void notThatUsingNullMustFail() { - ''' - assert.throwsExceptionWithMessage("Operation notThat doesn't support null parameters", { => assert.notThat(null) }) - '''.test - } - - @Test - def void throwsExceptionUsingNullMustFail() { - ''' - assert.throwsExceptionWithMessage("Operation throwsException doesn't support null parameters", { => assert.throwsException(null) }) - '''.test - } - - @Test - def void throwsExceptionLikeUsingNullMustFail() { - ''' - assert.throwsExceptionWithMessage("Operation throwsExceptionLike doesn't support null parameters", { => assert.throwsExceptionLike(null, null) }) - '''.test - } - - @Test - def void throwsExceptionWithMessageUsingNullMustFail() { - ''' - assert.throwsExceptionWithMessage("Operation throwsExceptionWithMessage doesn't support null parameters", { => assert.throwsExceptionWithMessage(null, null) }) - '''.test - } - - @Test - def void throwsExceptionWithTypeUsingNullMustFail() { - ''' - assert.throwsExceptionWithMessage("Operation throwsExceptionWithType doesn't support null parameters", { => assert.throwsExceptionWithType(null, null) }) - '''.test - } - - @Test - def void throwsExceptionByComparingUsingNullMustFail() { - ''' - assert.throwsExceptionWithMessage("Operation throwsExceptionByComparing doesn't support null parameters", { => assert.throwsExceptionByComparing(null, null) }) - '''.test - } - -} \ No newline at end of file From cbad363c41088759d7882517118215735ccf3a54 Mon Sep 17 00:00:00 2001 From: Fernando Dodino Date: Thu, 31 Oct 2019 19:46:40 -0300 Subject: [PATCH 083/133] Global constants moved to wollok-language! --- .../wollok/tests/game/ArrowListenerTest.xtend | 9 --- .../interpreter/GlobalConstantsTestCase.xtend | 75 ------------------- 2 files changed, 84 deletions(-) delete mode 100644 org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/GlobalConstantsTestCase.xtend diff --git a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/game/ArrowListenerTest.xtend b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/game/ArrowListenerTest.xtend index fd2a9a3880..427da70f39 100644 --- a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/game/ArrowListenerTest.xtend +++ b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/game/ArrowListenerTest.xtend @@ -73,15 +73,6 @@ class ArrowListenerTest { Assert.assertEquals(new WGPosition(1, 0), character.position) } -// @Test -// def when_right_key_is_pressed_character_move_right_2() { -// character.position = new WGPosition(4, 4) -// this.press("RIGHT") -// -// arrowListener.notify(gameboard) -// Assert.assertEquals(new WGPosition(4, 4), character.position) -// } - def press(String key) { when(keyboard.isKeyPressed(new Keyboard().getKey(key))).thenReturn(true) } diff --git a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/GlobalConstantsTestCase.xtend b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/GlobalConstantsTestCase.xtend deleted file mode 100644 index 8f69d8b9a3..0000000000 --- a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/GlobalConstantsTestCase.xtend +++ /dev/null @@ -1,75 +0,0 @@ -package org.uqbar.project.wollok.tests.interpreter - -import org.junit.Test - -class GlobalConstantsTestCase extends AbstractWollokInterpreterTestCase { - - @Test - def void effects() { - #[ - ''' - class Golondrina { - var energy = 0 - method energyLevel(){ - return energy - } - - method addEnergy(amount){ - energy = energy + amount - } - } - - const pepita = new Golondrina() - - program globalConstants { - assert.equals(0, pepita.energyLevel()) - pepita.addEnergy(10) - assert.equals(10, pepita.energyLevel()) - } - ''' - ].interpretPropagatingErrors - } - - @Test - def void references() { - ''' - class Golondrina { - var property energia = 0 - - method entrenar() { energia += 1 } - } - - class Entrenador { - const property ave - method entrenar() { ave.entrenar() } - } - - const chuck = new Entrenador(ave = pepita) - - const pepita = new Golondrina() - - program xxx { - assert.equals(0, pepita.energia()) - chuck.entrenar() - assert.equals(1, pepita.energia()) - } - '''.interpretPropagatingErrors - } - - @Test - def void testWithGlobalConstants() { - ''' - object wollok { - method numero() = numeroLoco - } - - const numeroLoco = 87 - - describe "Tests" { - test "Numero loco es 87" { - assert.equals(87, numeroLoco) - } - } - '''.interpretPropagatingErrors - } -} From 0e92b5ac2817f430088824fa56f401baa3fc0229 Mon Sep 17 00:00:00 2001 From: Fernando Dodino Date: Thu, 31 Oct 2019 19:56:25 -0300 Subject: [PATCH 084/133] Named object tests moved to wollok-language! --- .../interpreter/NamedObjectsTestCase.xtend | 57 ------------------- 1 file changed, 57 deletions(-) delete mode 100644 org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/NamedObjectsTestCase.xtend diff --git a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/NamedObjectsTestCase.xtend b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/NamedObjectsTestCase.xtend deleted file mode 100644 index 9cd0639ea1..0000000000 --- a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/NamedObjectsTestCase.xtend +++ /dev/null @@ -1,57 +0,0 @@ -package org.uqbar.project.wollok.tests.interpreter - -import org.junit.Test - -class NamedObjectsTestCase extends AbstractWollokInterpreterTestCase { - @Test - def void effects() { - #[ - ''' - object pepita { - var energy = 0 - method energyLevel(){ - return energy - } - - method addEnergy(amount){ - energy = energy + amount - } - } - - program namedObjects{ - assert.equals(0, pepita.energyLevel()) - pepita.addEnergy(10) - assert.equals(10, pepita.energyLevel()) - } - ''' - ].interpretPropagatingErrors - } - - @Test - def unusedVariables() { - val model = ''' - object pepita { - var energia = 0 - method getEnergia(){ return energia } - method setEnergia(x){ energia = x } - } - '''.parse - - model.assertNoIssues - } - - @Test - def void usingSelf() { - ''' - object pepita { - method uno(){ - return self.otro() - } - method otro(){ - return 5 - } - } - '''.interpretPropagatingErrors - } - -} From 205861a347addf76e73883e94c408ef43fcdd083 Mon Sep 17 00:00:00 2001 From: Fernando Dodino Date: Thu, 31 Oct 2019 20:34:04 -0300 Subject: [PATCH 085/133] Pair tests moved to wollok-language! --- .../tests/interpreter/PairTestCase.xtend | 112 ------------------ 1 file changed, 112 deletions(-) delete mode 100644 org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/PairTestCase.xtend diff --git a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/PairTestCase.xtend b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/PairTestCase.xtend deleted file mode 100644 index 1be28beb6c..0000000000 --- a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/PairTestCase.xtend +++ /dev/null @@ -1,112 +0,0 @@ -package org.uqbar.project.wollok.tests.interpreter - -import org.junit.Test - -class PairTestCase extends AbstractWollokInterpreterTestCase { - - @Test - def void smokeTest() { - ''' - const pair = new Pair(1, 1) - assert.equals(pair, pair) - '''.test - } - - @Test - def void testNewContructor() { - ''' - const pair = new Pair(1, 2) - assert.equals(1, pair.x()) - assert.equals(2, pair.y()) - '''.test - } - - @Test - def void testArrowContructor() { - ''' - const pair = 1->2 - assert.equals(1, pair.x()) - assert.equals(2, pair.y()) - '''.test - } - - @Test - def void testXGetter() { - ''' - const pair = "1"->2 - assert.equals("1", pair.x()) - '''.test - } - - @Test - def void testYGetter() { - ''' - const pair = 1->"2" - assert.equals("2", pair.y()) - '''.test - } - - @Test - def void testXSetterThrowsCannotModifyConstantPropertyException() { - ''' - const pair = 1->2 - assert.throwsExceptionWithMessage("Cannot modify constant property x", { pair.x(10) }) - '''.test - } - - @Test - def void testYSetterThrowsCannotModifyConstantPropertyException() { - ''' - const pair = 1->2 - assert.throwsExceptionWithMessage("Cannot modify constant property y", { pair.y(20) }) - '''.test - } - - @Test - def void testKeyGetter() { - ''' - const pair = 10->20 - assert.equals(10, pair.key()) - '''.test - } - - @Test - def void testValueGetter() { - ''' - const pair = 10->20 - assert.equals(20, pair.value()) - '''.test - } - - @Test - def void testKeySetterThrowsMessageNotUnderstoodException() { - ''' - const pair = 1->2 - assert.throwsExceptionWithType(new MessageNotUnderstoodException(), { pair.key(10) }) - '''.test - } - - @Test - def void testValueSetterThrowsMessageNotUnderstoodException() { - ''' - const pair = 1->2 - assert.throwsExceptionWithType(new MessageNotUnderstoodException(), { pair.value(20) }) - '''.test - } - - @Test - def void testToStringRepresentation() { - ''' - const pair = 10->20 - assert.equals("10 -> 20", pair.toString()) - '''.test - } - - @Test - def void testShortDescriptionRepresentation() { - ''' - const pair = 10->20 - assert.equals("10 -> 20", pair.shortDescription()) - '''.test - } -} \ No newline at end of file From 1adbc5994f21514cad81d51fd9f209080230c3bf Mon Sep 17 00:00:00 2001 From: Fernando Dodino Date: Fri, 1 Nov 2019 07:00:08 -0300 Subject: [PATCH 086/133] Using hard links instead of soft links, changed appveyor script and moved StringPrinter tests to wollok-language --- appveyor.yml | 2 - .../src/wollok/game.wlk | 472 ++- .../src/wollok/lang.wlk | 2757 ++++++++++++++++- .../src/wollok/lib.wlk | 254 +- .../src/wollok/mirror.wlk | 14 +- .../src/wollok/vm.wlk | 4 +- .../interpreter/StringPrinterTestCase.xtend | 35 - .../{ => language}/RuntimeTest.xtend | 4 +- .../libraries/WollokLibExtensionsTest.xtend | 5 +- .../WollokMultiInterpreterTest.xtend | 10 +- 10 files changed, 3506 insertions(+), 51 deletions(-) mode change 120000 => 100644 org.uqbar.project.wollok.lib/src/wollok/game.wlk mode change 120000 => 100644 org.uqbar.project.wollok.lib/src/wollok/lang.wlk mode change 120000 => 100644 org.uqbar.project.wollok.lib/src/wollok/lib.wlk mode change 120000 => 100644 org.uqbar.project.wollok.lib/src/wollok/mirror.wlk mode change 120000 => 100644 org.uqbar.project.wollok.lib/src/wollok/vm.wlk delete mode 100644 org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/StringPrinterTestCase.xtend rename org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/{ => language}/RuntimeTest.xtend (54%) diff --git a/appveyor.yml b/appveyor.yml index 3fc7a70738..2fab658b84 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -16,8 +16,6 @@ install: - cmd: SET MAVEN_OPTS=-XX:MaxPermSize=2g -Xmx4g - cmd: SET JAVA_OPTS=-XX:MaxPermSize=2g -Xmx4g - cmd: SET M2_HOME=C:\maven\apache-maven-3.2.5 - # - cmd: for %%I in (.\*.wlk) do (MKLINK "wollok-language\src\wollok\%%I" "org.uqbar.project.wollok.lib\src\wollok\%%I") - - cmd: copy /Y wollok-language\src\wollok\*.wlk org.uqbar.project.wollok.lib\src\wollok build_script: - cd org.uqbar.project.wollok.releng/ - mvn clean install -U -Darguments='-Dtycho.disableP2Mirrors=true' -Dtycho.disableP2Mirrors=true diff --git a/org.uqbar.project.wollok.lib/src/wollok/game.wlk b/org.uqbar.project.wollok.lib/src/wollok/game.wlk deleted file mode 120000 index 78a671621a..0000000000 --- a/org.uqbar.project.wollok.lib/src/wollok/game.wlk +++ /dev/null @@ -1 +0,0 @@ -../../../wollok-language/src/wollok/game.wlk \ No newline at end of file diff --git a/org.uqbar.project.wollok.lib/src/wollok/game.wlk b/org.uqbar.project.wollok.lib/src/wollok/game.wlk new file mode 100644 index 0000000000..dc00c52465 --- /dev/null +++ b/org.uqbar.project.wollok.lib/src/wollok/game.wlk @@ -0,0 +1,471 @@ +import wollok.vm.runtime + +/** + * Wollok Game main object + */ +object game { + + /** + * Adds an object to the board for drawing it. + * Object should understand a position property + * (implemented by a reference or getter method). + * + * Example: + * game.addVisual(pepita) ==> pepita should have a position property + */ + method addVisual(positionable) native + + /** + * Adds an object to the board for drawing it on a specific position. + * + * Example: + * game.addVisualIn(pepita, game.origin()) ==> no need for pepita to have a position property + * game.addVisualIn(pepita, game.at(2, 2)) + */ + method addVisualIn(element, position) native + + + /** + * Adds an object to the board for drawing it. It can be moved with arrow keys. + * That object should understand a position property + * (implemented by a reference or getter method). + * + * Example: + * game.addVisualCharacter(pepita) ==> pepita should have a position property + */ + method addVisualCharacter(positionable) native + + /** + * Adds an object to the board for drawing it on a specific position. It can be moved with arrow keys. + * + * Example: + * game.addVisualCharacterIn(pepita, game.origin()) ==> no need for pepita to have a position property + */ + method addVisualCharacterIn(element, position) native + + /** + * Removes an object from the board for stop drawing it. + * + * Example: + * game.removeVisual(pepita) + */ + method removeVisual(visual) native + + /** + * Verifies if an object is currently in the board. + * + * Example: + * game.hasVisual(pepita) + */ + method hasVisual(visual) native + + /** + * Returns all visual objects added to the board. + * + * Example: + * game.allVisuals() + */ + method allVisuals() native + + /** + * Adds a block that will be executed each time a specific key is pressed + * @see keyboard.onPressDo() + */ + method whenKeyPressedDo(key, action) native + + /** + * Adds a block that will be executed while the given object collides with other. + * Two objects collide when are in the same position. + * + * The block should expect the other object as parameter. + * + * Example: + * game.whenCollideDo(pepita, { comida => pepita.comer(comida) }) + */ + method whenCollideDo(visual, action) native + + /** + * Adds a block that will be executed exactly when the given object collides with other. + * Two objects collide when are in the same position. + * + * The block should expect the other object as parameter. + * + * Example: + * game.onCollideDo(pepita, { comida => pepita.comer(comida) }) + */ + method onCollideDo(visual, action) native + + /** + * Adds a block with a specific name that will be executed every n milliseconds. + * Block expects no argument. + * Be careful not to set it too often :) + * + * Example: + * game.onTick(5000, "pepitaMoving", { => pepita.position().x(0.randomUpTo(4)) }) + */ + method onTick(milliseconds, name, action) native + + /** + * Adds a block that will be executed in n milliseconds. + * Block expects no argument. + * + * Example: + * game.schedule(5000, { => pepita.position().x(0.randomUpTo(4)) }) + */ + method schedule(milliseconds, action) native + + /** + * Remove a tick event created with onTick message + * + * Example: + * game.removeTickEvent("pepitaMoving") + */ + method removeTickEvent(name) native + + /** + * Returns all objects in given position. + * + * Example: + * game.getObjectsIn(game.origin()) + */ + method getObjectsIn(position) native + + /** + * Draws a dialog balloon with given message in given visual object position. + * + * Example: + * game.say(pepita, "hola!") + */ + method say(visual, message) native + + /** + * Removes all visual objects on board and configurations (colliders, keys, etc). + */ + method clear() native + + /** + * Returns all objects that are in same position of given object. + */ + method colliders(visual) native + + /** + * Returns the unique object that is in same position of given object. + */ + method uniqueCollider(visual) = self.colliders(visual).uniqueElement() + + /** + * Stops render the board and finish the game. + */ + method stop() native + + /** + * Starts render the board in a new windows. + */ + method start() { + self.doStart(runtime.isInteractive()) + } + + /** + * Returns a position for given coordinates. + */ + method at(x, y) { + return new Position(x = x, y = y) + } + + /** + * Returns the position (0,0). + */ + method origin() = self.at(0, 0) + + /** + * Returns the center board position (rounded down). + */ + method center() = self.at(self.width().div(2), self.height().div(2)) + + /** + * Sets game title. + */ + method title(title) native + + /** + * Returns game title. + */ + method title() native + + /** + * Sets board width (in cells). + */ + method width(width) native + + /** + * Returns board width (in cells). + */ + method width() native + + /** + * Sets board height (in cells). + */ + method height(height) native + + /** + * Returns board height (in cells). + */ + method height() native + + /** + * Sets cells background image. + */ + method ground(image) native + + /** + * Sets full background image. + */ + method boardGround(image) native + + /** + * Attributes will not show when user mouse over a visual component. + * Default behavior is to show them. + */ + method hideAttributes(visual) native + + /** + * Attributes will appear again when user mouse over a visual component. + * Default behavior is to show them, so this is not necessary. + */ + method showAttributes(visual) native + + /** + * Allows to configure a visual component as "error reporter". + * Then every error in game board will be reported by this visual component, + * in a balloon message form. + */ + method errorReporter(visual) native + + /** + * Plays once a .mp3, .ogg or .wav audio file + */ + method sound(audioFile) native + + /** + * @private + */ + method doStart(isRepl) native +} + +/** + * Represents a position in a two-dimensional gameboard. + * It is an immutable object since Wollok 1.8.0 + */ +class Position { + const property x = 0 + const property y = 0 + + /** + * Returns a new Position n steps right from this one. + */ + method right(n) = new Position(x = x + n, y = y) + + /** + * Returns a new Position n steps left from this one. + */ + method left(n) = new Position(x = x - n, y = y) + + /** + * Returns a new Position n steps up from this one. + */ + method up(n) = new Position(x = x, y = y + n) + + /** + * Returns a new Position, n steps down from this one. + */ + method down(n) = new Position(x = x, y = y - n) + + /** + * Adds an object to the board for drawing it in self. + */ + method drawElement(element) { game.addVisualIn(element, self) } //TODO: Implement native + + /** + * Adds an object to the board for drawing it in self. It can be moved with arrow keys. + */ + method drawCharacter(element) { game.addVisualCharacterIn(element, self) } //TODO: Implement native + + /** + * Draw a dialog balloon with given message in given visual object position. + */ + method say(element, message) { game.say(element, message) } //TODO: Implement native + + /** + * Returns all objects in self. + */ + method allElements() = game.getObjectsIn(self) //TODO: Implement native + + /** + * Returns a new position with same coordinates. + */ + method clone() = new Position(x = x, y = y) + + /** + * Returns the distance between given position and self. + */ + method distance(position) { + self.checkNotNull(position, "distance") + const deltaX = x - position.x() + const deltaY = y - position.y() + return (deltaX.square() + deltaY.square()).squareRoot() + } + + /** + * Removes all objects in self from the board for stop drawing it. + */ + method clear() { + self.allElements().forEach{it => game.removeVisual(it)} + } + + /** + * Two positions are equals if they have same coordinates. + */ + override method ==(other) = x == other.x() && y == other.y() + + /** + * String representation of a position + */ + override method toString() = "(" + x + "," + y + ")" + +} + +/** + * Keyboard object handles all keys movements. There is a method for each key. + * + * Examples: + * keyboard.i().onPressDo { game.say(pepita, "hola!") } + * => when user hits "i" key, pepita will say "hola!" + * + * keyboard.any().onPressDo { game.say(pepita, "you pressed a key!") } + * => any key pressed will activate its closure + */ +object keyboard { + + method any() = new Key(keyCodes = [-1]) + + method num(n) = new Key(keyCodes = [n + 7, n + 144]) + + method num0() = self.num(0) + + method num1() = self.num(1) + + method num2() = self.num(2) + + method num3() = self.num(3) + + method num4() = self.num(4) + + method num5() = self.num(5) + + method num6() = self.num(6) + + method num7() = self.num(7) + + method num8() = self.num(8) + + method num9() = self.num(9) + + method a() = new Key(keyCodes = [29]) + + method alt() = new Key(keyCodes = [57, 58]) + + method b() = new Key(keyCodes = [30]) + + method backspace() = new Key(keyCodes = [67]) + + method c() = new Key(keyCodes = [31]) + + method control() = new Key(keyCodes = [129, 130]) + + method d() = new Key(keyCodes = [32]) + + method del() = new Key(keyCodes = [67]) + + method center() = new Key(keyCodes = [23]) + + method down() = new Key(keyCodes = [20]) + + method left() = new Key(keyCodes = [21]) + + method right() = new Key(keyCodes = [22]) + + method up() = new Key(keyCodes = [19]) + + method e() = new Key(keyCodes = [33]) + + method enter() = new Key(keyCodes = [66]) + + method f() = new Key(keyCodes = [34]) + + method g() = new Key(keyCodes = [35]) + + method h() = new Key(keyCodes = [36]) + + method i() = new Key(keyCodes = [37]) + + method j() = new Key(keyCodes = [38]) + + method k() = new Key(keyCodes = [39]) + + method l() = new Key(keyCodes = [40]) + + method m() = new Key(keyCodes = [41]) + + method minusKey() = new Key(keyCodes = [69]) + + method n() = new Key(keyCodes = [42]) + + method o() = new Key(keyCodes = [43]) + + method p() = new Key(keyCodes = [44]) + + method plusKey() = new Key(keyCodes = [81]) + + method q() = new Key(keyCodes = [45]) + + method r() = new Key(keyCodes = [46]) + + method s() = new Key(keyCodes = [47]) + + method shift() = new Key(keyCodes = [59, 60]) + + method slash() = new Key(keyCodes = [76]) + + method space() = new Key(keyCodes = [62]) + + method t() = new Key(keyCodes = [48]) + + method u() = new Key(keyCodes = [49]) + + method v() = new Key(keyCodes = [50]) + + method w() = new Key(keyCodes = [51]) + + method x() = new Key(keyCodes = [52]) + + method y() = new Key(keyCodes = [53]) + + method z() = new Key(keyCodes = [54]) + +} + + +class Key { + const property keyCodes + + /** + * Adds a block that will be executed always self is pressed. + * + * Example: + * keyboard.i().onPressDo { game.say(pepita, "hola!") } + * => when user hits "i" key, pepita will say "hola!" + */ + method onPressDo(action) { + keyCodes.forEach{ key => game.whenKeyPressedDo(key, action) } //TODO: Implement native + } +} diff --git a/org.uqbar.project.wollok.lib/src/wollok/lang.wlk b/org.uqbar.project.wollok.lib/src/wollok/lang.wlk deleted file mode 120000 index 6a158a00d3..0000000000 --- a/org.uqbar.project.wollok.lib/src/wollok/lang.wlk +++ /dev/null @@ -1 +0,0 @@ -../../../wollok-language/src/wollok/lang.wlk \ No newline at end of file diff --git a/org.uqbar.project.wollok.lib/src/wollok/lang.wlk b/org.uqbar.project.wollok.lib/src/wollok/lang.wlk new file mode 100644 index 0000000000..5d4a7e0ce2 --- /dev/null +++ b/org.uqbar.project.wollok.lib/src/wollok/lang.wlk @@ -0,0 +1,2756 @@ +/** + * Base class for all Exceptions. Every exception and its subclasses + * indicates conditions that a reasonable application might want to catch. + * + * @author jfernandes + * @since 1.0 + */ +class Exception { + /** specified detail message. */ + const property message = null + + /** specified cause */ + const property cause = null + + /** Prints this exception and its backtrace to the console */ + method printStackTrace() { self.printStackTrace(console) } + + /** Prints this exception and its backtrace as a string value */ + method getStackTraceAsString() { + const printer = new StringPrinter() + self.printStackTrace(printer) + return printer.getBuffer() + } + + /** + * @private + * Prints this exception and its backtrace to the specified printer + */ + method printStackTrace(printer) { self.printStackTraceWithPrefix("", printer) } + + /** @private */ + method printStackTraceWithPrefix(prefix, printer) { + printer.println(prefix + self.className() + (if (message != null) (": " + message.toString()) else "")) + + // TODO: eventually we will need a stringbuffer or something to avoid memory consumption + self.getStackTrace().forEach { e => + printer.println("\tat " + e.contextDescription() + " [" + e.location() + "]") + } + + if (cause != null) + cause.printStackTraceWithPrefix("Caused by: ", printer) + } + + /** @private */ + method createStackTraceElement(contextDescription, location) = new StackTraceElement(contextDescription = contextDescription, location = location) + + /** Provides programmatic access to the stack trace information + * printed by printStackTrace() with full path files for linking + */ + method getFullStackTrace() native + + /** Provides programmatic access to the stack trace information + * printed by printStackTrace(). + */ + method getStackTrace() native + + /** Overrides the behavior to compare exceptions */ + override method equals(other) = other.className().equals(self.className()) && other.message() == self.message() +} + +/** + * Thrown when a stack overflow occurs because an application recurses too deeply. + * + * @author jfernandes + * @since 1.5.1 + */ +class StackOverflowException inherits Exception {} + +/** + * An exception that is thrown when a specified element cannot be found + */ +class ElementNotFoundException inherits Exception {} + +/** + * An exception that is thrown for domain purpose + */ +class DomainException inherits Exception { + const property source = null +} + +/** + * (added by wollok-ts) An exception thrown whenever the interpreter fails to evaluate an expression + */ +class EvaluationError inherits Exception {} + +/** + * An exception that is thrown when an object cannot understand a certain message + */ +class MessageNotUnderstoodException inherits Exception {} + +/** + * An element in a stack trace, represented by a context and a location + * of a method where a message was sent + */ +class StackTraceElement { + const property contextDescription + const property location +} + +/** + * + * Representation of Wollok Object + * + * Class Object is the root of the class hierarchy. + * Every class has Object as a superclass. + * + * @author jfernandes + * since 1.0 + */ +class Object { + + /** + * Answers object identity of a Wollok object, represented by + * a unique number in Wollok environment + */ + method identity() native + + /** + * Answers a list of instance variables for this Wollok object + * @private - needed by wollok-xtext implementation + */ + method instanceVariables() native + + /** + * Retrieves a specific variable. Expects a name + * @private - needed by wollok-xtext implementation + */ + method instanceVariableFor(name) native + + /** + * Accesses a variable by name, in a reflexive way. + * @private - needed by wollok-xtext implementation + */ + method resolve(name) native + + /** Object description in english/spanish/... (depending on i18n configuration) + * + * Examples: + * "2".kindName() => Answers "a String" + * 2.kindName() => Answers "a Integer" + * + * @private + */ + method kindName() native + + /** + * Full name of Wollok object class + * @private + */ + method className() native + + /** + * Tells whether self object is "equal" to the given object + * The default behavior compares them in terms of identity (===) + */ + method ==(other) = other != null && self === other + + /** Tells whether self object is not equal to the given one */ + method !=(other) = ! (self == other) + + /** + * Tells whether self object is identical (the same) to the given one. + * It does it by comparing their identities. + * So self basically relies on the wollok.lang.Integer equality (which is native) + */ + method ===(other) = self.identity() == other.identity() + + /** + * Tells whether self object is not identical (the same) to the given one. + * @See === message. + */ + method !==(other) = ! (self === other) + + /** + * o1.equals(o2) is a synonym for o1 == o2 + */ + method equals(other) = self == other + + /** + * Generates a Pair key-value association. @see Pair. + */ + method ->(other) { + return new Pair(x = self, y = other) + } + + /** + * String representation of Wollok object + */ + method toString() { + return self.toSmartString([]) + } + + /** + * Shows a short, internal representation + */ + method shortDescription() = self.toString() + + /** + * Provides a visual representation of Wollok Object + * By default, same as toString but can be overridden + * like in String + */ + method printString() = self.toString() + + /** @private */ + method toSmartString(alreadyShown) { + if (alreadyShown.any { e => e.identity() == self.identity() } ) { + return self.simplifiedToSmartString() + } + else { + alreadyShown.add(self) + return self.internalToSmartString(alreadyShown) + } + } + + /** @private */ + method simplifiedToSmartString() = self.kindName() + + /** @private */ + method internalToSmartString(alreadyShown) { + return self.kindName() + "[" + + self.instanceVariables().map { v => + v.name() + "=" + v.valueToSmartString(alreadyShown) + }.join(', ') + + "]" + } + + /** @private */ + method messageNotUnderstood(messageName, parameters) { + const target = if (messageName != "toString") + self.toString() + else + self.kindName() + const aMessage = self.generateDoesNotUnderstandMessage(target, messageName, parameters.size()) + throw new MessageNotUnderstoodException(message = aMessage) + } + + /** + * @private + * + * internal method: generates a does not understand message + * parametersSize must be an integer value + */ + method generateDoesNotUnderstandMessage(target, messageName, parametersSize) native + + /** Builds an exception with a message */ + method error(aMessage) { + throw new DomainException(message = aMessage, source = self) + } + + /** @private */ + method checkNotNull(value, message) native +} + +/** Representation for methods that only have side effects */ +object void { } + +/** + * Representation of a Key/Value Association. + * It is also useful if you want to model a Point. + */ +class Pair { + const property x + const property y + constructor (_x, _y) { + x = _x + y = _y + } + method key() = x + method value() = y + + /** + * Two pairs are equal if they have the same values + * + * Example: + * new Pair(1, 2).equals(new Pair(1, 2)) ==> Answers true + */ + override method equals(other) { + self.checkNotNull(other, "equals") + return x == other.x() && y == other.y() + } + + /** String representation of a Pair */ + override method toString() = x.toString() + " -> " + y.toString() +} + +/** + * The root class in the collection hierarchy. + * A collection represents a group of objects, known as its elements. + */ +class Collection { + /** + * Answers the element that is considered to be/have the maximum value. + * The criteria is given by a closure that receives a single element + * as input (one of the element). The closure must return a comparable + * value (something that understands the >, >= messages). + * If collection is empty, an ElementNotFound exception is thrown. + * + * Example: + * ["a", "ab", "abc", "d" ].max({ e => e.length() }) + * => Answers "abc" + * + * [].max({ e => e.length() }) + * => Throws error, list must not be empty + */ + method max(closure) { + self.checkNotNull(closure, "max") + return self.maxIfEmpty(closure, { throw new ElementNotFoundException(message = "collection is empty") }) + } + + /** + * Answers the element that represents the maximum value in the collection. + * The criteria is by direct comparison of the elements. + * If collection is empty, an ElementNotFound exception is thrown. + * + * Example: + * [11, 1, 4, 8, 3, 15, 6].max() => Answers 15 + * [].max() => Throws error, list must not be empty + */ + method max() = self.max({it => it}) + + /** + * Answers the element that is considered to be/have the maximum value, + * or applies a closure if the collection is empty. + * The criteria is given by a closure that receives a single element + * as input (one of the element). The closure must return a comparable + * value (something that understands the >, >= messages). + * The closure to execute when the collection is empty is given as a second + * argument. + * + * Example: + * ["a", "ab", "abc", "d" ].maxIfEmpty({ e => e.length() }, { "default" }) + * => Answers "abc" + * + * [].maxIfEmpty({ e => e.length() }, { "default" }) + * => Answers "default" + */ + method maxIfEmpty(toComparableClosure, emptyCaseClosure) { + self.checkNotNull(toComparableClosure, "maxIfEmpty") + self.checkNotNull(emptyCaseClosure, "maxIfEmpty") + return self.absolute(toComparableClosure, { a, b => a > b }, emptyCaseClosure) + } + + /** + * Answers the element that is considered to be/have the maximum value, + * or applies a closure if the collection is empty. + * The criteria is by direct comparison of the elements. + * The closure to execute when the collection is empty is given as a second + * argument. + * + * Example: + * [11, 1, 4, 8, 3, 15, 6].maxIfEmpty({ 99 }) => Answers 15 + * [].maxIfEmpty({ 99 }) => Answers 99 + */ + method maxIfEmpty(emptyCaseClosure) = self.maxIfEmpty({it => it}, emptyCaseClosure) + + /** + * Answers the element that is considered to be/have the minimum value. + * The criteria is given by a closure that receives a single element + * as input (one of the element). The closure must return a comparable + * value (something that understands the <, <= messages). + * + * Example: + * ["ab", "abc", "hello", "wollok world"].min({ e => e.length() }) + * => Answers "ab" + * + * [].min({ e => e.length() }) + * => Throws error, list must not be empty + */ + method min(closure) { + self.checkNotNull(closure, "min") + return self.absolute(closure, { a, b => a < b }, { throw new ElementNotFoundException(message = "collection is empty") }) + } + + /** + * Answers the element that represents the minimum value in the + * non-empty collection. + * The criteria is by direct comparison of the elements. + * + * Example: + * [11, 1, 4, 8, 3, 15, 6].min() => Answers 1 + * [].min() => Throws error, list must not be empty + */ + method min() = self.min({it => it}) + + /** + * Answers the element that is considered to be/have the minimum value, + * or applies a closure if the collection is empty. + * The criteria is given by a closure that receives a single element + * as input (one of the element). The closure must return a comparable + * value (something that understands the >, >= messages). + * The closure to execute when the collection is empty is given as a second + * argument. + * + * Example: + * ["ab", "abc", "hello", "wollok world"].minIfEmpty({ e => e.length() }, { "default" }) + * => Answers "ab" + * + * [].minIfEmpty({ e => e.length() }, { "default" }) + * => Answers "default" + */ + method minIfEmpty(toComparableClosure, emptyCaseClosure) { + self.checkNotNull(toComparableClosure, "minIfEmpty") + self.checkNotNull(emptyCaseClosure, "minIfEmpty") + return self.absolute(toComparableClosure, { a, b => a < b }, emptyCaseClosure) + } + + /** + * Answers the element that is considered to be/have the minimum value, + * or applies a closure if the collection is empty. + * The criteria is by direct comparison of the elements. + * The closure to execute when the collection is empty is given as a second + * argument. + * + * Example: + * [11, 1, 4, 8, 3, 15, 6].minIfEmpty({ 99 }) => Answers 1 + * [].minIfEmpty({ 99 }) => Answers 99 + */ + method minIfEmpty(emptyCaseClosure) { + self.checkNotNull(emptyCaseClosure, "minIfEmpty") + return self.minIfEmpty({it => it}, emptyCaseClosure) + } + + /** @private */ + method absolute(closure, criteria, emptyCaseClosure) { + self.checkNotNull(closure, "absolute") + self.checkNotNull(criteria, "absolute") + self.checkNotNull(emptyCaseClosure, "absolute") + if (self.isEmpty()) { + return emptyCaseClosure.apply() + } + const result = self.fold(null, { acc, e => + const n = closure.apply(e) + if (acc == null) + e -> n + else { + if (criteria.apply(n, acc.y())) + e -> n + else + acc + } + }) + return result.x() + } + + /** + * Answers the unique element in the collection. + * If collection is empty, an error is thrown. + * If collection has more than one element, an error is thrown. + * + * Example: + * [1].uniqueElement() => Answers 1 + * [].uniqueElement() => Throws error, list must not be empty + * [1, 2].uniqueElement() => Throws error, list must have one element + */ + method uniqueElement() { + self.validateNotEmpty("uniqueElement") + const size = self.size() + if (size > 1) + throw new Exception(message = "Illegal operation 'uniqueElement' on collection with " + size.toString() + " elements") + return self.anyOne() + } + + + // non-native methods + + /** + * Concatenates this collection to all elements from the given + * collection parameter giving a new collection + * (no side effect) + * + * Example: + * [1, 2] + [3] => Answers [1, 2, 3] + * [1, 2] + #{3} => supports concatenation between lists and sets, answers [1, 2, 3] + * #{} + [] => Answers #{} + */ + method +(elements) { + const newCol = self.copy() + newCol.addAll(elements) + return newCol + } + + /** + * Adds all elements from the given collection parameter to self collection. + * This is a side effect operation. + * + * Example: + * const list = [] + * list.addAll(#{2, 4}) => list == [2, 4], always pointing to a list + */ + method addAll(elements) { + self.checkNotNull(elements, "addAll") + elements.forEach { element => self.add(element) } + } + + /** + * Removes all elements of the given collection parameter from self collection. + * This is a side effect operation. + * + * Example: + * const list = [1, 6, 5] + * list.removeAll([6]) => list == [1, 5] + */ + method removeAll(elements) { + self.checkNotNull(elements, "removeAll") + elements.forEach { element => self.remove(element) } + } + + /** + * Removes those elements that meet a given condition. + * This is a side effect operation. + * Supports empty collections. + * + * Example: + * const list = [1, 6, 5] + * list.removeAllSuchThat { e => e.even() } => list == [1, 5] + */ + method removeAllSuchThat(closure) { + self.checkNotNull(closure, "removeAllSuchThat") + self.removeAll( self.filter(closure) ) + } + + /** + * Tells whether self collection has no elements + * + * Example: + * [1, 6, 5].isEmpty() => Answers false + * [].isEmpty() => Answers true + */ + method isEmpty() = self.size() == 0 + + /** + * @private + * Throws error if self collection is empty + */ + method validateNotEmpty(operation) { + if (self.isEmpty()) + throw new Exception(message = "Illegal operation '" + operation + "' on empty collection") + } + + /** + * Performs an operation on every element of self collection. + * The logic to execute is passed as a closure that takes a single parameter. + * Supports empty collections. + * @returns nothing + * + * Example: + * plants.forEach { plant => plant.takeSomeWater() } + */ + method forEach(closure) { + self.checkNotNull(closure, "forEach") + self.fold(null, { seed, element => + closure.apply(element) + seed + }) + } + + /** + * Answers whether all the elements of self collection satisfy a given + * condition. The condition is a closure argument that takes a single + * element and answers a boolean value. + * + * @returns true/false + * + * Example: + * plants.all({ plant => plant.hasFlowers() }) + * [1, 3, 5].all { number => number.odd() } => Answers true + * [].all { number => number.odd() } => Answers true + */ + method all(predicate) { + self.checkNotNull(predicate, "all") + return self.fold(true, { seed, element => if (!seed) seed else predicate.apply(element) }) + } + + /** + * Tells whether at least one element of self collection satisfies a + * given condition. The condition is a closure argument that takes a + * single element and answers a boolean value. + * @returns true/false + * + * Example: + * plants.any({ plant => plant.hasFlowers() }) + * [1, 2, 3].any { number => number.even() } ==> Answers true + * [].any { number => number.even() } ==> Answers false + */ + method any(predicate) { + self.checkNotNull(predicate, "any") + return self.fold(false, { seed, element => if (seed) seed else predicate.apply(element) }) + } + + /** + * Answers the element of self collection that satisfies a given condition. + * If more than one element satisfies the condition then it depends + * on the specific collection class which element will be returned. + * + * @returns the element that complies the condition + * @throws ElementNotFoundException if no element matched the given predicate + * + * Example: + * users.find { user => user.name() == "Cosme Fulanito" } + * #{1, 4, 5}.find { number => number.even() } => Answers 4 + * #{1, 3}.find { number => number.even() } => Throws ElementNotFoundException + * #{}.find { number => number.even() } => Throws ElementNotFoundException + */ + method find(predicate) { + self.checkNotNull(predicate, "find") + return self.findOrElse(predicate, { + throw new ElementNotFoundException(message = "there is no element that satisfies the predicate") + }) + } + + /** + * Answers the element of self collection that satisfies a given condition, + * or the given default otherwise, if no element matched the predicate. + * If more than one element satisfies the condition then it depends on the specific + * collection class which element will be returned. + * + * @returns the element that complies the condition or the default value + * + * Example: + * users.findOrDefault({ user => user.name() == "Cosme Fulanito" }, homer) + * [1, 3, 5].findOrDefault({ number => number.even() }, 0) => Answers 0 + * [].findOrDefault({ number => number.even() }, 0) => Answers 0 + */ + method findOrDefault(predicate, value) = self.findOrElse(predicate, { value }) + + /** + * Answers the element of self collection that satisfies a given condition, + * or the the result of evaluating the given continuation. + * If more than one element satisfies the condition then it depends on the + * specific collection class which element will be returned. + * + * @returns the element that complies the condition or the result + * of evaluating the continuation + * + * Example: + * users.findOrElse({ user => user.name() == "Cosme Fulanito" }, { homer }) + * [1, 3, 5].findOrElse({ number => number.even() }, { 6.max(4) }) => Answers 6 + * [].findOrElse({ number => number.even() }, { false }) => Answers false + */ + method findOrElse(predicate, continuation) native + + /** + * Counts all elements of self collection that satisfies a given condition + * The condition is a closure argument that takes a single element and + * answers a number. + * @returns an integer number + * + * Example: + * plants.count { plant => plant.hasFlowers() } + * #{1, 2, 3, 4, 5}.count { number => number.odd() } => Answers 3 + * #{}.count { number => number.odd() } => Answers 0 + */ + method count(predicate) { + self.checkNotNull(predicate, "count") + return self.fold(0, { total, element => if (predicate.apply(element)) total+1 else total }) + } + + /** + * Counts the occurrences of a given element in self collection. + * @returns an integer number + * + * Example: + * [1, 8, 4, 1].occurrencesOf(1) => Answers 2 + * [].occurrencesOf(2) => Answers 0 + */ + method occurrencesOf(element) = self.count({it => it == element}) + + /** + * Collects the sum of each value for all elements. + * This is similar to call a map {} to transform each element into a + * number object and then adding all those numbers. + * The condition is a closure argument that takes a single element and + * answers a boolean value. + * + * @returns an integer + * + * Example: + * const totalNumberOfFlowers = plants.sum{ plant => plant.numberOfFlowers() } + * [].sum { employee => employee.salary() } => Answers 0 + */ + method sum(closure) { + self.checkNotNull(closure, "sum") + return self.fold(0, { total, element => total + closure.apply(element) }) + } + + /** + * Sums all elements in the collection. + * @returns an integer + * + * Example: + * [1, 2, 3, 4, 5].sum() => Answers 15 + * [].sum() => Answers 0 + */ + method sum() = self.sum( {it => it} ) + + /** + * Answers a new collection that contains the result of transforming + * each of self collection's elements using a given closure. + * The condition is a closure argument that takes a single element + * and answers an object. + * @returns another list + * + * Example: + * const ages = users.map({ user => user.age() }) + * [1, 2, 3].map { number => number.odd() } => Answers [true, false, true] + * [].map { number => number.odd() } => Answers [] + */ + method map(closure) { + self.checkNotNull(closure, "map") + return self.fold([], { newCollection, element => + newCollection.add(closure.apply(element)) + newCollection + }) + } + + /** + * Map + flatten operation + * @see map + * @see flatten + * + * Example: + * object klaus { + * method languages() = ["c", "cobol", "pascal"] + * } + * + * object fritz { + * method languages() = ["java", "perl"] + * } + * + * + * [klaus, fritz].flatMap({ person => person.languages() }) + * => Answers ["c", "cobol", "pascal", "java", "perl"] + */ + method flatMap(closure) { + self.checkNotNull(closure, "flatMap") + return self.fold(self.newInstance(), { flattenedList, element => + flattenedList.addAll(closure.apply(element)) + flattenedList + }) + } + + /** + * Answers a new collection that contains the elements that + * meet a given condition. The condition is a closure argument that + * takes a single element and answers a boolean. + * @returns another collection (same type as self one) + * + * Example: + * const overageUsers = users.filter({ user => user.age() >= 18 }) + * #{1, 2, 3, 4, 5}.filter { number => number.even() } => Answers #{2, 4} + * #{}.filter { number => number.even() } => Answers #{} + */ + method filter(closure) { + self.checkNotNull(closure, "filter") + return self.fold(self.newInstance(), { newCollection, element => + if (closure.apply(element)) + newCollection.add(element) + newCollection + }) + } + + /** + * Answers whether this collection contains the specified element. + * + * Example: + * [].contains(3) => Answers false + * [1, 2, 3].contains(2) => Answers true + */ + method contains(element) = self.any {one => element == one } + + /** + * Flattens a collection of collections + * + * Example: + * [ [1, 2], [3], [4, 0], [] ].flatten() => Answers [1, 2, 3, 4, 0] + * + */ + method flatten() = self.flatMap { it => it } + + /** @private */ + /* + * Optimized version for long collections + * + * @see Object#toString() + */ + override method internalToSmartString(alreadyShown) { + const size = self.size() + const internalCollection = if (size > 50) "..." + size + " elements" else self.map{ e => e.toSmartString(alreadyShown) }.join(", ") + return self.toStringPrefix() + internalCollection + self.toStringSuffix() + } + + /** @private */ + method toStringPrefix() + + /** @private */ + method toStringSuffix() + + /** Converts a collection to a list */ + method asList() + + /** Converts a collection to a set (removing duplicates if necessary) + * + * Examples: + * [1, 2, 3].asSet() => Answers #{1, 2, 3} + * [].asSet() => Answers #{} + * [1, 2, 1, 1, 2].asSet() => Answers #{1, 2} + * + * #{1, 2, 3}.asSet() => Answers #{1, 2, 3} + * #{}.asSet() => Answers #{} + * + * @see Set + */ + method asSet() { + const result = #{} + result.addAll(self) + return result + } + + /** + * Answers a new collection of the same type and with the same content + * as self. Supports empty collections. + * + * @returns a new collection + * + * Example: + * const usersCopy = users.copy() + */ + method copy() { + const copy = self.newInstance() + copy.addAll(self) + return copy + } + + /** + * Answers a new collection without element that is passed by parameter. + * If the element occurs more than once in the collection, all occurrences + * will be removed. + * + * @returns a new Collection + * + * Example: + * [1, 5, 9, 2, 4].copyWithout(9) => Answers [1, 5, 2, 4] + * [1, 5, 9, 2, 9].copyWithout(9) => Answers [1, 5, 2] + * + */ + method copyWithout(elementToRemove) { + return self.filter{ element => element != elementToRemove } + } + + /** + * Answers a new collection with the added element which is received by parameter. + * + * @returns a new Collection + * + * Example: + * [1, 5, 9, 2, 4].copyWith(9) => Answers [1, 5, 2, 4, 9] + * + */ + method copyWith(elementToAdd) { + const copy = self.copy() + copy.add(elementToAdd) + return copy + } + + /** + * Answers a new List that contains the elements of self collection + * sorted by a criteria given by a closure. The closure receives two objects + * X and Y and answers a boolean, true if X should come before Y in the + * resulting collection. Supports empty collections. + * + * @returns a new List + * + * Example: + * const usersByAge = users.sortedBy({ a, b => a.age() < b.age() }) + * const studentsByNameDesc = students.sortedBy({ a, b => a.name() > b.name() }) + * [1, 5, 9, 2, 4].sortedBy { a, b => a < b } => Answers [1, 2, 4, 5, 9] + * [1, 5, 9, 2, 4].sortedBy { a, b => a > b } => Answers [9, 5, 4, 2, 1] + * [].sortedBy { a, b => a > b } => Answers [] + * + */ + method sortedBy(closure) { + const copy = self.copy().asList() + copy.sortBy(closure) + return copy + } + + + /** + * Answers a new, empty collection of the same type as self. + * @returns a new collection + * + * Example: + * const newCollection = users.newInstance() + */ + method newInstance() + + /** + * @see subclasses implementations + */ + method anyOne() = throw new Exception(message = "Should be implemented by the subclasses") + + /** + * @see subclasses implementations + */ + method add(element) = throw new Exception(message = "Should be implemented by the subclasses") + + /** + * @see subclasses implementations + */ + method remove(element) = throw new Exception(message = "Should be implemented by the subclasses") + + /** + * @see subclasses implementations + */ + method fold(element, closure) = throw new Exception(message = "Should be implemented by the subclasses") + + /** + * @see subclasses implementations + */ + method size() = throw new Exception(message = "Should be implemented by the subclasses") + + /** + * Removes all of the elements from this set. This is a side effect operation. + * + * @see subclasses implementations + */ + method clear() + + /** + * Answers the concatenated string representation of the elements in the given set. + * You can pass an optional character as an element separator (default is ",") + */ + method join(separator) + + /** + * Answers the concatenated string representation of the elements in the given set + * with default element separator (",") + */ + method join() + +} + +/** + * + * A collection that contains no duplicate elements. + * It models the mathematical set abstraction. + * A Set guarantees no order of elements. + * + * @author jfernandes + * @since 1.3 + */ +class Set inherits Collection { + + /** @private */ + override method newInstance() = #{} + + /** @private */ + override method toStringPrefix() = "#{" + + /** @private */ + override method toStringSuffix() = "}" + + /** + * Converts this set to a list. + * + * Examples + * #{1, 2, 3}.asList() => Answers [1, 2, 3] + * #{}.asList() => Answers [] + * + * @see List + */ + override method asList() { + const result = [] + result.addAll(self) + return result + } + + /** + * Answers any element of a non-empty collection + * + * Examples + * #{1, 2, 3}.anyOne() => Answers 1, for example + * #{}.anyOne() => Throws error, set must not be empty + * + */ + override method anyOne() native + + /** + * Answers a new Set with the elements of both self and another collection. + * + * Examples + * #{1, 2}.union(#{5, 2}) => #{1, 2, 5} + * #{}.union(#{3}) => #{3} + * + * @returns a Set + */ + method union(another) = self + another + + /** + * Answers a new Set with the elements of self that exist in another collection + * + * Examples + * #{1, 2}.intersection(#{5, 2}) => #{2} + * #{}.intersection(#{3}) => #{} + * + * @returns a Set + */ + method intersection(another) = + self.filter({it => another.contains(it)}) + + /** + * Answers a new Set with the elements of self that don't exist in another collection + * + * Examples + * #{1, 2}.difference(#{5, 2}) => #{1} + * #{3}.difference(#{}) => #{3} + * + * @returns a Set + */ + method difference(another) = + self.filter({it => !another.contains(it)}) + + /** + * Reduce a collection to a certain value, beginning with a seed or initial value. + * + * Examples + * #{1, 9, 3, 8}.fold(0, {acum, each => acum + each}) + * => Answers 21, the sum of all elements + * + * #{}.fold(0, {acum, each => acum + each}) + * => Answers 0, the seed. + * + * var numbers = #{3, 2, 9, 1, 7} + * numbers.fold(numbers.anyOne(), { acum, number => acum.max(number) }) + * => Answers 9, the maximum of all elements + * + */ + override method fold(initialValue, closure) native + + /** + * @see Collection#filter(closure) + */ + override method filter(closure) native + + + /** + * @see Collection#max() + */ + override method max() native + + /** + * Tries to find an element in a collection (based on a closure) or + * applies a continuation closure. + * + * Examples: + * #{1, 9, 3, 8}.findOrElse({ n => n.even() }, { 100 }) => Answers 8 + * #{1, 5, 3, 7}.findOrElse({ n => n.even() }, { 100 }) => Answers 100 + */ + override method findOrElse(predicate, continuation) native + + /** + * Adds the specified element to this set if it is not already present. + * + * Example: + * const set = #{} + * set.add(3) => set = #{3} + * set.add(2) => set = #{2, 3} + * set.add(2) => set = #{2, 3}, second add produces no effect + */ + override method add(element) native + + /** + * Removes the specified element from this set if it is present. + * + * Example: + * const set = #{2, 3} + * set.remove(3) => set = #{2} + * set.remove(4) => set = #{2}, remove operation produces no effect + */ + override method remove(element) native + + /** Answers the number of elements in this set (its cardinality). + * + * Example: + * #{2, 3}.size() => Answers 2 + * #{}.size() => Answers 0 + */ + override method size() native + + /** + * Removes all of the elements from this set. This is a side effect operation. + * + * Example: + * const set = #{2, 3} + * set.clear() => set = #{} + */ + override method clear() native + + /** + * Answers the concatenated string representation of the elements in the given set. + * You can pass an optional character as an element separator (default is ",") + * + * Examples: + * #{1, 5, 3, 7}.join(":") => Answers "1:5:3:7" + * #{"you","will","love","wollok"}.join(" ") => Answers "love will wollok you" + * #{}.join(",") => Answers "" + */ + override method join(separator) native + + /** + * Answers the concatenated string representation of the elements in the given set + * with default element separator (",") + * + * Example: + * #{"you","will","love","wollok"}.join() => Answers "love,will,wollok,you" + */ + override method join() native + + /** + * + * @see List#contains(other) + */ + override method contains(other) native + + /** + * Two sets are equals if they have the same elements + * + * Examples: + * #{}.equals(#{}) => Answers true + * #{1, 2}.equals(#{2, 1}) => Answers true + * #{3, 2}.equals(#{2, 1}) => Answers false + */ + override method equals(other) native + + /** + * + * Set equality operator as defined by equals + * + * #{1, 2} == #{2, 1} => Answers true + * #{} == #{} => Answers true + * + * @see Object#== + */ + override method ==(other) native + +} + +/** + * + * An ordered collection (also known as a sequence). + * You iterate the list the same order elements are inserted. + * The user can access elements by their integer index (position in the list). + * A List can contain duplicate elements. + * + * @author jfernandes + * @since 1.3 + */ +class List inherits Collection { + + /** + * Answers the element at the specified position in this non-empty list. + * + * The first char value of the sequence is at index 0, + * the next at index 1, and so on, as for array indexing. + * Index must be a positive and integer value. + * + * Examples: + * [].get(0) => Throws error, list must not be empty + * [1].get(-1) => Throws error, index must be 0 or positive + * [1, 2, 3].get(3) => Throws error, index exceeds list size + * [5, 2, 7].get(0) => Answers 5 + */ + method get(index) native + + /** Creates a new list */ + override method newInstance() = [] + + /** + * Answers any element of a non-empty collection. + * + * Examples + * #[1, 2, 3].anyOne() => Answers 3, for example + * #[].anyOne() => Throws error, list must not be empty + */ + override method anyOne() { + self.validateNotEmpty("anyOne") + return self.get(0.randomUpTo(self.size())) + } + + /** + * Answers first element of the non-empty list + * + * @returns first element + * + * Example: + * [1, 2, 3, 4].first() => Answers 1 + * [].first() => Throws error, list must not be empty + */ + method first() = self.head() + + /** + * Synonym for first method + */ + method head() = self.get(0) + + /** + * Answers the last element of the non-empty list. + * + * @returns last element + * + * Examples: + * [1, 2, 3, 4].last() => Answers 4 + * [].last() => Throws error, list must not be empty + */ + method last() = self.get(self.size() - 1) + + /** @private */ + override method toStringPrefix() = "[" + + /** @private */ + override method toStringSuffix() = "]" + + /** + * Converts this collection to a list. No effect on Lists. + * + * @see List + */ + override method asList() = self + + /** + * Answers a view of the portion of this list between the specified start index + * and the end of the list. Remember first element is position 0, + * second is position 1, and so on. + * If toIndex exceeds length of list, no error is thrown. + * + * Example: + * [1, 5, 3, 2, 7, 9].subList(2) => Answers [3, 2, 7, 9] + * [1, 5, 3, 2, 7, 9].subList(4) => Answers [7, 9] + * [].subList(1) => Answers [] + */ + method subList(start) { + if (self.isEmpty()) return [] + if (start >= self.size()) return [] + return self.subList(start, self.size() - 1) + } + + /** + * Answers a view of the portion of this list between the specified fromIndex + * and toIndex, both inclusive. Remember first element is position 0, + * second is position 1, and so on. + * If toIndex exceeds length of list, no error is thrown. + * + * Example: + * [1, 5, 3, 2, 7, 9].subList(2, 3) => Answers [3, 2] + * [1, 5, 3, 2, 7, 9].subList(4, 6) => Answers [7, 9] + * [].subList(1, 2) => Answers [] + */ + method subList(start, end) { + self.checkNotNull(start, "subList") + self.checkNotNull(end, "subList") + if (self.isEmpty() || start >= self.size()) + return self.newInstance() + + const newList = self.newInstance() + const _start = start.coerceToInteger().limitBetween(0, self.size() - 1) + const _end = end.coerceToInteger().limitBetween(0, self.size() - 1) + (_start.._end).forEach { i => newList.add(self.get(i)) } + return newList + } + + /** + * + * Sorts elements of a list by a specific closure. + * Order of elements is modified (produces effect). + * + * Examples: + * const list = [2, 9, 3] + * list.sortBy { el1, el2 => el1 > el2 } + * list.get(0) => Answers 9 + * + * @see List#sortedBy + */ + method sortBy(closure) native + + /** + * Takes first n elements of a list. + * + * Examples: + * [1,9,2,3].take(5) ==> Answers [1, 9, 2, 3] + * [1,9,2,3].take(2) ==> Answers [1, 9] + * [1,9,2,3].take(-2) ==> Answers [] + * [].take(2) ==> Answers [] + */ + method take(n) { + self.checkNotNull(n, "take") + return if (n <= 0) self.newInstance() else self.subList(0, n - 1) + } + + /** + * Answers a new list dropping first n elements of a list. + * This operation has no side effect. + * + * Examples: + * [1, 9, 2, 3].drop(3) ==> Answers [3] + * [1, 9, 2, 3].drop(1) ==> Answers [9, 2, 3] + * [1, 9, 2, 3].drop(-2) ==> Answers [1, 9, 2, 3] + * [].drop(2) ==> Answers [] + */ + method drop(n) { + self.checkNotNull(n, "drop") + return if (n >= self.size()) self.newInstance() else self.subList(n, self.size() - 1) + } + + /** + * Answers a new list reversing the elements, + * so that first element becomes last element of the new list and so on. + * This operation has no side effect. + * + * Example: + * [1, 9, 2, 3].reverse() ==> Answers [3, 2, 9, 1] + * [1, 2].reverse() ==> Answers [2, 1] + * [].reverse() ==> Answers [] + * + */ + method reverse() = self.subList(self.size() - 1, 0) + + /** + * @see Collection#filter(closure) + */ + override method filter(closure) native + + /** + * @see Collection#contains(obj) + */ + override method contains(obj) native + + /** + * @see Collection#max() + */ + override method max() native + + /** + * Reduce a collection to a certain value, beginning with a seed or initial value + * + * Examples + * #{1, 9, 3, 8}.fold(0, {acum, each => acum + each}) + * => Answers 21, the sum of all elements + * + * [].fold(0, {acum, each => acum + each}) + * => Answers 0, the seed. + * + * var numbers = #{3, 2, 9, 1, 7} + * numbers.fold(numbers.anyOne(), { acum, number => acum.max(number) }) + * => Answers 9, the maximum of all elements + * + */ + override method fold(initialValue, closure) native + + /** + * Finds the first element matching the boolean closure, + * or evaluates the continuation block closure if no element is found + * + * Examples: + * [1, 9, 3, 8].findOrElse({ n => n.even() }, { 100 }) => Answers 8 + * [1, 5, 3, 7].findOrElse({ n => n.even() }, { 100 }) => Answers 100 + */ + override method findOrElse(predicate, continuation) native + + /** + * Adds the specified element as last one + * + * Example: + * const list = [] + * list.add(3) => list = [3] + * list.add(2) => list = [3, 2] + * list.add(2) => list = [3, 2, 2] + */ + override method add(element) native + + /** + * Removes an element in this list, if it is present. + * + * Example: + * const list = [2, 3] + * list.remove(3) => list = [2] + * list.remove(4) => list = [2], remove operation produces no effect + */ + override method remove(element) native + + /** + * Answers the number of elements + * + * Example: + * [2, 3].size() => Answers 2 + * [].size() => Answers 0 + */ + override method size() native + + /** + * Removes all of the mappings from this Dictionary. + * This is a side effect operation. + * + * Example: + * const list = [2, 3] + * list.clear() => list = [] + */ + override method clear() native + + /** + * Answers the concatenated string representation of the elements in the given set. + * You can pass an optional character as an element separator (default is ",") + * + * Examples: + * [1, 5, 3, 7].join(":") => Answers "1:5:3:7" + * ["you","will","love","wollok"].join(" ") => Answers "you will love wollok" + */ + override method join(separator) native + + /** + * + * Answers the concatenated string representation of the elements in the given set, + * using default element separator (",") + * + * Examples: + * ["you","will","love","wollok"].join() => Answers "you,will,love,wollok" + */ + override method join() native + + /** + * @see == message + */ + override method equals(other) native + + /** + * A list is == another list if all elements are equal (defined by == message) + * + * + * Examples: + * [] == [] => Answers true + * [1, 2] == [2, 1] => Answers false + * [1, 2] == [1, 2] => Answers true + */ + override method ==(other) native + + /** + * Answers the list without duplicate elements. Preserves order of elements. + * + * [1, 3, 1, 5, 1, 3, 2, 5].withoutDuplicates() => Answers [1, 3, 5, 2] + * [].withoutDuplicates() => Answers [] + */ + method withoutDuplicates() native + +} + +/** + * Represents a set of key -> values + * + */ +class Dictionary { + + /** + * Adds or updates a value based on a key. + * If key is not present, a new value is added. + * If key is present, value is updated. + * This is a side effect operation. + * + * Example: + * const phones = new Dictionary() + * phones.put("4004-4004", rolo) + * => phones == a Dictionary ["4004-4004" -> rolo] + */ + method put(_key, _value) native + + /** + * Answers the value to which the specified key is mapped, + * or null if this Dictionary contains no mapping for the key. + * + * Example, assuming phones is the dictionary created in put example: + * phones.basicGet("4004-4004") => Answers rolo + * phones.basicGet("4004-4005") => Answers null + */ + method basicGet(_key) native + + /** + * Answers the value to which the specified key is mapped, + * or evaluates a non-parameter closure otherwise. + * + * Example, assuming phones is the dictionary created in put example: + * phones.getOrElse("4004-4004", { 0 }) => Answers rolo + * phones.getOrElse("4004-4005", { 0 }) => Answers 0 + */ + method getOrElse(_key, _closure) { + const value = self.basicGet(_key) + if (value == null) + return _closure.apply() + else + return value + } + + /** + * Answers the value to which the specified key is mapped. + * If this Dictionary contains no mapping for the key, an error is thrown. + * + * Example, assuming phones is the dictionary created in put example: + * phones.get("4004-4004") => Answers rolo + * phones.get("4004-4005") => Throws ElementNotFoundException + */ + method get(_key) = self.getOrElse(_key,{ => throw new ElementNotFoundException(message = "there is no element associated with key " + _key) }) + + /** + * Answers the number of key-value mappings in this Dictionary. + * + * Example, assuming phones is the dictionary created in put example: + * phones.size() => Answers 1 + * new Dictionary().size() => Answers 0 + */ + method size() = self.values().size() + + /** + * Answers whether the dictionary has no elements + * + * Example, assuming phones is the dictionary created in put example: + * phones.isEmpty() => Answers false + * new Dictionary().isEmpty() => Answers true + */ + method isEmpty() = self.size() == 0 + + /** + * Answers whether this Dictionary contains a mapping for the specified key. + * + * Example, assuming phones is the dictionary created in put example: + * phones.containsKey("4004-4004") => Answers true + * phones.containsKey("4004-4005") => Answers false + * new Dictionary().containsKey(1) => Answers false + */ + method containsKey(_key) = self.keys().contains(_key) + + /** + * Answers whether if this Dictionary maps one or more keys to the specified value. + * + * Example: + * const numbers = new Dictionary() + * numbers.put("one", 1) + * numbers.put("two", 2) + * numbers.containsValue(2) => Answers true + * numbers.containsValue(5) => Answers false + * new Dictionary().containsValue(3) => Answers false + */ + method containsValue(_value) = self.values().contains(_value) + + /** + * Removes the mapping for a key from this Dictionary if it is present. + * If key is not present nothing happens. + * This is a side effect operation. + * + * Example: + * const numbers = new Dictionary() + * numbers.put("one", 1) + * numbers.put("two", 2) + * numbers.remove("one") => numbers is a dictionary ("two" -> 2) + * numbers.remove("three") => nothing happens + */ + method remove(_key) native + + /** + * Answers a list of the keys contained in this Dictionary. + * + * Example: + * const numbers = new Dictionary() + * numbers.put("one", 1) + * numbers.put("two", 2) + * numbers.keys() => ["one", "two"] + */ + method keys() native + + /** + * Answers a list of the values contained in this Dictionary. + * + * Example: + * const numbers = new Dictionary() + * numbers.put("one", 1) + * numbers.put("two", 2) + * numbers.values() => [1, 2] + */ + method values() native + + /** + * Performs the given action for each entry in this Dictionary + * until all entries have been processed or the action throws an exception. + * + * Expected closure with two parameters: the first associated with key and + * second with value. + * + * Example: + * mapaTelefonos.forEach({ k, v => result += k.size() + v.size() }) + * + */ + method forEach(closure) native + + /** + * Removes all of the mappings from this Dictionary. + * This is a side effect operation. + * + * Example: + * const numbers = new Dictionary() + * numbers.put("one", 1) + * numbers.put("two", 2) + * numbers.clear() => phones == empty dictionary + */ + method clear() native + + /** + * String representation of a Dictionary + * + * Example: + * const numbers = new Dictionary() + * numbers.put("one", 1) + * numbers.put("two", 2) + * => Answers a Dictionary ["one" -> 1, "two" -> 2] + */ + override method toString() { + var result = "a Dictionary [" + self.forEach { key, value => result = result + (key.printString() + " -> " + value.printString() + ", ") } + if (self.size() > 0) result = result.substring(0, result.length() - 2) + return result + "]" + } + + /** + * Two dictionaries are equal if they have the same keys and values + */ + override method equals(other) { + self.checkNotNull(other, "equals") + return self.keys() == other.keys() && self.values() == other.values() + } + +} + +/** + * + * In Wollok we have numbers as an immutable representation. You can customize + * how many decimals you want to work with, and printing strategies. So + * number two could be printed as "2", "2,00000", "2,000", etc. + * + * Coercing strategy for numbers can be + * 1) rounding up: 2,3258 using 3 decimals will result in 2,326 + * 2) rounding down or truncation: 2,3258 using 3 decimals will + * result in 2,325 + * 3) not allowed: 2,3258 using 3 decimals will throw an exception + * since decimals exceeds maximum allowed + * + * @author jfernandes + * @author dodain (unification between Double and Integer in a single Number class) + * + * @since 1.3 + * @noInstantiate + */ +class Number { + + /** @private */ + override method simplifiedToSmartString(){ return self.stringValue() } + + /** @private */ + override method internalToSmartString(alreadyShown) { return self.stringValue() } + + /** + * @private + * + * Applies coercing strategy to integer. If it is an integer, nothing happens. + * Otherwise, if it is a decimal, defined coercing algorithm is applied + * (see definition of class Number) + */ + method coerceToInteger() native + + /** + * @private + * @see coerceToInteger + * + * Applies coercing strategy to integer. And throws exception if it is negative. + */ + method coerceToPositiveInteger() native + + /** + * Two references are identical if they are the same number + */ + override method ===(other) native + + method +(other) native + method -(other) native + method *(other) native + method /(other) native + + /** + * Integer division between self and other + * + * Example: + * 8.div(3) ==> Answers 2 + * 15.div(5) ==> Answers 3 + * 8.2.div(3.3) ==> Answers 2 + */ + method div(other) { + self.checkNotNull(other, "div") + return (self / other).truncate(0) + } + + /** + * raisedTo operation + * + * Example: + * 3.2 ** 2 ==> Answers 10.24 + * 3 ** 2 ==> Answers 9 + */ + method **(other) native + + /** + * Answers remainder of division between self and other + */ + method %(other) native + + /** String representation of self number */ + override method toString() native + + /** @private */ + override method toSmartString(alreadyShown) = self.toString() + + /** + * Builds a Range between self and end + * + * Example: + * 1..4 Answers ==> a new Range object from 1 to 4 + */ + method ..(end) { + self.checkNotNull(end, "..") + return new Range(start = self, end = end) + } + + method >(other) native + method <(other) native + + method >=(other) = self > other || self == other + method <=(other) = self < other || self == other + + /** + * Answers absolute value of self + * + * Example: + * 2.abs() ==> 2 + * (-3).abs() ==> 3 (be careful with parentheses) + * 2.7.abs() ==> Answers 2.7 + * (-3.2).abs() ==> Answers 3.2 (be careful with parentheses) + */ + method abs() native + + /** + * Inverts sign of self + * + * Example: + * 3.invert() ==> Answers -3 + * (-2).invert() ==> Answers 2 (be careful with parentheses) + * 3.2.invert() ==> -3.2 + * (-2.4).invert() ==> 2.4 (be careful with parentheses) + */ + method invert() native + + /** + * Answers the greater number between two + * Example: + * 5.max(8) ==> Answers 8 + */ + method max(other) { + self.checkNotNull(other, "max") + return if (self >= other) self else other + } + + /** + * Answers the lower number between two. @see max + * Example: + * 5.min(8) ==> Answers 5 + */ + method min(other) { + self.checkNotNull(other, "min") + return if (self <= other) self else other + } + + /** + * Given self and a range of integer values, + * answers self if it is in that range + * or nearest value from self to that range + * + * Examples + * 4.limitBetween(2, 10) ==> Answers 4, because 4 is in the range + * 4.limitBetween(6, 10) ==> Answers 6, because 4 is not in range 6..10, and 6 is nearest value to 4 + * 4.limitBetween(1, 2) ==> Answers 2, because 4 is not in range 1..2, but 2 is nearest value to 4 + * + */ + method limitBetween(limitA, limitB) { + self.checkNotNull(limitA, "limitBetween") + self.checkNotNull(limitB, "limitBetween") + return + if (limitA <= limitB) + limitA.max(self).min(limitB) + else + limitB.max(self).min(limitA) + } + + /** + * Answers whether self is between min and max + * + * Example: + * 2.between(2, 3) ==> Answers true + * 6.between(4, 6) ==> Answers true + * 3.between(4, 6) ==> Answers false + */ + method between(min, max) = (self >= min) && (self <= max) + + /** Answers squareRoot of self + * + * Example: + * 9.squareRoot() => Answers 3 + */ + method squareRoot() = self ** 0.5 + + /** Answers square of self + * + * Example: + * 3.square() => Answers 9 + */ + method square() = self * self + + /** + * Answers whether self is an even number + * (divisible by 2, mathematically 2k). + * + * Self must be an integer value + */ + method even() = self % 2 == 0 + + /** + * Answers whether self is an odd number + * (not divisible by 2, mathematically 2k + 1). + * + * Self must be an integer value + */ + method odd() { + if (!self.isInteger()) return false + return !self.even() + } + + /** Answers remainder between self and other + * + * Example: + * 5.rem(3) ==> Answers 2 + * 5.5.rem(3) ==> Answers 2 + */ + method rem(other) { + self.checkNotNull(other, "rem") + return self % other + } + + /* + * Self as String value. Equivalent: toString() + */ + method stringValue() = self.toString() + + /** + * Rounds up self up to a certain amount of decimals. + * Amount of decimals must be a positive and integer value. + * + * Example: + * 1.223445.roundUp(3) ==> 1.224 + * -1.223445.roundUp(3) ==> -1.224 + * 14.6165.roundUp(3) ==> 14.617 + * 5.roundUp(3) ==> 5 + */ + method roundUp(_decimals) native + + /** + * Truncates self up to a certain amount of decimals. + * Amount of decimals must be a positive and integer value. + * + * Example: + * 1.223445.truncate(3) ==> 1.223 + * 14.6165.truncate(3) ==> 14.616 + * -14.6165.truncate(3) ==> -14.616 + * 5.truncate(3) ==> 5 + */ + method truncate(_decimals) native + + /** + * Answers a random number between self and max + */ + method randomUpTo(max) native + + /** + * Answers the next integer greater than self + * 13.224.roundUp() ==> 14 + * -13.224.roundUp() ==> -14 + * 15.942.roundUp() ==> 16 + */ + method roundUp() = self.roundUp(0) + + /** + * greater common divisor. + * Both self and "other" parameter are coerced to be integer values. + * + * Example: + * 8.gcd(12) ==> Answers 4 + * 5.gcd(10) ==> Answers 5 + */ + method gcd(other) native + + /** + * least common multiple. + * Both self and "other" parameter are coerced to be integer values. + * + * Example: + * 3.lcm(4) ==> Answers 12 + * 6.lcm(12) ==> Answers 12 + */ + method lcm(other) { + self.checkNotNull(other, "lcm") + const mcd = self.gcd(other) + return self * (other / mcd) + } + + /** + * Number of digits of self (without sign) + * + * Examples: + * 600.digits() ==> Answers 3 + * 6.00012.digits() ==> Answers 6 + * -100.digits() ==> Answers -3 + */ + method digits() { + var digits = self.toString().size() + if (self < 0) { + digits -= 1 + } + if (!self.isInteger()) { + digits -= 1 + } + return digits + } + + /** + * Tells if this number can be considered an integer number. + * + * Examples: + * 2.isInteger() ==> Answers true + * (2.0).isInteger() ==> Answers true + * (2.3).isInteger() ==> Answers false + * + * This could depend also on the rounding strategy, for example: + * (2.0001).isInteger() ==> Answers false if rounding strategy is set to 5 decimal places (default) + * (2.0001).isInteger() ==> Answers true if rounding strategy is set to 3 decimal places + */ + method isInteger() native + + /** Answers whether self is a prime number, + * like 2, 3, 5, 7, 11 ... + * Self must be an integer positive value + */ + method isPrime() { + const intValue = self.coerceToInteger() + if (intValue == 1) return false + return (2..(intValue.div(2) + 1)).any({ i => intValue % i == 0 }).negate() + } + + /** + * Executes the given action n times (n = self) + * + * Self must be a positive integer value. + * The closure must have one argument (index goes from 1 to self) + * + * Example: + * 4.times({ i => console.println(i) }) ==> Answers + * 1 + * 2 + * 3 + * 4 + */ + method times(action) { + self.checkNotNull(action, "times") + const intValue = self.coerceToInteger() + if (intValue < 0) self.error("times requires a positive integer number") + if (intValue > 0) (1..intValue).forEach(action) + } + + /** Allows users to define a positive number with 1 or +1 */ + method plus() = self +} + +/** + * Strings are constant; + * their values cannot be changed after they are created. + * + * @author jfernandes + * @noInstantiate + */ +class String { + /** Answers the number of elements */ + method length() native + + /** + * Answers the char value at the specified index. An index ranges + * from 0 to length() - 1. The first char value of the sequence is + * at index 0, the next at index 1, and so on, as for array indexing. + * Parameter index must be a positive integer value. + */ + method charAt(index) { + self.checkNotNull(index, "charAt") + if (!index.isInteger()) throw new DomainException(message = "charAt expects an integer instead of " + index) + return self.substring(index, index + 1) + } + + /** + * Concatenates the specified string to the end of this string. + * Example: + * "cares" + "s" => Answers "caress" + */ + method +(other) = self.concat(other.toString()) + + /** + * Concatenates the specified string to the end of this string. Same as +. + * Example: + * "cares".concat("s") => Answers "caress" + */ + method concat(other) native + + + /** + * Tests if this string starts with the specified prefix. + * It is case sensitive. + * + * Examples: + * "mother".startsWith("moth") ==> Answers true + * "mother".startsWith("Moth") ==> Answers false + */ + method startsWith(other) native + + /** + * Tests if this string ends with the specified suffix. + * It is case sensitive. + * @see startsWith + */ + method endsWith(other) native + + /** + * Answers the index within this string of the first occurrence + * of the specified character. + * If character is not present, Answers -1 + * + * Examples: + * "pototo".indexOf("o") ==> Answers 1 + * "unpredictable".indexOf("o") ==> Answers -1 + */ + method indexOf(other) native + + /** + * Answers the index within this string of the last + * occurrence of the specified character. + * If character is not present, Answers -1 + * + * Examples: + * "pototo".lastIndexOf("o") ==> Answers 5 + * "unpredictable".lastIndexOf("o") ==> Answers -1 + */ + method lastIndexOf(other) native + + /** + * Converts all of the characters in this String to lower case + * + * Examples: + * "Fer".toLowerCase() ==> Answers "fer" + * "".toLowerCase() ==> Answers "" + */ + method toLowerCase() native + + /** + * Converts all of the characters in this String to upper case + * + * Examples: + * "Fer".toUpperCase() ==> Answers "FER" + * "".toUpperCase() ==> Answers "" + */ + method toUpperCase() native + + /** + * Answers a string whose value is this string, + * with any leading and trailing whitespace removed. + * + * Example: + * " emptySpace ".trim() ==> "emptySpace" + */ + method trim() native + + /** + * Answers a string reversing this string, + * so that first character becomes last character of the new string and so on. + * + * Example: + * "hola".reverse() ==> "aloh" + */ + method reverse() native + + /** + * @see take + * + * Example: + * "word".takeLeft(3) ==> Answers "wor" + * "word".takeLeft(0) ==> Answers "" + * "word".takeLeft(-1) ==> Throws error + * "".takeLeft(2) ==> Answers "" + */ + method takeLeft(length) = self.take(length) + + /** + * Takes last n characters of this string. + * n must be zero-positive integer. + * + * Example: + * "word".takeRight(3) ==> Answers "ord" + * "word".takeRight(0) ==> Answers "" + * "word".takeRight(-1) ==> Throws error + * "".takeRight(2) ==> Answers "" + */ + method takeRight(_length) { + const length = _length.coerceToPositiveInteger().min(self.size()) + return self.drop(self.size() - length) + } + + method <(aString) native + method <=(aString) { + return self < aString || (self.equals(aString)) + } + method >(aString) native + method >=(aString) { + return self > aString || (self.equals(aString)) + } + + /** + * Answers whether this string contains the specified sequence of char values. + * It is a case sensitive test. + * + * Examples: + * "unusual".contains("usual") ==> Answers true + * "become".contains("CO") ==> Answers false + */ + method contains(other) native + + /** Answers whether this string has no characters */ + method isEmpty() = self.size() == 0 + + /** + * Compares this String to another String, ignoring case considerations. + * + * Example: + * "WoRD".equalsIgnoreCase("Word") ==> Answers true + */ + method equalsIgnoreCase(aString) { + self.checkNotNull(aString, "equalsIgnoreCase") + return self.toUpperCase() == aString.toUpperCase() + } + + /** + * Answers a substring of this string beginning from + * an inclusive index. Parameter index must be a positive + * integer value. + * + * Examples: + * "substitute".substring(6) ==> Answers "tute", second "t" is in position 6 + * "effect".substring(0) ==> Answers "effect", has no effect at all + */ + method substring(index) native + + /** + * Answers a substring of this string beginning + * from an inclusive index up to another inclusive index + * + * Examples: + * "walking".substring(2, 4) ==> Answers "lk" + * "walking".substring(3, 5) ==> Answers "ki" + * "walking".substring(0, 5) ==> Answers "walki" + * "walking".substring(0, 45) ==> throws an out of range exception + */ + method substring(startIndex, length) native + + /** + * Splits this string around matches of the given string. + * Answers a list of strings. + * + * Example: + * "this,could,be,a,list".split(",") + * ==> Answers ["this", "could", "be", "a", "list"] + */ + method split(expression) { + self.checkNotNull(expression, "split") + const result = [] + var me = self.toString() + expression + var first = 0 + (0..me.size() - 1).forEach { i => + if (me.charAt(i) == expression) { + result.add(me.substring(first, i)) + first = i + 1 + } + } + return result + } + + /** + * Answers a string resulting from replacing all occurrences of + * expression in this string with replacement + * + * Example: + * "stupid is what stupid does".replace("stupid", "genius") + * ==> Answers "genius is what genius does" + */ + method replace(expression, replacement) native + + /** This object (which is already a string!) is itself returned */ + override method toString() native + + /** String implementation of printString, + * simply adds quotation marks + */ + override method printString() = '"' + self.toString() + '"' + + /** @private */ + override method toSmartString(alreadyShown) native + + /** Compares this string to the specified object. + * The result is true if and only if the + * argument is not null and is a String object + * that represents the same sequence of characters as this object. + */ + override method ==(other) native + + /** A synonym for length */ + method size() = self.length() + + /** + * Takes first n characters of this string. + * n must be zero-positive integer. + * + * Examples: + * "lowercase".take(3) ==> Answers "low" + * "lowercase".take(0) ==> Answers "" + * "lowercase".take(-1) ==> Throws error + * "".take(2) ==> Answers "" + */ + method take(n) { + self.checkNotNull(n, "take") + return self.substring(0, n.min(self.size())) + } + + /** + * Answers a new string dropping + * first n characters of this string. + * n must be zero-positive integer. + * + * Examples: + * "caption".drop(4) ==> Answers "ion" + * "caption".drop(0) ==> Answers "caption" + * "caption".drop(-1) ==> Throws error + * "".drop(2) ==> Answers "" + */ + method drop(n) { + self.checkNotNull(n, "drop") + return self.substring(n.min(self.size()), self.size()) + } + + /** + * Splits this strings into several words. + * + * Examples: + * "how does words work?".words() + * ==> Answers ["how", "does", "words", "work?"] + * + * "".words() ==> Answers [] + */ + method words() = self.split(" ") + + /** + * Changes the first letter of every word to + * upper case in this string. + * + * Example: + * "javier fernandes".capitalize() ==> Answers "Javier Fernandes" + */ + method capitalize() { + const capitalizedPhrase = self.words().fold("", { words, word => words + word.take(1).toUpperCase() + word.drop(1).toLowerCase() + " " }) + return capitalizedPhrase.take(capitalizedPhrase.size() - 1) + } + +} + +/** + * Represents a Boolean value (true or false) + * + * @author jfernandes + * @noInstantiate + */ +class Boolean { + + /** + * Answers the result of applying the logical AND operator + * to the specified boolean operands self and other + */ + method and(other) native + + /** A synonym for and operation */ + method &&(other) native + + /** Answers the result of applying the logical OR operator + * to the specified boolean operands self and other + */ + method or(other) native + + /** A synonym for or operation */ + method ||(other) native + + /** Answers a String object representing this Boolean's value. */ + override method toString() native + + /** @private */ + override method toSmartString(alreadyShown) native + + /** Compares this string to the specified object. + * The result is true if and only if the + * argument is not null and represents same value + * (true or false) + */ + override method ==(other) native + + /** NOT logical operation */ + method negate() native +} + +/** + * Represents a finite arithmetic progression + * of integer numbers with optional step + * If start = 1, end = 8, Range will represent [1, 2, 3, 4, 5, 6, 7, 8] + * If start = 1, end = 8, step = 3, Range will represent [1, 4, 7] + * + * @author jfernandes + * @since 1.3 + */ +class Range { + var start + var end + var property step = null + + /** + * Instantiates a Range. + * Both start and end must be integer values. + */ + method initialize() { + start = start.truncate(0) + end = end.truncate(0) + if (step == null) { + if (start > end) { + step = -1 + } else { + step = 1 + } + } + } + + /** + * Getter for start attribute + */ + method start() = start + + /** + * Getter for end attribute + */ + method end() = end + + /** + * Setter for step attribute. + */ + method step(_step) { + self.checkNotNull(_step, "step") + step = _step.coerceToInteger() + } + + /** + * Iterates over a Range from start to end, based on step. + * + * Example: + * new Range(start = 1, end = 3).forEach { value => console.println(value) } + * => prints 1, 2, 3 + */ + method forEach(closure) native + + /** + * Answers a new collection that contains the result of + * transforming each of self collection's elements using + * a given closure. + * + * The condition is a closure argument that takes an integer + * and answers an object. + * @returns another list + * + * Example: + * (1..10).map({ n => n * 2}) ==> Answers [2, 4, 6, 8, 10, 12, 14, 16, 18, 20] + */ + method map(closure) { + self.checkNotNull(closure, "map") + const list = [] + self.forEach { element => list.add(closure.apply(element)) } + return list + } + + /** + * Map + flatten operation + * @see map + * @see flatten + * + * Example: + * (1..4).flatMap({ n => 1 .. n }) ==> Answers [1, 1, 2, 1, 2, 3, 1, 2, 3, 4] + */ + method flatMap(closure) { + self.checkNotNull(closure, "flatMap") + return self.fold([], { seed, element => + seed.addAll(closure.apply(element)) + seed + }) + } + + /** @private */ + method asList() { + return self.map({ elem => elem }) + } + + /** + * Answers whether this range contains no elements + * @see Collection#isEmpty() + */ + method isEmpty() = self.size() == 0 + + /** @see List#fold(seed, foldClosure) */ + method fold(seed, foldClosure) = self.asList().fold(seed, foldClosure) + + /** + * Answers the number of elements + * + * Examples: + * new Range(start = 0, end = 2).size() ==> Answers 3 + * new Range(start = -2, end = 2).size() ==> Answers 5 + */ + method size() { + const base = (end - start) / step + return if (base >= 0) base.truncate(0) + 1 else 0 + } + + /** @see List#any(closure) */ + method any(closure) = self.asList().any(closure) + + /** @see List#all(closure) */ + method all(closure) = self.asList().all(closure) + + /** @see List#filter(closure) */ + method filter(closure) = self.asList().filter(closure) + + /** @see List#min() */ + method min() = self.asList().min() + + /** @see List#max() */ + method max() = self.asList().max() + + /** + * Answers a random integer contained in the range + * + * Example: + * new Range(start = 1, end = 3).anyOne() ==> Answers 1 or 2 or 3 + */ + method anyOne() native + + /** + * Tests whether a number e is contained in the range + * + * Examples: + * new Range(start = 2, end = 5).contains(4) ==> Answers true + * new Range(start = 2, end = 5).contains(0) ==> Answers false + */ + method contains(element) = self.asList().contains(element) + + /** @see List#sum() */ + method sum() = self.asList().sum() + + /** + * Sums all elements that match the boolean closure + * + * Example: + * (1..9).sum({ i => if (i.even()) i else 0 }) ==> Answers 20 + */ + method sum(closure) = self.asList().sum(closure) + + /** + * Counts how many elements match the boolean closure + * + * Example: + * (1..9).count({ i => i.even() }) ==> Answers 4 (2, 4, 6 and 8 are even) + */ + method count(closure) = self.asList().count(closure) + + /** @see List#find(closure) */ + method find(closure) = self.asList().find(closure) + + /** @see List#findOrElse(predicate, continuation) */ + method findOrElse(closure, continuation) = self.asList().findOrElse(closure, continuation) + + /** @see List#findOrDefault(predicate, value) */ + method findOrDefault(predicate, value) = self.asList().findOrDefault(predicate, value) + + /** @see List#sortBy */ + method sortedBy(closure) = self.asList().sortedBy(closure) + + /** @private */ + override method internalToSmartString(alreadyShown) = start.toString() + ".." + end.toString() +} + +/** + * + * Represents an executable piece of code. You can create a closure, + * assign it to a reference, evaluate it many times, + * send it as parameter to another object, and many useful things. + * + * @author jfernandes + * @since 1.3 + * @noInstantiate + */ +class Closure { + + method initialize() native + + /** Evaluates this closure passing its parameters + * + * Example: + * { number => number + 1 }.apply(8) ==> Answers 9 // 1 parameter + * { "screw" + "driver" }.apply() ==> Answers "screwdriver" // no parameter + */ + method apply(parameters...) native + + /** Answers a string representation of this closure object */ + override method toString() native + +} + +/** Represents days of week. */ + +object monday { } +object tuesday { } +object wednesday { } +object thursday { } +object friday { } +object saturday { } +object sunday { } +const daysOfWeek = [monday, tuesday, wednesday, thursday, friday, saturday, sunday] + +/** + * + * Represents a Date (without time). A Date is immutable, once created you can not change it. + * + * @since 1.4.5 + */ +class Date { + + const property day + const property month + const property year + + /** @private */ + method initialize() native + + /** String representation of a date */ + override method toString() = self.toSmartString(false) + + /** Two dates are equals if they represent the same date */ + override method ==(_aDate) native + + /** + * Answers a copy of this Date with the specified number of days added. + * Parameter must be an integer value. + * This operation has no side effect (a new date is returned). + * + * Example: + * new Date(day = 12, month = 5, year = 2018).plusDays(1) + * ==> Answers 13/5/2018, a day forward + * + * new Date(day = 12, month = 5, year = 2018).plusDays(-1) + * ==> Answers 11/5/2018, a day back + */ + method plusDays(_days) native + + /** + * Answers a copy of this Date with the specified number of months added. + * Parameter must be an integer value. + * This operation has no side effect (a new date is returned). + * + * Example: + * new Date(day = 31, month = 1, year = 2018).plusMonths(1) + * ==> Answers 28/2/2018, a month forward + * + * new Date(day = 12, month = 5, year = 2018).plusMonths(-1) + * ==> Answers 12/4/2018, a month back + */ + method plusMonths(_months) native + + /** + * Answers a copy of this Date with the specified number of years added. + * Parameter must be an integer value. + * This operation has no side effect (a new date is returned). + * + * Example: + * new Date(day = 31, month = 1, year = 2018).plusYears(1) + * ==> Answers 31/1/2019, a year forward + * + * new Date(day = 12, month = 5, year = 2018).plusYears(-1) + * ==> Answers 12/5/2017, a year back + */ + method plusYears(_years) native + + /** + * Checks if the year is a leap year, like 2000, 2004, 2008... + * + * Example: + * new Date(day = 12, month = 5, year = 2018).isLeapYear() ==> Answers false + */ + method isLeapYear() native + + /** Answers the day of the week of the Date with an object representation. + * There is a wko (well known object) for every day of the week. + * + * Example: + * new Date(day = 24, month = 2, year = 2018).dayOfWeek() ==> Answers saturday object + */ + method dayOfWeek() = daysOfWeek.get(self.internalDayOfWeek() - 1) + + /** Answers the day of week of the Date, where + * 1 = MONDAY + * 2 = TUESDAY + * 3 = WEDNESDAY + * ... + * 7 = SUNDAY + * + * Example: + * new Date(day = 24, month = 2, year = 2018).internalDayOfWeek() ==> Answers 6 (SATURDAY) + */ + method internalDayOfWeek() native + + /** + * Answers the difference in days between two dates, assuming self is minuend and _aDate is subtrahend. + * + * Examples: + * new Date().plusDays(4) - new Date() ==> Answers 4 + * new Date() - new Date().plusDays(2) ==> Answers -2 + */ + method -(_aDate) native + + /** + * Answers a copy of this date with the specified number of days subtracted. + * This instance is immutable and unaffected by this method call. + * Parameter must be an integer value. + * This operation has no side effect (a new date is returned). + * + * Examples: + * new Date(day = 1, month = 1, year = 2009).minusDays(1) + * ==> Answers 31/12/2008, a day back + * + * new Date(day = 1, month = 1, year = 2009).minusDays(-1) + * ==> Answers 2/1/2009, a day forward + */ + method minusDays(_days) native + + /** + * Answers a copy of this date with the specified number of months subtracted. + * Parameter must be an integer value. + * This operation has no side effect (a new date is returned). + * + * Examples: + * new Date(day = 1, month = 1, year = 2009).minusMonths(1) + * ==> Answers 1/12/2008, a month back + * + * new Date(day = 1, month = 1, year = 2009).minusMonths(-1) + * ==> Answers 1/2/2009, a month forward + */ + method minusMonths(_months) native + + /** + * Answers a copy of this date with the specified number of years subtracted. + * Parameter must be an integer value. + * This operation has no side effect (a new date is returned). + * + * Examples: + * new Date(day = 1, month = 1, year = 2009).minusYears(1) + * ==> Answers 1/1/2008, a year back + * + * new Date(day = 1, month = 1, year = 2009).minusYears(-1) + * ==> Answers 1/1/2010, a year forward + */ + method minusYears(_years) native + + method <(_aDate) native + method >(_aDate) native + method <=(_aDate) = (self < _aDate) || (self.equals(_aDate)) + method >=(_aDate) = (self > _aDate) || (self.equals(_aDate)) + + /** + * Answers whether self is between two dates (both inclusive comparison) + * + * Example: + * new Date(day = 2, month = 4, year = 2018).between(new Date(day = 1, month = 4, year = 2018), new Date(day = 2, month = 4, year = 2018)) + * ==> Answers true + */ + method between(_startDate, _endDate) = (self >= _startDate) && (self <= _endDate) + + /** Shows nicely an internal representation of a date **/ + override method toSmartString(alreadyShown) = + self.shortDescription() + + /** + * Shows a short, internal representation of a date + * (the result varies depending on user's locale) + * + * Example: + * new Date(day = 2, month = 4, year = 2018).shortDescription() + * ==> Answers 2/4/2018 + */ + override method shortDescription() native + +} + +object io { + const eventHandlers = new Dictionary() + var eventQueue = [] + + method queueEvent(event) { + eventQueue.add(event) + } + + // TODO: removeHandler + method addHandler(event, callback) { + if (!eventHandlers.containsKey(event)) eventHandlers.put(event, []) + eventHandlers.get(event).add(callback) + } + + method flushEvents() { + const currentEvents = eventQueue.copy() + eventQueue = [] + currentEvents.forEach{ event => + eventHandlers.getOrElse(event, { [] }).forEach{ callback => callback.apply() } + } + } +} diff --git a/org.uqbar.project.wollok.lib/src/wollok/lib.wlk b/org.uqbar.project.wollok.lib/src/wollok/lib.wlk deleted file mode 120000 index df6a69f86a..0000000000 --- a/org.uqbar.project.wollok.lib/src/wollok/lib.wlk +++ /dev/null @@ -1 +0,0 @@ -../../../wollok-language/src/wollok/lib.wlk \ No newline at end of file diff --git a/org.uqbar.project.wollok.lib/src/wollok/lib.wlk b/org.uqbar.project.wollok.lib/src/wollok/lib.wlk new file mode 100644 index 0000000000..78e904a87e --- /dev/null +++ b/org.uqbar.project.wollok.lib/src/wollok/lib.wlk @@ -0,0 +1,253 @@ +/** + * Console is a global wollok object that implements a character-based console device + * called "standard input/output" stream + */ +object console { + + /** Prints a String with end-of-line character */ + method println(obj) native + + /** Reads a line from input stream */ + method readLine() native + + /** Reads an int character from input stream */ + method readInt() native + + /** Returns the system's representation of a new line: + * - \n in Unix systems + * - \r\n in Windows systems + */ + method newline() native +} + +/** + * Exception to handle other values expected in assert.throwsException... methods + */ +class OtherValueExpectedException inherits wollok.lang.Exception {} + +/** + * Exception to handle difference between current and expected values + * in assert.throwsException... methods + */ +class AssertionException inherits Exception { + const property expected = null + const property actual = null +} + +/** + * Assert object simplifies testing conditions + */ +object assert { + + /** + * Tests whether value is true. Otherwise throws an exception. + * + * Example: + * assert.that(7.even()) ==> throws an exception "Value was not true" + * assert.that(8.even()) ==> ok, nothing happens + */ + method that(value) { + self.checkNotNull(value, "that") + if (!value) throw new AssertionException(message = "Value was not true") + } + + /** Tests whether value is false. Otherwise throws an exception. + * @see assert#that(value) + */ + method notThat(value) { + self.checkNotNull(value, "notThat") + if (value) throw new AssertionException(message = "Value was not false") + } + + /* + * This method avoids confusion with equals definition in Object + */ + override method equals(value) { + throw new AssertionException(message = "assert.equals(expected, actual): missing second parameter") + } + + /** + * Tests whether two values are equal, based on wollok ==, != methods + * + * Examples: + * assert.equals(10, 100.div(10)) ==> ok, nothing happens + * assert.equals(10.0, 100.div(10)) ==> ok, nothing happens + * assert.equals(10.01, 100.div(10)) ==> throws an exception + */ + method equals(expected, actual) { + if (expected != actual) throw new AssertionException(message = "Expected [" + expected.printString() + "] but found [" + actual.printString() + "]") + } + + /** + * Tests whether two values are equal, based on wollok ==, != methods + * + * Examples: + * const value = 5 + * assert.notEquals(10, value * 3) ==> ok, nothing happens + * assert.notEquals(10, value) ==> throws an exception + */ + method notEquals(expected, actual) { + if (expected == actual) throw new AssertionException(message = "Expected to be different, but [" + expected.printString() + "] and [" + actual.printString() + "] match") + } + + /** + * Tests whether a block throws an exception. Otherwise an exception is thrown. + * + * Examples: + * assert.throwsException({ 7 / 0 }) + * ==> Division by zero error, it is expected, ok + * + * assert.throwsException({ "hola".length() }) + * ==> throws an exception "Block should have failed" + */ + method throwsException(block) { + self.checkNotNull(block, "throwsException") + var failed = false + try { + block.apply() + } catch e { + failed = true + } + if (!failed) throw new AssertionException(message = "Block " + block + " should have failed") + } + + /** + * Tests whether a block throws an exception and this is the same expected. + * Otherwise an exception is thrown. + * + * Examples: + * assert.throwsExceptionLike(new BusinessException("hola"), + * { => throw new BusinessException("hola") } + * => Works! Exception class and message both match. + * + * assert.throwsExceptionLike(new BusinessException("chau"), + * { => throw new BusinessException("hola") } + * => Doesn't work. Exception class matches but messages are different. + * + * assert.throwsExceptionLike(new OtherException("hola"), + * { => throw new BusinessException("hola") } + * => Doesn't work. Messages matches but they are instances of different exceptions. + */ + method throwsExceptionLike(exceptionExpected, block) { + self.checkNotNull(exceptionExpected, "throwsExceptionLike") + self.checkNotNull(block, "throwsExceptionLike") + try + { + self.throwsExceptionByComparing(block, {a => a.equals(exceptionExpected)}) + } + catch ex : OtherValueExpectedException + { + throw new AssertionException(message = "The Exception expected was " + exceptionExpected + " but got " + ex.cause()) + } + } + + /** + * Tests whether a block throws an exception and it has the error message as is expected. + * Otherwise an exception is thrown. + * + * Examples: + * assert.throwsExceptionWithMessage("hola",{ => throw new BusinessException(message = "hola") } + * => Works! Both have the same message. + * + * assert.throwsExceptionWithMessage("hola",{ => throw new OtherException(message = "hola") } + * => Works! Both have the same message. + * + * assert.throwsExceptionWithMessage("chau",{ => throw new BusinessException(message = "hola") } + * => Doesn't work. Both are instances of BusinessException but their messages differ. + */ + method throwsExceptionWithMessage(errorMessage, block) { + self.checkNotNull(errorMessage, "throwsExceptionWithMessage") + self.checkNotNull(block, "throwsExceptionWithMessage") + try + { + self.throwsExceptionByComparing(block, {a => errorMessage.equals(a.message())}) + } + catch ex : OtherValueExpectedException + { + throw new AssertionException(message = "The error message expected was " + errorMessage + " but got " + ex.cause().message()) + } + } + + /** + * Tests whether a block throws an exception and this is the same exception class expected. + * Otherwise an exception is thrown. + * + * Examples: + * assert.throwsExceptionWithType(new BusinessException("hola"),{ => throw new BusinessException("hola") } + * => Works! Both exceptions are instances of the same class. + * + * assert.throwsExceptionWithType(new BusinessException("chau"),{ => throw new BusinessException("hola") } + * => Works again! Both exceptions are instances of the same class. + * + * assert.throwsExceptionWithType(new OtherException("hola"),{ => throw new BusinessException("hola") } + * => Doesn't work. Exception classes differ although they contain the same message. + */ + method throwsExceptionWithType(exceptionExpected, block) { + self.checkNotNull(exceptionExpected, "throwsExceptionWithType") + self.checkNotNull(block, "throwsExceptionWithType") + try + { + self.throwsExceptionByComparing(block,{a => exceptionExpected.className().equals(a.className())}) + } + catch ex : OtherValueExpectedException + { + throw new AssertionException(message = "The exception expected was " + exceptionExpected.className() + " but got " + ex.cause().className()) + } + } + + /** + * Tests whether a block throws an exception and compare this exception with other block + * called comparison. Otherwise an exception is thrown. The block comparison + * receives a value (an exception thrown) that is compared in a boolean expression + * returning the result. + * + * Examples: + * assert.throwsExceptionByComparing({ => throw new BusinessException("hola"),{ex => "hola".equals(ex.message())}} + * => Works!. + * + * assert.throwsExceptionByComparing({ => throw new BusinessException("hola"),{ex => new BusinessException("lele").className().equals(ex.className())} } + * => Works again! + * + * assert.throwsExceptionByComparing({ => throw new BusinessException("hola"),{ex => "chau!".equals(ex.message())} } + * => Doesn't work. The block evaluation resolves to a false value. + */ + method throwsExceptionByComparing(block, comparison){ + self.checkNotNull(block, "throwsExceptionByComparing") + self.checkNotNull(comparison, "throwsExceptionByComparing") + var continue = false + try + { + block.apply() + continue = true + } + catch ex + { + if(comparison.apply(ex)) + self.that(true) + else + throw new OtherValueExpectedException(message = "Expected other value", cause = ex) + } + if (continue) throw new AssertionException(message = "Should have thrown an exception") + } + + /** + * Throws an exception with a custom message. + * Useful when you reach code that should not be reached. + */ + method fail(message) { + self.checkNotNull(message, "fail") + throw new AssertionException(message = message) + } + +} + +class StringPrinter { + var buffer = "" + + method println(obj) { + const objAsString = if (obj === null) "null" else obj.toString() + buffer += objAsString + console.newline() + } + + method getBuffer() = buffer +} diff --git a/org.uqbar.project.wollok.lib/src/wollok/mirror.wlk b/org.uqbar.project.wollok.lib/src/wollok/mirror.wlk deleted file mode 120000 index 74fb5c030b..0000000000 --- a/org.uqbar.project.wollok.lib/src/wollok/mirror.wlk +++ /dev/null @@ -1 +0,0 @@ -../../../wollok-language/src/wollok/mirror.wlk \ No newline at end of file diff --git a/org.uqbar.project.wollok.lib/src/wollok/mirror.wlk b/org.uqbar.project.wollok.lib/src/wollok/mirror.wlk new file mode 100644 index 0000000000..08ae25802c --- /dev/null +++ b/org.uqbar.project.wollok.lib/src/wollok/mirror.wlk @@ -0,0 +1,13 @@ +class InstanceVariableMirror { + const target + const property name + + method value() = target.resolve(name) + + method valueToSmartString(alreadyShown) { + const value = self.value() + return if (value == null) "null" else value.toSmartString(alreadyShown) + } + + override method toString() = name + "=" + self.value() +} diff --git a/org.uqbar.project.wollok.lib/src/wollok/vm.wlk b/org.uqbar.project.wollok.lib/src/wollok/vm.wlk deleted file mode 120000 index 77bf6dfea6..0000000000 --- a/org.uqbar.project.wollok.lib/src/wollok/vm.wlk +++ /dev/null @@ -1 +0,0 @@ -../../../wollok-language/src/wollok/vm.wlk \ No newline at end of file diff --git a/org.uqbar.project.wollok.lib/src/wollok/vm.wlk b/org.uqbar.project.wollok.lib/src/wollok/vm.wlk new file mode 100644 index 0000000000..17b74b0af9 --- /dev/null +++ b/org.uqbar.project.wollok.lib/src/wollok/vm.wlk @@ -0,0 +1,3 @@ +object runtime { + method isInteractive() native +} diff --git a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/StringPrinterTestCase.xtend b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/StringPrinterTestCase.xtend deleted file mode 100644 index 0bc3b06d47..0000000000 --- a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/StringPrinterTestCase.xtend +++ /dev/null @@ -1,35 +0,0 @@ -package org.uqbar.project.wollok.tests.interpreter - -import org.junit.Test - -/** - * Tests for String Printer - * - * @author dodain - */ -class StringPrinterTestCase extends AbstractWollokInterpreterTestCase { - - @Test - def void printingNull() { - ''' - const printer = new StringPrinter() - printer.println(null) - assert.equals("null", printer.getBuffer().trim()) - '''.test - } - - @Test - def void printingSomethingNotNullUsesToStringMethod() { - ''' - const pepita = object { - var energia = 10 - override method toString() = "pepita" - } - - const printer = new StringPrinter() - printer.println(pepita) - assert.equals("pepita", printer.getBuffer().trim()) - '''.test - } - -} \ No newline at end of file diff --git a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/RuntimeTest.xtend b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/language/RuntimeTest.xtend similarity index 54% rename from org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/RuntimeTest.xtend rename to org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/language/RuntimeTest.xtend index b5c2ac6b76..814bbe6fac 100644 --- a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/RuntimeTest.xtend +++ b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/language/RuntimeTest.xtend @@ -1,8 +1,8 @@ -package org.uqbar.project.wollok.tests.interpreter +package org.uqbar.project.wollok.tests.interpreter.language import org.junit.Test -class RuntimeTest extends AbstractWollokInterpreterTestCase { +class RuntimeTest extends org.uqbar.project.wollok.tests.interpreter.AbstractWollokInterpreterTestCase { @Test def void testInteractive() { ''' diff --git a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/libraries/WollokLibExtensionsTest.xtend b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/libraries/WollokLibExtensionsTest.xtend index 9323ad671c..5f9bf5cce8 100644 --- a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/libraries/WollokLibExtensionsTest.xtend +++ b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/libraries/WollokLibExtensionsTest.xtend @@ -2,9 +2,10 @@ package org.uqbar.project.wollok.tests.libraries import org.junit.Test import org.uqbar.project.wollok.libraries.WollokLibExtensions -import org.junit.rules.TestName -import static org.junit.Assert.assertTrue + import static org.junit.Assert.assertFalse +import static org.junit.Assert.assertTrue + class WollokLibExtensionsTest { public static class IsCoreLibTest{ diff --git a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/multithread/WollokMultiInterpreterTest.xtend b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/multithread/WollokMultiInterpreterTest.xtend index bd29ea91e1..73c812c637 100644 --- a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/multithread/WollokMultiInterpreterTest.xtend +++ b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/multithread/WollokMultiInterpreterTest.xtend @@ -64,8 +64,8 @@ class WollokMultiInterpreterTest { @Test @Ignore def void testRunALotOfPrograms() { - val numberOfThreads = 4 - val numberOfTimes = 5 + val numberOfThreads = 3 + val numberOfTimes = 4 var startTime = System.currentTimeMillis val parameters = new WollokLauncherParameters() @@ -74,15 +74,15 @@ class WollokMultiInterpreterTest { val program = ''' object pepita { - var energia = 100 + var energia = 50 method energia() = energia method volar() { energia -= 1 } } test "pepita vuela" { - (1..100).forEach{ i => + (1..50).forEach{ i => pepita.volar() - assert.equals(100-i, pepita.energia()) + assert.equals(50-i, pepita.energia()) } } ''' From 844d092c5f8aee3a287fe2a64b4ea240dc02a461 Mon Sep 17 00:00:00 2001 From: nicovio Date: Fri, 1 Nov 2019 19:23:15 -0300 Subject: [PATCH 087/133] change importToAddLocation method in QuickFixUtils --- .../wollok/ui/quickfix/QuickFixUtils.xtend | 21 +++++++++---------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/org.uqbar.project.wollok.ui/src/org/uqbar/project/wollok/ui/quickfix/QuickFixUtils.xtend b/org.uqbar.project.wollok.ui/src/org/uqbar/project/wollok/ui/quickfix/QuickFixUtils.xtend index bd8fcebb04..4bc80958f7 100644 --- a/org.uqbar.project.wollok.ui/src/org/uqbar/project/wollok/ui/quickfix/QuickFixUtils.xtend +++ b/org.uqbar.project.wollok.ui/src/org/uqbar/project/wollok/ui/quickfix/QuickFixUtils.xtend @@ -285,20 +285,19 @@ class QuickFixUtils { } def static Location importToAddLocation(IXtextDocument xtextDocument, int position) { - val IRegion lineInformation = xtextDocument.getLineInformationOfOffset(position) - val String lineText = xtextDocument.lineText(position) - val String nextLineText = xtextDocument.lineText(lineInformation.endOfLine + 2) - var Location result - - if (position.equals(0)) { + var Location result = Location.AFTER + val firstImportPosition = 0 + if (position.equals(firstImportPosition)) { + val IRegion lineInformation = xtextDocument.getLineInformationOfOffset(position) + val String lineText = xtextDocument.lineText(position) + val String nextLineText = xtextDocument.lineText(lineInformation.endOfLine + 2) if (!lineText.isEmpty) result = Location.TWOLINESBEFORE - else if(!nextLineText.isEmpty) result = Location.BEFORE else result = Location.NONE - } else { - if(!nextLineText.isEmpty) result = Location.ALL else result = Location.AFTER - + else if (!nextLineText.isEmpty) + result = Location.BEFORE + else + result = Location.NONE } - result } From 0e15f5cb330d067df2d546e77741172ee6b69e1a Mon Sep 17 00:00:00 2001 From: fdodino Date: Fri, 1 Nov 2019 21:49:58 -0300 Subject: [PATCH 088/133] Fix Script for generating links to wollok-language --- .gitignore | 23 +++++++++++++++++------ README.md | 13 +++++++------ appveyor.yml | 2 +- install.sh | 4 ++++ 4 files changed, 29 insertions(+), 13 deletions(-) create mode 100644 install.sh diff --git a/.gitignore b/.gitignore index 53489ab5a2..a6b1774a9a 100644 --- a/.gitignore +++ b/.gitignore @@ -1,9 +1,4 @@ -*/bin/ -/eclipse/* -**/target/ -.metadata/* .DS_Store -/target/ */workspace/ org.eclipse.* pom.xml.versionsBackup @@ -11,13 +6,29 @@ pom.xml.versionsBackup CHANGELOG.txt changelog.txt CHANGELOG.md + +# Xtend generated files +/target/ xtend-gen +*/bin/ +**/target/ + +# Eclipse files +.metadata/* +/eclipse/* eclipse .classpath .project .recommenders + +# VSC - Git Lens .history + +# Release scripts scripts/libs scripts/jars scripts/wollok-site -scripts/wollok-cli \ No newline at end of file +scripts/wollok-cli + +# Ignoring wollok-language files +org.uqbar.project.wollok.lib/src/wollok/*.wlk diff --git a/README.md b/README.md index 671c3c26dd..7e88eb0236 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,10 @@ A programming language and environment for teaching OOP. +## Xtext-based implementation notes + +This is the main repository for the Wollok Xtext-based implementation, which is part of the [Wollok Language Specification](https://github.com/uqbar-project/wollok-language) + ## Installation ## You have two options to download an use Wollok. @@ -28,7 +32,7 @@ Or drag and drop Date: Fri, 1 Nov 2019 21:51:31 -0300 Subject: [PATCH 089/133] appveyor script requires no ./ --- appveyor.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/appveyor.yml b/appveyor.yml index 0fc9f216e3..e4f81a4c68 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -2,7 +2,7 @@ version: '{build}' os: Windows Server 2012 install: - cd %APPVEYOR_BUILD_FOLDER% - - ./install.sh + - install.sh - ps: | Add-Type -AssemblyName System.IO.Compression.FileSystem if (!(Test-Path -Path "C:\maven" )) { From 2987d37cc0dba68a9ec77f045814404b535f81aa Mon Sep 17 00:00:00 2001 From: fdodino Date: Fri, 1 Nov 2019 22:12:48 -0300 Subject: [PATCH 090/133] Fixing appveyor --- appveyor.yml | 2 +- install.bat | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) create mode 100644 install.bat diff --git a/appveyor.yml b/appveyor.yml index e4f81a4c68..cbd806b411 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -2,7 +2,7 @@ version: '{build}' os: Windows Server 2012 install: - cd %APPVEYOR_BUILD_FOLDER% - - install.sh + - install.bat - ps: | Add-Type -AssemblyName System.IO.Compression.FileSystem if (!(Test-Path -Path "C:\maven" )) { diff --git a/install.bat b/install.bat new file mode 100644 index 0000000000..77e107dbff --- /dev/null +++ b/install.bat @@ -0,0 +1,2 @@ +git submodule update --init --recursive +for %%f in (./wollok-language/src/wollok/*.wlk) do mklink %%f "../../org.uqbar.project.wollok.lib/src/wollok/%%f" From 7e04f3eb826bb03e2cd65cf52fadc3d9dc0c1076 Mon Sep 17 00:00:00 2001 From: Fernando Dodino Date: Fri, 1 Nov 2019 23:25:48 -0300 Subject: [PATCH 091/133] Adding install.sh to travis --- .gitignore | 2 +- .travis.yml | 1 + install.sh | 0 .../src/wollok/game.wlk | 471 --- .../src/wollok/lang.wlk | 2756 ----------------- .../src/wollok/lib.wlk | 253 -- .../src/wollok/mirror.wlk | 13 - .../src/wollok/vm.wlk | 3 - 8 files changed, 2 insertions(+), 3497 deletions(-) mode change 100644 => 100755 install.sh delete mode 100644 org.uqbar.project.wollok.lib/src/wollok/game.wlk delete mode 100644 org.uqbar.project.wollok.lib/src/wollok/lang.wlk delete mode 100644 org.uqbar.project.wollok.lib/src/wollok/lib.wlk delete mode 100644 org.uqbar.project.wollok.lib/src/wollok/mirror.wlk delete mode 100644 org.uqbar.project.wollok.lib/src/wollok/vm.wlk diff --git a/.gitignore b/.gitignore index a6b1774a9a..457b6ba85f 100644 --- a/.gitignore +++ b/.gitignore @@ -31,4 +31,4 @@ scripts/wollok-site scripts/wollok-cli # Ignoring wollok-language files -org.uqbar.project.wollok.lib/src/wollok/*.wlk +# org.uqbar.project.wollok.lib/src/wollok/*.wlk diff --git a/.travis.yml b/.travis.yml index 8d12aa3d7d..3a4e27d330 100644 --- a/.travis.yml +++ b/.travis.yml @@ -17,6 +17,7 @@ after_success: cd .. fi script: +- install.sh - cd org.uqbar.project.wollok.releng/ - export PROFILES=normalProfile - export UPDATE_SITE=none diff --git a/install.sh b/install.sh old mode 100644 new mode 100755 diff --git a/org.uqbar.project.wollok.lib/src/wollok/game.wlk b/org.uqbar.project.wollok.lib/src/wollok/game.wlk deleted file mode 100644 index dc00c52465..0000000000 --- a/org.uqbar.project.wollok.lib/src/wollok/game.wlk +++ /dev/null @@ -1,471 +0,0 @@ -import wollok.vm.runtime - -/** - * Wollok Game main object - */ -object game { - - /** - * Adds an object to the board for drawing it. - * Object should understand a position property - * (implemented by a reference or getter method). - * - * Example: - * game.addVisual(pepita) ==> pepita should have a position property - */ - method addVisual(positionable) native - - /** - * Adds an object to the board for drawing it on a specific position. - * - * Example: - * game.addVisualIn(pepita, game.origin()) ==> no need for pepita to have a position property - * game.addVisualIn(pepita, game.at(2, 2)) - */ - method addVisualIn(element, position) native - - - /** - * Adds an object to the board for drawing it. It can be moved with arrow keys. - * That object should understand a position property - * (implemented by a reference or getter method). - * - * Example: - * game.addVisualCharacter(pepita) ==> pepita should have a position property - */ - method addVisualCharacter(positionable) native - - /** - * Adds an object to the board for drawing it on a specific position. It can be moved with arrow keys. - * - * Example: - * game.addVisualCharacterIn(pepita, game.origin()) ==> no need for pepita to have a position property - */ - method addVisualCharacterIn(element, position) native - - /** - * Removes an object from the board for stop drawing it. - * - * Example: - * game.removeVisual(pepita) - */ - method removeVisual(visual) native - - /** - * Verifies if an object is currently in the board. - * - * Example: - * game.hasVisual(pepita) - */ - method hasVisual(visual) native - - /** - * Returns all visual objects added to the board. - * - * Example: - * game.allVisuals() - */ - method allVisuals() native - - /** - * Adds a block that will be executed each time a specific key is pressed - * @see keyboard.onPressDo() - */ - method whenKeyPressedDo(key, action) native - - /** - * Adds a block that will be executed while the given object collides with other. - * Two objects collide when are in the same position. - * - * The block should expect the other object as parameter. - * - * Example: - * game.whenCollideDo(pepita, { comida => pepita.comer(comida) }) - */ - method whenCollideDo(visual, action) native - - /** - * Adds a block that will be executed exactly when the given object collides with other. - * Two objects collide when are in the same position. - * - * The block should expect the other object as parameter. - * - * Example: - * game.onCollideDo(pepita, { comida => pepita.comer(comida) }) - */ - method onCollideDo(visual, action) native - - /** - * Adds a block with a specific name that will be executed every n milliseconds. - * Block expects no argument. - * Be careful not to set it too often :) - * - * Example: - * game.onTick(5000, "pepitaMoving", { => pepita.position().x(0.randomUpTo(4)) }) - */ - method onTick(milliseconds, name, action) native - - /** - * Adds a block that will be executed in n milliseconds. - * Block expects no argument. - * - * Example: - * game.schedule(5000, { => pepita.position().x(0.randomUpTo(4)) }) - */ - method schedule(milliseconds, action) native - - /** - * Remove a tick event created with onTick message - * - * Example: - * game.removeTickEvent("pepitaMoving") - */ - method removeTickEvent(name) native - - /** - * Returns all objects in given position. - * - * Example: - * game.getObjectsIn(game.origin()) - */ - method getObjectsIn(position) native - - /** - * Draws a dialog balloon with given message in given visual object position. - * - * Example: - * game.say(pepita, "hola!") - */ - method say(visual, message) native - - /** - * Removes all visual objects on board and configurations (colliders, keys, etc). - */ - method clear() native - - /** - * Returns all objects that are in same position of given object. - */ - method colliders(visual) native - - /** - * Returns the unique object that is in same position of given object. - */ - method uniqueCollider(visual) = self.colliders(visual).uniqueElement() - - /** - * Stops render the board and finish the game. - */ - method stop() native - - /** - * Starts render the board in a new windows. - */ - method start() { - self.doStart(runtime.isInteractive()) - } - - /** - * Returns a position for given coordinates. - */ - method at(x, y) { - return new Position(x = x, y = y) - } - - /** - * Returns the position (0,0). - */ - method origin() = self.at(0, 0) - - /** - * Returns the center board position (rounded down). - */ - method center() = self.at(self.width().div(2), self.height().div(2)) - - /** - * Sets game title. - */ - method title(title) native - - /** - * Returns game title. - */ - method title() native - - /** - * Sets board width (in cells). - */ - method width(width) native - - /** - * Returns board width (in cells). - */ - method width() native - - /** - * Sets board height (in cells). - */ - method height(height) native - - /** - * Returns board height (in cells). - */ - method height() native - - /** - * Sets cells background image. - */ - method ground(image) native - - /** - * Sets full background image. - */ - method boardGround(image) native - - /** - * Attributes will not show when user mouse over a visual component. - * Default behavior is to show them. - */ - method hideAttributes(visual) native - - /** - * Attributes will appear again when user mouse over a visual component. - * Default behavior is to show them, so this is not necessary. - */ - method showAttributes(visual) native - - /** - * Allows to configure a visual component as "error reporter". - * Then every error in game board will be reported by this visual component, - * in a balloon message form. - */ - method errorReporter(visual) native - - /** - * Plays once a .mp3, .ogg or .wav audio file - */ - method sound(audioFile) native - - /** - * @private - */ - method doStart(isRepl) native -} - -/** - * Represents a position in a two-dimensional gameboard. - * It is an immutable object since Wollok 1.8.0 - */ -class Position { - const property x = 0 - const property y = 0 - - /** - * Returns a new Position n steps right from this one. - */ - method right(n) = new Position(x = x + n, y = y) - - /** - * Returns a new Position n steps left from this one. - */ - method left(n) = new Position(x = x - n, y = y) - - /** - * Returns a new Position n steps up from this one. - */ - method up(n) = new Position(x = x, y = y + n) - - /** - * Returns a new Position, n steps down from this one. - */ - method down(n) = new Position(x = x, y = y - n) - - /** - * Adds an object to the board for drawing it in self. - */ - method drawElement(element) { game.addVisualIn(element, self) } //TODO: Implement native - - /** - * Adds an object to the board for drawing it in self. It can be moved with arrow keys. - */ - method drawCharacter(element) { game.addVisualCharacterIn(element, self) } //TODO: Implement native - - /** - * Draw a dialog balloon with given message in given visual object position. - */ - method say(element, message) { game.say(element, message) } //TODO: Implement native - - /** - * Returns all objects in self. - */ - method allElements() = game.getObjectsIn(self) //TODO: Implement native - - /** - * Returns a new position with same coordinates. - */ - method clone() = new Position(x = x, y = y) - - /** - * Returns the distance between given position and self. - */ - method distance(position) { - self.checkNotNull(position, "distance") - const deltaX = x - position.x() - const deltaY = y - position.y() - return (deltaX.square() + deltaY.square()).squareRoot() - } - - /** - * Removes all objects in self from the board for stop drawing it. - */ - method clear() { - self.allElements().forEach{it => game.removeVisual(it)} - } - - /** - * Two positions are equals if they have same coordinates. - */ - override method ==(other) = x == other.x() && y == other.y() - - /** - * String representation of a position - */ - override method toString() = "(" + x + "," + y + ")" - -} - -/** - * Keyboard object handles all keys movements. There is a method for each key. - * - * Examples: - * keyboard.i().onPressDo { game.say(pepita, "hola!") } - * => when user hits "i" key, pepita will say "hola!" - * - * keyboard.any().onPressDo { game.say(pepita, "you pressed a key!") } - * => any key pressed will activate its closure - */ -object keyboard { - - method any() = new Key(keyCodes = [-1]) - - method num(n) = new Key(keyCodes = [n + 7, n + 144]) - - method num0() = self.num(0) - - method num1() = self.num(1) - - method num2() = self.num(2) - - method num3() = self.num(3) - - method num4() = self.num(4) - - method num5() = self.num(5) - - method num6() = self.num(6) - - method num7() = self.num(7) - - method num8() = self.num(8) - - method num9() = self.num(9) - - method a() = new Key(keyCodes = [29]) - - method alt() = new Key(keyCodes = [57, 58]) - - method b() = new Key(keyCodes = [30]) - - method backspace() = new Key(keyCodes = [67]) - - method c() = new Key(keyCodes = [31]) - - method control() = new Key(keyCodes = [129, 130]) - - method d() = new Key(keyCodes = [32]) - - method del() = new Key(keyCodes = [67]) - - method center() = new Key(keyCodes = [23]) - - method down() = new Key(keyCodes = [20]) - - method left() = new Key(keyCodes = [21]) - - method right() = new Key(keyCodes = [22]) - - method up() = new Key(keyCodes = [19]) - - method e() = new Key(keyCodes = [33]) - - method enter() = new Key(keyCodes = [66]) - - method f() = new Key(keyCodes = [34]) - - method g() = new Key(keyCodes = [35]) - - method h() = new Key(keyCodes = [36]) - - method i() = new Key(keyCodes = [37]) - - method j() = new Key(keyCodes = [38]) - - method k() = new Key(keyCodes = [39]) - - method l() = new Key(keyCodes = [40]) - - method m() = new Key(keyCodes = [41]) - - method minusKey() = new Key(keyCodes = [69]) - - method n() = new Key(keyCodes = [42]) - - method o() = new Key(keyCodes = [43]) - - method p() = new Key(keyCodes = [44]) - - method plusKey() = new Key(keyCodes = [81]) - - method q() = new Key(keyCodes = [45]) - - method r() = new Key(keyCodes = [46]) - - method s() = new Key(keyCodes = [47]) - - method shift() = new Key(keyCodes = [59, 60]) - - method slash() = new Key(keyCodes = [76]) - - method space() = new Key(keyCodes = [62]) - - method t() = new Key(keyCodes = [48]) - - method u() = new Key(keyCodes = [49]) - - method v() = new Key(keyCodes = [50]) - - method w() = new Key(keyCodes = [51]) - - method x() = new Key(keyCodes = [52]) - - method y() = new Key(keyCodes = [53]) - - method z() = new Key(keyCodes = [54]) - -} - - -class Key { - const property keyCodes - - /** - * Adds a block that will be executed always self is pressed. - * - * Example: - * keyboard.i().onPressDo { game.say(pepita, "hola!") } - * => when user hits "i" key, pepita will say "hola!" - */ - method onPressDo(action) { - keyCodes.forEach{ key => game.whenKeyPressedDo(key, action) } //TODO: Implement native - } -} diff --git a/org.uqbar.project.wollok.lib/src/wollok/lang.wlk b/org.uqbar.project.wollok.lib/src/wollok/lang.wlk deleted file mode 100644 index 5d4a7e0ce2..0000000000 --- a/org.uqbar.project.wollok.lib/src/wollok/lang.wlk +++ /dev/null @@ -1,2756 +0,0 @@ -/** - * Base class for all Exceptions. Every exception and its subclasses - * indicates conditions that a reasonable application might want to catch. - * - * @author jfernandes - * @since 1.0 - */ -class Exception { - /** specified detail message. */ - const property message = null - - /** specified cause */ - const property cause = null - - /** Prints this exception and its backtrace to the console */ - method printStackTrace() { self.printStackTrace(console) } - - /** Prints this exception and its backtrace as a string value */ - method getStackTraceAsString() { - const printer = new StringPrinter() - self.printStackTrace(printer) - return printer.getBuffer() - } - - /** - * @private - * Prints this exception and its backtrace to the specified printer - */ - method printStackTrace(printer) { self.printStackTraceWithPrefix("", printer) } - - /** @private */ - method printStackTraceWithPrefix(prefix, printer) { - printer.println(prefix + self.className() + (if (message != null) (": " + message.toString()) else "")) - - // TODO: eventually we will need a stringbuffer or something to avoid memory consumption - self.getStackTrace().forEach { e => - printer.println("\tat " + e.contextDescription() + " [" + e.location() + "]") - } - - if (cause != null) - cause.printStackTraceWithPrefix("Caused by: ", printer) - } - - /** @private */ - method createStackTraceElement(contextDescription, location) = new StackTraceElement(contextDescription = contextDescription, location = location) - - /** Provides programmatic access to the stack trace information - * printed by printStackTrace() with full path files for linking - */ - method getFullStackTrace() native - - /** Provides programmatic access to the stack trace information - * printed by printStackTrace(). - */ - method getStackTrace() native - - /** Overrides the behavior to compare exceptions */ - override method equals(other) = other.className().equals(self.className()) && other.message() == self.message() -} - -/** - * Thrown when a stack overflow occurs because an application recurses too deeply. - * - * @author jfernandes - * @since 1.5.1 - */ -class StackOverflowException inherits Exception {} - -/** - * An exception that is thrown when a specified element cannot be found - */ -class ElementNotFoundException inherits Exception {} - -/** - * An exception that is thrown for domain purpose - */ -class DomainException inherits Exception { - const property source = null -} - -/** - * (added by wollok-ts) An exception thrown whenever the interpreter fails to evaluate an expression - */ -class EvaluationError inherits Exception {} - -/** - * An exception that is thrown when an object cannot understand a certain message - */ -class MessageNotUnderstoodException inherits Exception {} - -/** - * An element in a stack trace, represented by a context and a location - * of a method where a message was sent - */ -class StackTraceElement { - const property contextDescription - const property location -} - -/** - * - * Representation of Wollok Object - * - * Class Object is the root of the class hierarchy. - * Every class has Object as a superclass. - * - * @author jfernandes - * since 1.0 - */ -class Object { - - /** - * Answers object identity of a Wollok object, represented by - * a unique number in Wollok environment - */ - method identity() native - - /** - * Answers a list of instance variables for this Wollok object - * @private - needed by wollok-xtext implementation - */ - method instanceVariables() native - - /** - * Retrieves a specific variable. Expects a name - * @private - needed by wollok-xtext implementation - */ - method instanceVariableFor(name) native - - /** - * Accesses a variable by name, in a reflexive way. - * @private - needed by wollok-xtext implementation - */ - method resolve(name) native - - /** Object description in english/spanish/... (depending on i18n configuration) - * - * Examples: - * "2".kindName() => Answers "a String" - * 2.kindName() => Answers "a Integer" - * - * @private - */ - method kindName() native - - /** - * Full name of Wollok object class - * @private - */ - method className() native - - /** - * Tells whether self object is "equal" to the given object - * The default behavior compares them in terms of identity (===) - */ - method ==(other) = other != null && self === other - - /** Tells whether self object is not equal to the given one */ - method !=(other) = ! (self == other) - - /** - * Tells whether self object is identical (the same) to the given one. - * It does it by comparing their identities. - * So self basically relies on the wollok.lang.Integer equality (which is native) - */ - method ===(other) = self.identity() == other.identity() - - /** - * Tells whether self object is not identical (the same) to the given one. - * @See === message. - */ - method !==(other) = ! (self === other) - - /** - * o1.equals(o2) is a synonym for o1 == o2 - */ - method equals(other) = self == other - - /** - * Generates a Pair key-value association. @see Pair. - */ - method ->(other) { - return new Pair(x = self, y = other) - } - - /** - * String representation of Wollok object - */ - method toString() { - return self.toSmartString([]) - } - - /** - * Shows a short, internal representation - */ - method shortDescription() = self.toString() - - /** - * Provides a visual representation of Wollok Object - * By default, same as toString but can be overridden - * like in String - */ - method printString() = self.toString() - - /** @private */ - method toSmartString(alreadyShown) { - if (alreadyShown.any { e => e.identity() == self.identity() } ) { - return self.simplifiedToSmartString() - } - else { - alreadyShown.add(self) - return self.internalToSmartString(alreadyShown) - } - } - - /** @private */ - method simplifiedToSmartString() = self.kindName() - - /** @private */ - method internalToSmartString(alreadyShown) { - return self.kindName() + "[" - + self.instanceVariables().map { v => - v.name() + "=" + v.valueToSmartString(alreadyShown) - }.join(', ') - + "]" - } - - /** @private */ - method messageNotUnderstood(messageName, parameters) { - const target = if (messageName != "toString") - self.toString() - else - self.kindName() - const aMessage = self.generateDoesNotUnderstandMessage(target, messageName, parameters.size()) - throw new MessageNotUnderstoodException(message = aMessage) - } - - /** - * @private - * - * internal method: generates a does not understand message - * parametersSize must be an integer value - */ - method generateDoesNotUnderstandMessage(target, messageName, parametersSize) native - - /** Builds an exception with a message */ - method error(aMessage) { - throw new DomainException(message = aMessage, source = self) - } - - /** @private */ - method checkNotNull(value, message) native -} - -/** Representation for methods that only have side effects */ -object void { } - -/** - * Representation of a Key/Value Association. - * It is also useful if you want to model a Point. - */ -class Pair { - const property x - const property y - constructor (_x, _y) { - x = _x - y = _y - } - method key() = x - method value() = y - - /** - * Two pairs are equal if they have the same values - * - * Example: - * new Pair(1, 2).equals(new Pair(1, 2)) ==> Answers true - */ - override method equals(other) { - self.checkNotNull(other, "equals") - return x == other.x() && y == other.y() - } - - /** String representation of a Pair */ - override method toString() = x.toString() + " -> " + y.toString() -} - -/** - * The root class in the collection hierarchy. - * A collection represents a group of objects, known as its elements. - */ -class Collection { - /** - * Answers the element that is considered to be/have the maximum value. - * The criteria is given by a closure that receives a single element - * as input (one of the element). The closure must return a comparable - * value (something that understands the >, >= messages). - * If collection is empty, an ElementNotFound exception is thrown. - * - * Example: - * ["a", "ab", "abc", "d" ].max({ e => e.length() }) - * => Answers "abc" - * - * [].max({ e => e.length() }) - * => Throws error, list must not be empty - */ - method max(closure) { - self.checkNotNull(closure, "max") - return self.maxIfEmpty(closure, { throw new ElementNotFoundException(message = "collection is empty") }) - } - - /** - * Answers the element that represents the maximum value in the collection. - * The criteria is by direct comparison of the elements. - * If collection is empty, an ElementNotFound exception is thrown. - * - * Example: - * [11, 1, 4, 8, 3, 15, 6].max() => Answers 15 - * [].max() => Throws error, list must not be empty - */ - method max() = self.max({it => it}) - - /** - * Answers the element that is considered to be/have the maximum value, - * or applies a closure if the collection is empty. - * The criteria is given by a closure that receives a single element - * as input (one of the element). The closure must return a comparable - * value (something that understands the >, >= messages). - * The closure to execute when the collection is empty is given as a second - * argument. - * - * Example: - * ["a", "ab", "abc", "d" ].maxIfEmpty({ e => e.length() }, { "default" }) - * => Answers "abc" - * - * [].maxIfEmpty({ e => e.length() }, { "default" }) - * => Answers "default" - */ - method maxIfEmpty(toComparableClosure, emptyCaseClosure) { - self.checkNotNull(toComparableClosure, "maxIfEmpty") - self.checkNotNull(emptyCaseClosure, "maxIfEmpty") - return self.absolute(toComparableClosure, { a, b => a > b }, emptyCaseClosure) - } - - /** - * Answers the element that is considered to be/have the maximum value, - * or applies a closure if the collection is empty. - * The criteria is by direct comparison of the elements. - * The closure to execute when the collection is empty is given as a second - * argument. - * - * Example: - * [11, 1, 4, 8, 3, 15, 6].maxIfEmpty({ 99 }) => Answers 15 - * [].maxIfEmpty({ 99 }) => Answers 99 - */ - method maxIfEmpty(emptyCaseClosure) = self.maxIfEmpty({it => it}, emptyCaseClosure) - - /** - * Answers the element that is considered to be/have the minimum value. - * The criteria is given by a closure that receives a single element - * as input (one of the element). The closure must return a comparable - * value (something that understands the <, <= messages). - * - * Example: - * ["ab", "abc", "hello", "wollok world"].min({ e => e.length() }) - * => Answers "ab" - * - * [].min({ e => e.length() }) - * => Throws error, list must not be empty - */ - method min(closure) { - self.checkNotNull(closure, "min") - return self.absolute(closure, { a, b => a < b }, { throw new ElementNotFoundException(message = "collection is empty") }) - } - - /** - * Answers the element that represents the minimum value in the - * non-empty collection. - * The criteria is by direct comparison of the elements. - * - * Example: - * [11, 1, 4, 8, 3, 15, 6].min() => Answers 1 - * [].min() => Throws error, list must not be empty - */ - method min() = self.min({it => it}) - - /** - * Answers the element that is considered to be/have the minimum value, - * or applies a closure if the collection is empty. - * The criteria is given by a closure that receives a single element - * as input (one of the element). The closure must return a comparable - * value (something that understands the >, >= messages). - * The closure to execute when the collection is empty is given as a second - * argument. - * - * Example: - * ["ab", "abc", "hello", "wollok world"].minIfEmpty({ e => e.length() }, { "default" }) - * => Answers "ab" - * - * [].minIfEmpty({ e => e.length() }, { "default" }) - * => Answers "default" - */ - method minIfEmpty(toComparableClosure, emptyCaseClosure) { - self.checkNotNull(toComparableClosure, "minIfEmpty") - self.checkNotNull(emptyCaseClosure, "minIfEmpty") - return self.absolute(toComparableClosure, { a, b => a < b }, emptyCaseClosure) - } - - /** - * Answers the element that is considered to be/have the minimum value, - * or applies a closure if the collection is empty. - * The criteria is by direct comparison of the elements. - * The closure to execute when the collection is empty is given as a second - * argument. - * - * Example: - * [11, 1, 4, 8, 3, 15, 6].minIfEmpty({ 99 }) => Answers 1 - * [].minIfEmpty({ 99 }) => Answers 99 - */ - method minIfEmpty(emptyCaseClosure) { - self.checkNotNull(emptyCaseClosure, "minIfEmpty") - return self.minIfEmpty({it => it}, emptyCaseClosure) - } - - /** @private */ - method absolute(closure, criteria, emptyCaseClosure) { - self.checkNotNull(closure, "absolute") - self.checkNotNull(criteria, "absolute") - self.checkNotNull(emptyCaseClosure, "absolute") - if (self.isEmpty()) { - return emptyCaseClosure.apply() - } - const result = self.fold(null, { acc, e => - const n = closure.apply(e) - if (acc == null) - e -> n - else { - if (criteria.apply(n, acc.y())) - e -> n - else - acc - } - }) - return result.x() - } - - /** - * Answers the unique element in the collection. - * If collection is empty, an error is thrown. - * If collection has more than one element, an error is thrown. - * - * Example: - * [1].uniqueElement() => Answers 1 - * [].uniqueElement() => Throws error, list must not be empty - * [1, 2].uniqueElement() => Throws error, list must have one element - */ - method uniqueElement() { - self.validateNotEmpty("uniqueElement") - const size = self.size() - if (size > 1) - throw new Exception(message = "Illegal operation 'uniqueElement' on collection with " + size.toString() + " elements") - return self.anyOne() - } - - - // non-native methods - - /** - * Concatenates this collection to all elements from the given - * collection parameter giving a new collection - * (no side effect) - * - * Example: - * [1, 2] + [3] => Answers [1, 2, 3] - * [1, 2] + #{3} => supports concatenation between lists and sets, answers [1, 2, 3] - * #{} + [] => Answers #{} - */ - method +(elements) { - const newCol = self.copy() - newCol.addAll(elements) - return newCol - } - - /** - * Adds all elements from the given collection parameter to self collection. - * This is a side effect operation. - * - * Example: - * const list = [] - * list.addAll(#{2, 4}) => list == [2, 4], always pointing to a list - */ - method addAll(elements) { - self.checkNotNull(elements, "addAll") - elements.forEach { element => self.add(element) } - } - - /** - * Removes all elements of the given collection parameter from self collection. - * This is a side effect operation. - * - * Example: - * const list = [1, 6, 5] - * list.removeAll([6]) => list == [1, 5] - */ - method removeAll(elements) { - self.checkNotNull(elements, "removeAll") - elements.forEach { element => self.remove(element) } - } - - /** - * Removes those elements that meet a given condition. - * This is a side effect operation. - * Supports empty collections. - * - * Example: - * const list = [1, 6, 5] - * list.removeAllSuchThat { e => e.even() } => list == [1, 5] - */ - method removeAllSuchThat(closure) { - self.checkNotNull(closure, "removeAllSuchThat") - self.removeAll( self.filter(closure) ) - } - - /** - * Tells whether self collection has no elements - * - * Example: - * [1, 6, 5].isEmpty() => Answers false - * [].isEmpty() => Answers true - */ - method isEmpty() = self.size() == 0 - - /** - * @private - * Throws error if self collection is empty - */ - method validateNotEmpty(operation) { - if (self.isEmpty()) - throw new Exception(message = "Illegal operation '" + operation + "' on empty collection") - } - - /** - * Performs an operation on every element of self collection. - * The logic to execute is passed as a closure that takes a single parameter. - * Supports empty collections. - * @returns nothing - * - * Example: - * plants.forEach { plant => plant.takeSomeWater() } - */ - method forEach(closure) { - self.checkNotNull(closure, "forEach") - self.fold(null, { seed, element => - closure.apply(element) - seed - }) - } - - /** - * Answers whether all the elements of self collection satisfy a given - * condition. The condition is a closure argument that takes a single - * element and answers a boolean value. - * - * @returns true/false - * - * Example: - * plants.all({ plant => plant.hasFlowers() }) - * [1, 3, 5].all { number => number.odd() } => Answers true - * [].all { number => number.odd() } => Answers true - */ - method all(predicate) { - self.checkNotNull(predicate, "all") - return self.fold(true, { seed, element => if (!seed) seed else predicate.apply(element) }) - } - - /** - * Tells whether at least one element of self collection satisfies a - * given condition. The condition is a closure argument that takes a - * single element and answers a boolean value. - * @returns true/false - * - * Example: - * plants.any({ plant => plant.hasFlowers() }) - * [1, 2, 3].any { number => number.even() } ==> Answers true - * [].any { number => number.even() } ==> Answers false - */ - method any(predicate) { - self.checkNotNull(predicate, "any") - return self.fold(false, { seed, element => if (seed) seed else predicate.apply(element) }) - } - - /** - * Answers the element of self collection that satisfies a given condition. - * If more than one element satisfies the condition then it depends - * on the specific collection class which element will be returned. - * - * @returns the element that complies the condition - * @throws ElementNotFoundException if no element matched the given predicate - * - * Example: - * users.find { user => user.name() == "Cosme Fulanito" } - * #{1, 4, 5}.find { number => number.even() } => Answers 4 - * #{1, 3}.find { number => number.even() } => Throws ElementNotFoundException - * #{}.find { number => number.even() } => Throws ElementNotFoundException - */ - method find(predicate) { - self.checkNotNull(predicate, "find") - return self.findOrElse(predicate, { - throw new ElementNotFoundException(message = "there is no element that satisfies the predicate") - }) - } - - /** - * Answers the element of self collection that satisfies a given condition, - * or the given default otherwise, if no element matched the predicate. - * If more than one element satisfies the condition then it depends on the specific - * collection class which element will be returned. - * - * @returns the element that complies the condition or the default value - * - * Example: - * users.findOrDefault({ user => user.name() == "Cosme Fulanito" }, homer) - * [1, 3, 5].findOrDefault({ number => number.even() }, 0) => Answers 0 - * [].findOrDefault({ number => number.even() }, 0) => Answers 0 - */ - method findOrDefault(predicate, value) = self.findOrElse(predicate, { value }) - - /** - * Answers the element of self collection that satisfies a given condition, - * or the the result of evaluating the given continuation. - * If more than one element satisfies the condition then it depends on the - * specific collection class which element will be returned. - * - * @returns the element that complies the condition or the result - * of evaluating the continuation - * - * Example: - * users.findOrElse({ user => user.name() == "Cosme Fulanito" }, { homer }) - * [1, 3, 5].findOrElse({ number => number.even() }, { 6.max(4) }) => Answers 6 - * [].findOrElse({ number => number.even() }, { false }) => Answers false - */ - method findOrElse(predicate, continuation) native - - /** - * Counts all elements of self collection that satisfies a given condition - * The condition is a closure argument that takes a single element and - * answers a number. - * @returns an integer number - * - * Example: - * plants.count { plant => plant.hasFlowers() } - * #{1, 2, 3, 4, 5}.count { number => number.odd() } => Answers 3 - * #{}.count { number => number.odd() } => Answers 0 - */ - method count(predicate) { - self.checkNotNull(predicate, "count") - return self.fold(0, { total, element => if (predicate.apply(element)) total+1 else total }) - } - - /** - * Counts the occurrences of a given element in self collection. - * @returns an integer number - * - * Example: - * [1, 8, 4, 1].occurrencesOf(1) => Answers 2 - * [].occurrencesOf(2) => Answers 0 - */ - method occurrencesOf(element) = self.count({it => it == element}) - - /** - * Collects the sum of each value for all elements. - * This is similar to call a map {} to transform each element into a - * number object and then adding all those numbers. - * The condition is a closure argument that takes a single element and - * answers a boolean value. - * - * @returns an integer - * - * Example: - * const totalNumberOfFlowers = plants.sum{ plant => plant.numberOfFlowers() } - * [].sum { employee => employee.salary() } => Answers 0 - */ - method sum(closure) { - self.checkNotNull(closure, "sum") - return self.fold(0, { total, element => total + closure.apply(element) }) - } - - /** - * Sums all elements in the collection. - * @returns an integer - * - * Example: - * [1, 2, 3, 4, 5].sum() => Answers 15 - * [].sum() => Answers 0 - */ - method sum() = self.sum( {it => it} ) - - /** - * Answers a new collection that contains the result of transforming - * each of self collection's elements using a given closure. - * The condition is a closure argument that takes a single element - * and answers an object. - * @returns another list - * - * Example: - * const ages = users.map({ user => user.age() }) - * [1, 2, 3].map { number => number.odd() } => Answers [true, false, true] - * [].map { number => number.odd() } => Answers [] - */ - method map(closure) { - self.checkNotNull(closure, "map") - return self.fold([], { newCollection, element => - newCollection.add(closure.apply(element)) - newCollection - }) - } - - /** - * Map + flatten operation - * @see map - * @see flatten - * - * Example: - * object klaus { - * method languages() = ["c", "cobol", "pascal"] - * } - * - * object fritz { - * method languages() = ["java", "perl"] - * } - * - * - * [klaus, fritz].flatMap({ person => person.languages() }) - * => Answers ["c", "cobol", "pascal", "java", "perl"] - */ - method flatMap(closure) { - self.checkNotNull(closure, "flatMap") - return self.fold(self.newInstance(), { flattenedList, element => - flattenedList.addAll(closure.apply(element)) - flattenedList - }) - } - - /** - * Answers a new collection that contains the elements that - * meet a given condition. The condition is a closure argument that - * takes a single element and answers a boolean. - * @returns another collection (same type as self one) - * - * Example: - * const overageUsers = users.filter({ user => user.age() >= 18 }) - * #{1, 2, 3, 4, 5}.filter { number => number.even() } => Answers #{2, 4} - * #{}.filter { number => number.even() } => Answers #{} - */ - method filter(closure) { - self.checkNotNull(closure, "filter") - return self.fold(self.newInstance(), { newCollection, element => - if (closure.apply(element)) - newCollection.add(element) - newCollection - }) - } - - /** - * Answers whether this collection contains the specified element. - * - * Example: - * [].contains(3) => Answers false - * [1, 2, 3].contains(2) => Answers true - */ - method contains(element) = self.any {one => element == one } - - /** - * Flattens a collection of collections - * - * Example: - * [ [1, 2], [3], [4, 0], [] ].flatten() => Answers [1, 2, 3, 4, 0] - * - */ - method flatten() = self.flatMap { it => it } - - /** @private */ - /* - * Optimized version for long collections - * - * @see Object#toString() - */ - override method internalToSmartString(alreadyShown) { - const size = self.size() - const internalCollection = if (size > 50) "..." + size + " elements" else self.map{ e => e.toSmartString(alreadyShown) }.join(", ") - return self.toStringPrefix() + internalCollection + self.toStringSuffix() - } - - /** @private */ - method toStringPrefix() - - /** @private */ - method toStringSuffix() - - /** Converts a collection to a list */ - method asList() - - /** Converts a collection to a set (removing duplicates if necessary) - * - * Examples: - * [1, 2, 3].asSet() => Answers #{1, 2, 3} - * [].asSet() => Answers #{} - * [1, 2, 1, 1, 2].asSet() => Answers #{1, 2} - * - * #{1, 2, 3}.asSet() => Answers #{1, 2, 3} - * #{}.asSet() => Answers #{} - * - * @see Set - */ - method asSet() { - const result = #{} - result.addAll(self) - return result - } - - /** - * Answers a new collection of the same type and with the same content - * as self. Supports empty collections. - * - * @returns a new collection - * - * Example: - * const usersCopy = users.copy() - */ - method copy() { - const copy = self.newInstance() - copy.addAll(self) - return copy - } - - /** - * Answers a new collection without element that is passed by parameter. - * If the element occurs more than once in the collection, all occurrences - * will be removed. - * - * @returns a new Collection - * - * Example: - * [1, 5, 9, 2, 4].copyWithout(9) => Answers [1, 5, 2, 4] - * [1, 5, 9, 2, 9].copyWithout(9) => Answers [1, 5, 2] - * - */ - method copyWithout(elementToRemove) { - return self.filter{ element => element != elementToRemove } - } - - /** - * Answers a new collection with the added element which is received by parameter. - * - * @returns a new Collection - * - * Example: - * [1, 5, 9, 2, 4].copyWith(9) => Answers [1, 5, 2, 4, 9] - * - */ - method copyWith(elementToAdd) { - const copy = self.copy() - copy.add(elementToAdd) - return copy - } - - /** - * Answers a new List that contains the elements of self collection - * sorted by a criteria given by a closure. The closure receives two objects - * X and Y and answers a boolean, true if X should come before Y in the - * resulting collection. Supports empty collections. - * - * @returns a new List - * - * Example: - * const usersByAge = users.sortedBy({ a, b => a.age() < b.age() }) - * const studentsByNameDesc = students.sortedBy({ a, b => a.name() > b.name() }) - * [1, 5, 9, 2, 4].sortedBy { a, b => a < b } => Answers [1, 2, 4, 5, 9] - * [1, 5, 9, 2, 4].sortedBy { a, b => a > b } => Answers [9, 5, 4, 2, 1] - * [].sortedBy { a, b => a > b } => Answers [] - * - */ - method sortedBy(closure) { - const copy = self.copy().asList() - copy.sortBy(closure) - return copy - } - - - /** - * Answers a new, empty collection of the same type as self. - * @returns a new collection - * - * Example: - * const newCollection = users.newInstance() - */ - method newInstance() - - /** - * @see subclasses implementations - */ - method anyOne() = throw new Exception(message = "Should be implemented by the subclasses") - - /** - * @see subclasses implementations - */ - method add(element) = throw new Exception(message = "Should be implemented by the subclasses") - - /** - * @see subclasses implementations - */ - method remove(element) = throw new Exception(message = "Should be implemented by the subclasses") - - /** - * @see subclasses implementations - */ - method fold(element, closure) = throw new Exception(message = "Should be implemented by the subclasses") - - /** - * @see subclasses implementations - */ - method size() = throw new Exception(message = "Should be implemented by the subclasses") - - /** - * Removes all of the elements from this set. This is a side effect operation. - * - * @see subclasses implementations - */ - method clear() - - /** - * Answers the concatenated string representation of the elements in the given set. - * You can pass an optional character as an element separator (default is ",") - */ - method join(separator) - - /** - * Answers the concatenated string representation of the elements in the given set - * with default element separator (",") - */ - method join() - -} - -/** - * - * A collection that contains no duplicate elements. - * It models the mathematical set abstraction. - * A Set guarantees no order of elements. - * - * @author jfernandes - * @since 1.3 - */ -class Set inherits Collection { - - /** @private */ - override method newInstance() = #{} - - /** @private */ - override method toStringPrefix() = "#{" - - /** @private */ - override method toStringSuffix() = "}" - - /** - * Converts this set to a list. - * - * Examples - * #{1, 2, 3}.asList() => Answers [1, 2, 3] - * #{}.asList() => Answers [] - * - * @see List - */ - override method asList() { - const result = [] - result.addAll(self) - return result - } - - /** - * Answers any element of a non-empty collection - * - * Examples - * #{1, 2, 3}.anyOne() => Answers 1, for example - * #{}.anyOne() => Throws error, set must not be empty - * - */ - override method anyOne() native - - /** - * Answers a new Set with the elements of both self and another collection. - * - * Examples - * #{1, 2}.union(#{5, 2}) => #{1, 2, 5} - * #{}.union(#{3}) => #{3} - * - * @returns a Set - */ - method union(another) = self + another - - /** - * Answers a new Set with the elements of self that exist in another collection - * - * Examples - * #{1, 2}.intersection(#{5, 2}) => #{2} - * #{}.intersection(#{3}) => #{} - * - * @returns a Set - */ - method intersection(another) = - self.filter({it => another.contains(it)}) - - /** - * Answers a new Set with the elements of self that don't exist in another collection - * - * Examples - * #{1, 2}.difference(#{5, 2}) => #{1} - * #{3}.difference(#{}) => #{3} - * - * @returns a Set - */ - method difference(another) = - self.filter({it => !another.contains(it)}) - - /** - * Reduce a collection to a certain value, beginning with a seed or initial value. - * - * Examples - * #{1, 9, 3, 8}.fold(0, {acum, each => acum + each}) - * => Answers 21, the sum of all elements - * - * #{}.fold(0, {acum, each => acum + each}) - * => Answers 0, the seed. - * - * var numbers = #{3, 2, 9, 1, 7} - * numbers.fold(numbers.anyOne(), { acum, number => acum.max(number) }) - * => Answers 9, the maximum of all elements - * - */ - override method fold(initialValue, closure) native - - /** - * @see Collection#filter(closure) - */ - override method filter(closure) native - - - /** - * @see Collection#max() - */ - override method max() native - - /** - * Tries to find an element in a collection (based on a closure) or - * applies a continuation closure. - * - * Examples: - * #{1, 9, 3, 8}.findOrElse({ n => n.even() }, { 100 }) => Answers 8 - * #{1, 5, 3, 7}.findOrElse({ n => n.even() }, { 100 }) => Answers 100 - */ - override method findOrElse(predicate, continuation) native - - /** - * Adds the specified element to this set if it is not already present. - * - * Example: - * const set = #{} - * set.add(3) => set = #{3} - * set.add(2) => set = #{2, 3} - * set.add(2) => set = #{2, 3}, second add produces no effect - */ - override method add(element) native - - /** - * Removes the specified element from this set if it is present. - * - * Example: - * const set = #{2, 3} - * set.remove(3) => set = #{2} - * set.remove(4) => set = #{2}, remove operation produces no effect - */ - override method remove(element) native - - /** Answers the number of elements in this set (its cardinality). - * - * Example: - * #{2, 3}.size() => Answers 2 - * #{}.size() => Answers 0 - */ - override method size() native - - /** - * Removes all of the elements from this set. This is a side effect operation. - * - * Example: - * const set = #{2, 3} - * set.clear() => set = #{} - */ - override method clear() native - - /** - * Answers the concatenated string representation of the elements in the given set. - * You can pass an optional character as an element separator (default is ",") - * - * Examples: - * #{1, 5, 3, 7}.join(":") => Answers "1:5:3:7" - * #{"you","will","love","wollok"}.join(" ") => Answers "love will wollok you" - * #{}.join(",") => Answers "" - */ - override method join(separator) native - - /** - * Answers the concatenated string representation of the elements in the given set - * with default element separator (",") - * - * Example: - * #{"you","will","love","wollok"}.join() => Answers "love,will,wollok,you" - */ - override method join() native - - /** - * - * @see List#contains(other) - */ - override method contains(other) native - - /** - * Two sets are equals if they have the same elements - * - * Examples: - * #{}.equals(#{}) => Answers true - * #{1, 2}.equals(#{2, 1}) => Answers true - * #{3, 2}.equals(#{2, 1}) => Answers false - */ - override method equals(other) native - - /** - * - * Set equality operator as defined by equals - * - * #{1, 2} == #{2, 1} => Answers true - * #{} == #{} => Answers true - * - * @see Object#== - */ - override method ==(other) native - -} - -/** - * - * An ordered collection (also known as a sequence). - * You iterate the list the same order elements are inserted. - * The user can access elements by their integer index (position in the list). - * A List can contain duplicate elements. - * - * @author jfernandes - * @since 1.3 - */ -class List inherits Collection { - - /** - * Answers the element at the specified position in this non-empty list. - * - * The first char value of the sequence is at index 0, - * the next at index 1, and so on, as for array indexing. - * Index must be a positive and integer value. - * - * Examples: - * [].get(0) => Throws error, list must not be empty - * [1].get(-1) => Throws error, index must be 0 or positive - * [1, 2, 3].get(3) => Throws error, index exceeds list size - * [5, 2, 7].get(0) => Answers 5 - */ - method get(index) native - - /** Creates a new list */ - override method newInstance() = [] - - /** - * Answers any element of a non-empty collection. - * - * Examples - * #[1, 2, 3].anyOne() => Answers 3, for example - * #[].anyOne() => Throws error, list must not be empty - */ - override method anyOne() { - self.validateNotEmpty("anyOne") - return self.get(0.randomUpTo(self.size())) - } - - /** - * Answers first element of the non-empty list - * - * @returns first element - * - * Example: - * [1, 2, 3, 4].first() => Answers 1 - * [].first() => Throws error, list must not be empty - */ - method first() = self.head() - - /** - * Synonym for first method - */ - method head() = self.get(0) - - /** - * Answers the last element of the non-empty list. - * - * @returns last element - * - * Examples: - * [1, 2, 3, 4].last() => Answers 4 - * [].last() => Throws error, list must not be empty - */ - method last() = self.get(self.size() - 1) - - /** @private */ - override method toStringPrefix() = "[" - - /** @private */ - override method toStringSuffix() = "]" - - /** - * Converts this collection to a list. No effect on Lists. - * - * @see List - */ - override method asList() = self - - /** - * Answers a view of the portion of this list between the specified start index - * and the end of the list. Remember first element is position 0, - * second is position 1, and so on. - * If toIndex exceeds length of list, no error is thrown. - * - * Example: - * [1, 5, 3, 2, 7, 9].subList(2) => Answers [3, 2, 7, 9] - * [1, 5, 3, 2, 7, 9].subList(4) => Answers [7, 9] - * [].subList(1) => Answers [] - */ - method subList(start) { - if (self.isEmpty()) return [] - if (start >= self.size()) return [] - return self.subList(start, self.size() - 1) - } - - /** - * Answers a view of the portion of this list between the specified fromIndex - * and toIndex, both inclusive. Remember first element is position 0, - * second is position 1, and so on. - * If toIndex exceeds length of list, no error is thrown. - * - * Example: - * [1, 5, 3, 2, 7, 9].subList(2, 3) => Answers [3, 2] - * [1, 5, 3, 2, 7, 9].subList(4, 6) => Answers [7, 9] - * [].subList(1, 2) => Answers [] - */ - method subList(start, end) { - self.checkNotNull(start, "subList") - self.checkNotNull(end, "subList") - if (self.isEmpty() || start >= self.size()) - return self.newInstance() - - const newList = self.newInstance() - const _start = start.coerceToInteger().limitBetween(0, self.size() - 1) - const _end = end.coerceToInteger().limitBetween(0, self.size() - 1) - (_start.._end).forEach { i => newList.add(self.get(i)) } - return newList - } - - /** - * - * Sorts elements of a list by a specific closure. - * Order of elements is modified (produces effect). - * - * Examples: - * const list = [2, 9, 3] - * list.sortBy { el1, el2 => el1 > el2 } - * list.get(0) => Answers 9 - * - * @see List#sortedBy - */ - method sortBy(closure) native - - /** - * Takes first n elements of a list. - * - * Examples: - * [1,9,2,3].take(5) ==> Answers [1, 9, 2, 3] - * [1,9,2,3].take(2) ==> Answers [1, 9] - * [1,9,2,3].take(-2) ==> Answers [] - * [].take(2) ==> Answers [] - */ - method take(n) { - self.checkNotNull(n, "take") - return if (n <= 0) self.newInstance() else self.subList(0, n - 1) - } - - /** - * Answers a new list dropping first n elements of a list. - * This operation has no side effect. - * - * Examples: - * [1, 9, 2, 3].drop(3) ==> Answers [3] - * [1, 9, 2, 3].drop(1) ==> Answers [9, 2, 3] - * [1, 9, 2, 3].drop(-2) ==> Answers [1, 9, 2, 3] - * [].drop(2) ==> Answers [] - */ - method drop(n) { - self.checkNotNull(n, "drop") - return if (n >= self.size()) self.newInstance() else self.subList(n, self.size() - 1) - } - - /** - * Answers a new list reversing the elements, - * so that first element becomes last element of the new list and so on. - * This operation has no side effect. - * - * Example: - * [1, 9, 2, 3].reverse() ==> Answers [3, 2, 9, 1] - * [1, 2].reverse() ==> Answers [2, 1] - * [].reverse() ==> Answers [] - * - */ - method reverse() = self.subList(self.size() - 1, 0) - - /** - * @see Collection#filter(closure) - */ - override method filter(closure) native - - /** - * @see Collection#contains(obj) - */ - override method contains(obj) native - - /** - * @see Collection#max() - */ - override method max() native - - /** - * Reduce a collection to a certain value, beginning with a seed or initial value - * - * Examples - * #{1, 9, 3, 8}.fold(0, {acum, each => acum + each}) - * => Answers 21, the sum of all elements - * - * [].fold(0, {acum, each => acum + each}) - * => Answers 0, the seed. - * - * var numbers = #{3, 2, 9, 1, 7} - * numbers.fold(numbers.anyOne(), { acum, number => acum.max(number) }) - * => Answers 9, the maximum of all elements - * - */ - override method fold(initialValue, closure) native - - /** - * Finds the first element matching the boolean closure, - * or evaluates the continuation block closure if no element is found - * - * Examples: - * [1, 9, 3, 8].findOrElse({ n => n.even() }, { 100 }) => Answers 8 - * [1, 5, 3, 7].findOrElse({ n => n.even() }, { 100 }) => Answers 100 - */ - override method findOrElse(predicate, continuation) native - - /** - * Adds the specified element as last one - * - * Example: - * const list = [] - * list.add(3) => list = [3] - * list.add(2) => list = [3, 2] - * list.add(2) => list = [3, 2, 2] - */ - override method add(element) native - - /** - * Removes an element in this list, if it is present. - * - * Example: - * const list = [2, 3] - * list.remove(3) => list = [2] - * list.remove(4) => list = [2], remove operation produces no effect - */ - override method remove(element) native - - /** - * Answers the number of elements - * - * Example: - * [2, 3].size() => Answers 2 - * [].size() => Answers 0 - */ - override method size() native - - /** - * Removes all of the mappings from this Dictionary. - * This is a side effect operation. - * - * Example: - * const list = [2, 3] - * list.clear() => list = [] - */ - override method clear() native - - /** - * Answers the concatenated string representation of the elements in the given set. - * You can pass an optional character as an element separator (default is ",") - * - * Examples: - * [1, 5, 3, 7].join(":") => Answers "1:5:3:7" - * ["you","will","love","wollok"].join(" ") => Answers "you will love wollok" - */ - override method join(separator) native - - /** - * - * Answers the concatenated string representation of the elements in the given set, - * using default element separator (",") - * - * Examples: - * ["you","will","love","wollok"].join() => Answers "you,will,love,wollok" - */ - override method join() native - - /** - * @see == message - */ - override method equals(other) native - - /** - * A list is == another list if all elements are equal (defined by == message) - * - * - * Examples: - * [] == [] => Answers true - * [1, 2] == [2, 1] => Answers false - * [1, 2] == [1, 2] => Answers true - */ - override method ==(other) native - - /** - * Answers the list without duplicate elements. Preserves order of elements. - * - * [1, 3, 1, 5, 1, 3, 2, 5].withoutDuplicates() => Answers [1, 3, 5, 2] - * [].withoutDuplicates() => Answers [] - */ - method withoutDuplicates() native - -} - -/** - * Represents a set of key -> values - * - */ -class Dictionary { - - /** - * Adds or updates a value based on a key. - * If key is not present, a new value is added. - * If key is present, value is updated. - * This is a side effect operation. - * - * Example: - * const phones = new Dictionary() - * phones.put("4004-4004", rolo) - * => phones == a Dictionary ["4004-4004" -> rolo] - */ - method put(_key, _value) native - - /** - * Answers the value to which the specified key is mapped, - * or null if this Dictionary contains no mapping for the key. - * - * Example, assuming phones is the dictionary created in put example: - * phones.basicGet("4004-4004") => Answers rolo - * phones.basicGet("4004-4005") => Answers null - */ - method basicGet(_key) native - - /** - * Answers the value to which the specified key is mapped, - * or evaluates a non-parameter closure otherwise. - * - * Example, assuming phones is the dictionary created in put example: - * phones.getOrElse("4004-4004", { 0 }) => Answers rolo - * phones.getOrElse("4004-4005", { 0 }) => Answers 0 - */ - method getOrElse(_key, _closure) { - const value = self.basicGet(_key) - if (value == null) - return _closure.apply() - else - return value - } - - /** - * Answers the value to which the specified key is mapped. - * If this Dictionary contains no mapping for the key, an error is thrown. - * - * Example, assuming phones is the dictionary created in put example: - * phones.get("4004-4004") => Answers rolo - * phones.get("4004-4005") => Throws ElementNotFoundException - */ - method get(_key) = self.getOrElse(_key,{ => throw new ElementNotFoundException(message = "there is no element associated with key " + _key) }) - - /** - * Answers the number of key-value mappings in this Dictionary. - * - * Example, assuming phones is the dictionary created in put example: - * phones.size() => Answers 1 - * new Dictionary().size() => Answers 0 - */ - method size() = self.values().size() - - /** - * Answers whether the dictionary has no elements - * - * Example, assuming phones is the dictionary created in put example: - * phones.isEmpty() => Answers false - * new Dictionary().isEmpty() => Answers true - */ - method isEmpty() = self.size() == 0 - - /** - * Answers whether this Dictionary contains a mapping for the specified key. - * - * Example, assuming phones is the dictionary created in put example: - * phones.containsKey("4004-4004") => Answers true - * phones.containsKey("4004-4005") => Answers false - * new Dictionary().containsKey(1) => Answers false - */ - method containsKey(_key) = self.keys().contains(_key) - - /** - * Answers whether if this Dictionary maps one or more keys to the specified value. - * - * Example: - * const numbers = new Dictionary() - * numbers.put("one", 1) - * numbers.put("two", 2) - * numbers.containsValue(2) => Answers true - * numbers.containsValue(5) => Answers false - * new Dictionary().containsValue(3) => Answers false - */ - method containsValue(_value) = self.values().contains(_value) - - /** - * Removes the mapping for a key from this Dictionary if it is present. - * If key is not present nothing happens. - * This is a side effect operation. - * - * Example: - * const numbers = new Dictionary() - * numbers.put("one", 1) - * numbers.put("two", 2) - * numbers.remove("one") => numbers is a dictionary ("two" -> 2) - * numbers.remove("three") => nothing happens - */ - method remove(_key) native - - /** - * Answers a list of the keys contained in this Dictionary. - * - * Example: - * const numbers = new Dictionary() - * numbers.put("one", 1) - * numbers.put("two", 2) - * numbers.keys() => ["one", "two"] - */ - method keys() native - - /** - * Answers a list of the values contained in this Dictionary. - * - * Example: - * const numbers = new Dictionary() - * numbers.put("one", 1) - * numbers.put("two", 2) - * numbers.values() => [1, 2] - */ - method values() native - - /** - * Performs the given action for each entry in this Dictionary - * until all entries have been processed or the action throws an exception. - * - * Expected closure with two parameters: the first associated with key and - * second with value. - * - * Example: - * mapaTelefonos.forEach({ k, v => result += k.size() + v.size() }) - * - */ - method forEach(closure) native - - /** - * Removes all of the mappings from this Dictionary. - * This is a side effect operation. - * - * Example: - * const numbers = new Dictionary() - * numbers.put("one", 1) - * numbers.put("two", 2) - * numbers.clear() => phones == empty dictionary - */ - method clear() native - - /** - * String representation of a Dictionary - * - * Example: - * const numbers = new Dictionary() - * numbers.put("one", 1) - * numbers.put("two", 2) - * => Answers a Dictionary ["one" -> 1, "two" -> 2] - */ - override method toString() { - var result = "a Dictionary [" - self.forEach { key, value => result = result + (key.printString() + " -> " + value.printString() + ", ") } - if (self.size() > 0) result = result.substring(0, result.length() - 2) - return result + "]" - } - - /** - * Two dictionaries are equal if they have the same keys and values - */ - override method equals(other) { - self.checkNotNull(other, "equals") - return self.keys() == other.keys() && self.values() == other.values() - } - -} - -/** - * - * In Wollok we have numbers as an immutable representation. You can customize - * how many decimals you want to work with, and printing strategies. So - * number two could be printed as "2", "2,00000", "2,000", etc. - * - * Coercing strategy for numbers can be - * 1) rounding up: 2,3258 using 3 decimals will result in 2,326 - * 2) rounding down or truncation: 2,3258 using 3 decimals will - * result in 2,325 - * 3) not allowed: 2,3258 using 3 decimals will throw an exception - * since decimals exceeds maximum allowed - * - * @author jfernandes - * @author dodain (unification between Double and Integer in a single Number class) - * - * @since 1.3 - * @noInstantiate - */ -class Number { - - /** @private */ - override method simplifiedToSmartString(){ return self.stringValue() } - - /** @private */ - override method internalToSmartString(alreadyShown) { return self.stringValue() } - - /** - * @private - * - * Applies coercing strategy to integer. If it is an integer, nothing happens. - * Otherwise, if it is a decimal, defined coercing algorithm is applied - * (see definition of class Number) - */ - method coerceToInteger() native - - /** - * @private - * @see coerceToInteger - * - * Applies coercing strategy to integer. And throws exception if it is negative. - */ - method coerceToPositiveInteger() native - - /** - * Two references are identical if they are the same number - */ - override method ===(other) native - - method +(other) native - method -(other) native - method *(other) native - method /(other) native - - /** - * Integer division between self and other - * - * Example: - * 8.div(3) ==> Answers 2 - * 15.div(5) ==> Answers 3 - * 8.2.div(3.3) ==> Answers 2 - */ - method div(other) { - self.checkNotNull(other, "div") - return (self / other).truncate(0) - } - - /** - * raisedTo operation - * - * Example: - * 3.2 ** 2 ==> Answers 10.24 - * 3 ** 2 ==> Answers 9 - */ - method **(other) native - - /** - * Answers remainder of division between self and other - */ - method %(other) native - - /** String representation of self number */ - override method toString() native - - /** @private */ - override method toSmartString(alreadyShown) = self.toString() - - /** - * Builds a Range between self and end - * - * Example: - * 1..4 Answers ==> a new Range object from 1 to 4 - */ - method ..(end) { - self.checkNotNull(end, "..") - return new Range(start = self, end = end) - } - - method >(other) native - method <(other) native - - method >=(other) = self > other || self == other - method <=(other) = self < other || self == other - - /** - * Answers absolute value of self - * - * Example: - * 2.abs() ==> 2 - * (-3).abs() ==> 3 (be careful with parentheses) - * 2.7.abs() ==> Answers 2.7 - * (-3.2).abs() ==> Answers 3.2 (be careful with parentheses) - */ - method abs() native - - /** - * Inverts sign of self - * - * Example: - * 3.invert() ==> Answers -3 - * (-2).invert() ==> Answers 2 (be careful with parentheses) - * 3.2.invert() ==> -3.2 - * (-2.4).invert() ==> 2.4 (be careful with parentheses) - */ - method invert() native - - /** - * Answers the greater number between two - * Example: - * 5.max(8) ==> Answers 8 - */ - method max(other) { - self.checkNotNull(other, "max") - return if (self >= other) self else other - } - - /** - * Answers the lower number between two. @see max - * Example: - * 5.min(8) ==> Answers 5 - */ - method min(other) { - self.checkNotNull(other, "min") - return if (self <= other) self else other - } - - /** - * Given self and a range of integer values, - * answers self if it is in that range - * or nearest value from self to that range - * - * Examples - * 4.limitBetween(2, 10) ==> Answers 4, because 4 is in the range - * 4.limitBetween(6, 10) ==> Answers 6, because 4 is not in range 6..10, and 6 is nearest value to 4 - * 4.limitBetween(1, 2) ==> Answers 2, because 4 is not in range 1..2, but 2 is nearest value to 4 - * - */ - method limitBetween(limitA, limitB) { - self.checkNotNull(limitA, "limitBetween") - self.checkNotNull(limitB, "limitBetween") - return - if (limitA <= limitB) - limitA.max(self).min(limitB) - else - limitB.max(self).min(limitA) - } - - /** - * Answers whether self is between min and max - * - * Example: - * 2.between(2, 3) ==> Answers true - * 6.between(4, 6) ==> Answers true - * 3.between(4, 6) ==> Answers false - */ - method between(min, max) = (self >= min) && (self <= max) - - /** Answers squareRoot of self - * - * Example: - * 9.squareRoot() => Answers 3 - */ - method squareRoot() = self ** 0.5 - - /** Answers square of self - * - * Example: - * 3.square() => Answers 9 - */ - method square() = self * self - - /** - * Answers whether self is an even number - * (divisible by 2, mathematically 2k). - * - * Self must be an integer value - */ - method even() = self % 2 == 0 - - /** - * Answers whether self is an odd number - * (not divisible by 2, mathematically 2k + 1). - * - * Self must be an integer value - */ - method odd() { - if (!self.isInteger()) return false - return !self.even() - } - - /** Answers remainder between self and other - * - * Example: - * 5.rem(3) ==> Answers 2 - * 5.5.rem(3) ==> Answers 2 - */ - method rem(other) { - self.checkNotNull(other, "rem") - return self % other - } - - /* - * Self as String value. Equivalent: toString() - */ - method stringValue() = self.toString() - - /** - * Rounds up self up to a certain amount of decimals. - * Amount of decimals must be a positive and integer value. - * - * Example: - * 1.223445.roundUp(3) ==> 1.224 - * -1.223445.roundUp(3) ==> -1.224 - * 14.6165.roundUp(3) ==> 14.617 - * 5.roundUp(3) ==> 5 - */ - method roundUp(_decimals) native - - /** - * Truncates self up to a certain amount of decimals. - * Amount of decimals must be a positive and integer value. - * - * Example: - * 1.223445.truncate(3) ==> 1.223 - * 14.6165.truncate(3) ==> 14.616 - * -14.6165.truncate(3) ==> -14.616 - * 5.truncate(3) ==> 5 - */ - method truncate(_decimals) native - - /** - * Answers a random number between self and max - */ - method randomUpTo(max) native - - /** - * Answers the next integer greater than self - * 13.224.roundUp() ==> 14 - * -13.224.roundUp() ==> -14 - * 15.942.roundUp() ==> 16 - */ - method roundUp() = self.roundUp(0) - - /** - * greater common divisor. - * Both self and "other" parameter are coerced to be integer values. - * - * Example: - * 8.gcd(12) ==> Answers 4 - * 5.gcd(10) ==> Answers 5 - */ - method gcd(other) native - - /** - * least common multiple. - * Both self and "other" parameter are coerced to be integer values. - * - * Example: - * 3.lcm(4) ==> Answers 12 - * 6.lcm(12) ==> Answers 12 - */ - method lcm(other) { - self.checkNotNull(other, "lcm") - const mcd = self.gcd(other) - return self * (other / mcd) - } - - /** - * Number of digits of self (without sign) - * - * Examples: - * 600.digits() ==> Answers 3 - * 6.00012.digits() ==> Answers 6 - * -100.digits() ==> Answers -3 - */ - method digits() { - var digits = self.toString().size() - if (self < 0) { - digits -= 1 - } - if (!self.isInteger()) { - digits -= 1 - } - return digits - } - - /** - * Tells if this number can be considered an integer number. - * - * Examples: - * 2.isInteger() ==> Answers true - * (2.0).isInteger() ==> Answers true - * (2.3).isInteger() ==> Answers false - * - * This could depend also on the rounding strategy, for example: - * (2.0001).isInteger() ==> Answers false if rounding strategy is set to 5 decimal places (default) - * (2.0001).isInteger() ==> Answers true if rounding strategy is set to 3 decimal places - */ - method isInteger() native - - /** Answers whether self is a prime number, - * like 2, 3, 5, 7, 11 ... - * Self must be an integer positive value - */ - method isPrime() { - const intValue = self.coerceToInteger() - if (intValue == 1) return false - return (2..(intValue.div(2) + 1)).any({ i => intValue % i == 0 }).negate() - } - - /** - * Executes the given action n times (n = self) - * - * Self must be a positive integer value. - * The closure must have one argument (index goes from 1 to self) - * - * Example: - * 4.times({ i => console.println(i) }) ==> Answers - * 1 - * 2 - * 3 - * 4 - */ - method times(action) { - self.checkNotNull(action, "times") - const intValue = self.coerceToInteger() - if (intValue < 0) self.error("times requires a positive integer number") - if (intValue > 0) (1..intValue).forEach(action) - } - - /** Allows users to define a positive number with 1 or +1 */ - method plus() = self -} - -/** - * Strings are constant; - * their values cannot be changed after they are created. - * - * @author jfernandes - * @noInstantiate - */ -class String { - /** Answers the number of elements */ - method length() native - - /** - * Answers the char value at the specified index. An index ranges - * from 0 to length() - 1. The first char value of the sequence is - * at index 0, the next at index 1, and so on, as for array indexing. - * Parameter index must be a positive integer value. - */ - method charAt(index) { - self.checkNotNull(index, "charAt") - if (!index.isInteger()) throw new DomainException(message = "charAt expects an integer instead of " + index) - return self.substring(index, index + 1) - } - - /** - * Concatenates the specified string to the end of this string. - * Example: - * "cares" + "s" => Answers "caress" - */ - method +(other) = self.concat(other.toString()) - - /** - * Concatenates the specified string to the end of this string. Same as +. - * Example: - * "cares".concat("s") => Answers "caress" - */ - method concat(other) native - - - /** - * Tests if this string starts with the specified prefix. - * It is case sensitive. - * - * Examples: - * "mother".startsWith("moth") ==> Answers true - * "mother".startsWith("Moth") ==> Answers false - */ - method startsWith(other) native - - /** - * Tests if this string ends with the specified suffix. - * It is case sensitive. - * @see startsWith - */ - method endsWith(other) native - - /** - * Answers the index within this string of the first occurrence - * of the specified character. - * If character is not present, Answers -1 - * - * Examples: - * "pototo".indexOf("o") ==> Answers 1 - * "unpredictable".indexOf("o") ==> Answers -1 - */ - method indexOf(other) native - - /** - * Answers the index within this string of the last - * occurrence of the specified character. - * If character is not present, Answers -1 - * - * Examples: - * "pototo".lastIndexOf("o") ==> Answers 5 - * "unpredictable".lastIndexOf("o") ==> Answers -1 - */ - method lastIndexOf(other) native - - /** - * Converts all of the characters in this String to lower case - * - * Examples: - * "Fer".toLowerCase() ==> Answers "fer" - * "".toLowerCase() ==> Answers "" - */ - method toLowerCase() native - - /** - * Converts all of the characters in this String to upper case - * - * Examples: - * "Fer".toUpperCase() ==> Answers "FER" - * "".toUpperCase() ==> Answers "" - */ - method toUpperCase() native - - /** - * Answers a string whose value is this string, - * with any leading and trailing whitespace removed. - * - * Example: - * " emptySpace ".trim() ==> "emptySpace" - */ - method trim() native - - /** - * Answers a string reversing this string, - * so that first character becomes last character of the new string and so on. - * - * Example: - * "hola".reverse() ==> "aloh" - */ - method reverse() native - - /** - * @see take - * - * Example: - * "word".takeLeft(3) ==> Answers "wor" - * "word".takeLeft(0) ==> Answers "" - * "word".takeLeft(-1) ==> Throws error - * "".takeLeft(2) ==> Answers "" - */ - method takeLeft(length) = self.take(length) - - /** - * Takes last n characters of this string. - * n must be zero-positive integer. - * - * Example: - * "word".takeRight(3) ==> Answers "ord" - * "word".takeRight(0) ==> Answers "" - * "word".takeRight(-1) ==> Throws error - * "".takeRight(2) ==> Answers "" - */ - method takeRight(_length) { - const length = _length.coerceToPositiveInteger().min(self.size()) - return self.drop(self.size() - length) - } - - method <(aString) native - method <=(aString) { - return self < aString || (self.equals(aString)) - } - method >(aString) native - method >=(aString) { - return self > aString || (self.equals(aString)) - } - - /** - * Answers whether this string contains the specified sequence of char values. - * It is a case sensitive test. - * - * Examples: - * "unusual".contains("usual") ==> Answers true - * "become".contains("CO") ==> Answers false - */ - method contains(other) native - - /** Answers whether this string has no characters */ - method isEmpty() = self.size() == 0 - - /** - * Compares this String to another String, ignoring case considerations. - * - * Example: - * "WoRD".equalsIgnoreCase("Word") ==> Answers true - */ - method equalsIgnoreCase(aString) { - self.checkNotNull(aString, "equalsIgnoreCase") - return self.toUpperCase() == aString.toUpperCase() - } - - /** - * Answers a substring of this string beginning from - * an inclusive index. Parameter index must be a positive - * integer value. - * - * Examples: - * "substitute".substring(6) ==> Answers "tute", second "t" is in position 6 - * "effect".substring(0) ==> Answers "effect", has no effect at all - */ - method substring(index) native - - /** - * Answers a substring of this string beginning - * from an inclusive index up to another inclusive index - * - * Examples: - * "walking".substring(2, 4) ==> Answers "lk" - * "walking".substring(3, 5) ==> Answers "ki" - * "walking".substring(0, 5) ==> Answers "walki" - * "walking".substring(0, 45) ==> throws an out of range exception - */ - method substring(startIndex, length) native - - /** - * Splits this string around matches of the given string. - * Answers a list of strings. - * - * Example: - * "this,could,be,a,list".split(",") - * ==> Answers ["this", "could", "be", "a", "list"] - */ - method split(expression) { - self.checkNotNull(expression, "split") - const result = [] - var me = self.toString() + expression - var first = 0 - (0..me.size() - 1).forEach { i => - if (me.charAt(i) == expression) { - result.add(me.substring(first, i)) - first = i + 1 - } - } - return result - } - - /** - * Answers a string resulting from replacing all occurrences of - * expression in this string with replacement - * - * Example: - * "stupid is what stupid does".replace("stupid", "genius") - * ==> Answers "genius is what genius does" - */ - method replace(expression, replacement) native - - /** This object (which is already a string!) is itself returned */ - override method toString() native - - /** String implementation of printString, - * simply adds quotation marks - */ - override method printString() = '"' + self.toString() + '"' - - /** @private */ - override method toSmartString(alreadyShown) native - - /** Compares this string to the specified object. - * The result is true if and only if the - * argument is not null and is a String object - * that represents the same sequence of characters as this object. - */ - override method ==(other) native - - /** A synonym for length */ - method size() = self.length() - - /** - * Takes first n characters of this string. - * n must be zero-positive integer. - * - * Examples: - * "lowercase".take(3) ==> Answers "low" - * "lowercase".take(0) ==> Answers "" - * "lowercase".take(-1) ==> Throws error - * "".take(2) ==> Answers "" - */ - method take(n) { - self.checkNotNull(n, "take") - return self.substring(0, n.min(self.size())) - } - - /** - * Answers a new string dropping - * first n characters of this string. - * n must be zero-positive integer. - * - * Examples: - * "caption".drop(4) ==> Answers "ion" - * "caption".drop(0) ==> Answers "caption" - * "caption".drop(-1) ==> Throws error - * "".drop(2) ==> Answers "" - */ - method drop(n) { - self.checkNotNull(n, "drop") - return self.substring(n.min(self.size()), self.size()) - } - - /** - * Splits this strings into several words. - * - * Examples: - * "how does words work?".words() - * ==> Answers ["how", "does", "words", "work?"] - * - * "".words() ==> Answers [] - */ - method words() = self.split(" ") - - /** - * Changes the first letter of every word to - * upper case in this string. - * - * Example: - * "javier fernandes".capitalize() ==> Answers "Javier Fernandes" - */ - method capitalize() { - const capitalizedPhrase = self.words().fold("", { words, word => words + word.take(1).toUpperCase() + word.drop(1).toLowerCase() + " " }) - return capitalizedPhrase.take(capitalizedPhrase.size() - 1) - } - -} - -/** - * Represents a Boolean value (true or false) - * - * @author jfernandes - * @noInstantiate - */ -class Boolean { - - /** - * Answers the result of applying the logical AND operator - * to the specified boolean operands self and other - */ - method and(other) native - - /** A synonym for and operation */ - method &&(other) native - - /** Answers the result of applying the logical OR operator - * to the specified boolean operands self and other - */ - method or(other) native - - /** A synonym for or operation */ - method ||(other) native - - /** Answers a String object representing this Boolean's value. */ - override method toString() native - - /** @private */ - override method toSmartString(alreadyShown) native - - /** Compares this string to the specified object. - * The result is true if and only if the - * argument is not null and represents same value - * (true or false) - */ - override method ==(other) native - - /** NOT logical operation */ - method negate() native -} - -/** - * Represents a finite arithmetic progression - * of integer numbers with optional step - * If start = 1, end = 8, Range will represent [1, 2, 3, 4, 5, 6, 7, 8] - * If start = 1, end = 8, step = 3, Range will represent [1, 4, 7] - * - * @author jfernandes - * @since 1.3 - */ -class Range { - var start - var end - var property step = null - - /** - * Instantiates a Range. - * Both start and end must be integer values. - */ - method initialize() { - start = start.truncate(0) - end = end.truncate(0) - if (step == null) { - if (start > end) { - step = -1 - } else { - step = 1 - } - } - } - - /** - * Getter for start attribute - */ - method start() = start - - /** - * Getter for end attribute - */ - method end() = end - - /** - * Setter for step attribute. - */ - method step(_step) { - self.checkNotNull(_step, "step") - step = _step.coerceToInteger() - } - - /** - * Iterates over a Range from start to end, based on step. - * - * Example: - * new Range(start = 1, end = 3).forEach { value => console.println(value) } - * => prints 1, 2, 3 - */ - method forEach(closure) native - - /** - * Answers a new collection that contains the result of - * transforming each of self collection's elements using - * a given closure. - * - * The condition is a closure argument that takes an integer - * and answers an object. - * @returns another list - * - * Example: - * (1..10).map({ n => n * 2}) ==> Answers [2, 4, 6, 8, 10, 12, 14, 16, 18, 20] - */ - method map(closure) { - self.checkNotNull(closure, "map") - const list = [] - self.forEach { element => list.add(closure.apply(element)) } - return list - } - - /** - * Map + flatten operation - * @see map - * @see flatten - * - * Example: - * (1..4).flatMap({ n => 1 .. n }) ==> Answers [1, 1, 2, 1, 2, 3, 1, 2, 3, 4] - */ - method flatMap(closure) { - self.checkNotNull(closure, "flatMap") - return self.fold([], { seed, element => - seed.addAll(closure.apply(element)) - seed - }) - } - - /** @private */ - method asList() { - return self.map({ elem => elem }) - } - - /** - * Answers whether this range contains no elements - * @see Collection#isEmpty() - */ - method isEmpty() = self.size() == 0 - - /** @see List#fold(seed, foldClosure) */ - method fold(seed, foldClosure) = self.asList().fold(seed, foldClosure) - - /** - * Answers the number of elements - * - * Examples: - * new Range(start = 0, end = 2).size() ==> Answers 3 - * new Range(start = -2, end = 2).size() ==> Answers 5 - */ - method size() { - const base = (end - start) / step - return if (base >= 0) base.truncate(0) + 1 else 0 - } - - /** @see List#any(closure) */ - method any(closure) = self.asList().any(closure) - - /** @see List#all(closure) */ - method all(closure) = self.asList().all(closure) - - /** @see List#filter(closure) */ - method filter(closure) = self.asList().filter(closure) - - /** @see List#min() */ - method min() = self.asList().min() - - /** @see List#max() */ - method max() = self.asList().max() - - /** - * Answers a random integer contained in the range - * - * Example: - * new Range(start = 1, end = 3).anyOne() ==> Answers 1 or 2 or 3 - */ - method anyOne() native - - /** - * Tests whether a number e is contained in the range - * - * Examples: - * new Range(start = 2, end = 5).contains(4) ==> Answers true - * new Range(start = 2, end = 5).contains(0) ==> Answers false - */ - method contains(element) = self.asList().contains(element) - - /** @see List#sum() */ - method sum() = self.asList().sum() - - /** - * Sums all elements that match the boolean closure - * - * Example: - * (1..9).sum({ i => if (i.even()) i else 0 }) ==> Answers 20 - */ - method sum(closure) = self.asList().sum(closure) - - /** - * Counts how many elements match the boolean closure - * - * Example: - * (1..9).count({ i => i.even() }) ==> Answers 4 (2, 4, 6 and 8 are even) - */ - method count(closure) = self.asList().count(closure) - - /** @see List#find(closure) */ - method find(closure) = self.asList().find(closure) - - /** @see List#findOrElse(predicate, continuation) */ - method findOrElse(closure, continuation) = self.asList().findOrElse(closure, continuation) - - /** @see List#findOrDefault(predicate, value) */ - method findOrDefault(predicate, value) = self.asList().findOrDefault(predicate, value) - - /** @see List#sortBy */ - method sortedBy(closure) = self.asList().sortedBy(closure) - - /** @private */ - override method internalToSmartString(alreadyShown) = start.toString() + ".." + end.toString() -} - -/** - * - * Represents an executable piece of code. You can create a closure, - * assign it to a reference, evaluate it many times, - * send it as parameter to another object, and many useful things. - * - * @author jfernandes - * @since 1.3 - * @noInstantiate - */ -class Closure { - - method initialize() native - - /** Evaluates this closure passing its parameters - * - * Example: - * { number => number + 1 }.apply(8) ==> Answers 9 // 1 parameter - * { "screw" + "driver" }.apply() ==> Answers "screwdriver" // no parameter - */ - method apply(parameters...) native - - /** Answers a string representation of this closure object */ - override method toString() native - -} - -/** Represents days of week. */ - -object monday { } -object tuesday { } -object wednesday { } -object thursday { } -object friday { } -object saturday { } -object sunday { } -const daysOfWeek = [monday, tuesday, wednesday, thursday, friday, saturday, sunday] - -/** - * - * Represents a Date (without time). A Date is immutable, once created you can not change it. - * - * @since 1.4.5 - */ -class Date { - - const property day - const property month - const property year - - /** @private */ - method initialize() native - - /** String representation of a date */ - override method toString() = self.toSmartString(false) - - /** Two dates are equals if they represent the same date */ - override method ==(_aDate) native - - /** - * Answers a copy of this Date with the specified number of days added. - * Parameter must be an integer value. - * This operation has no side effect (a new date is returned). - * - * Example: - * new Date(day = 12, month = 5, year = 2018).plusDays(1) - * ==> Answers 13/5/2018, a day forward - * - * new Date(day = 12, month = 5, year = 2018).plusDays(-1) - * ==> Answers 11/5/2018, a day back - */ - method plusDays(_days) native - - /** - * Answers a copy of this Date with the specified number of months added. - * Parameter must be an integer value. - * This operation has no side effect (a new date is returned). - * - * Example: - * new Date(day = 31, month = 1, year = 2018).plusMonths(1) - * ==> Answers 28/2/2018, a month forward - * - * new Date(day = 12, month = 5, year = 2018).plusMonths(-1) - * ==> Answers 12/4/2018, a month back - */ - method plusMonths(_months) native - - /** - * Answers a copy of this Date with the specified number of years added. - * Parameter must be an integer value. - * This operation has no side effect (a new date is returned). - * - * Example: - * new Date(day = 31, month = 1, year = 2018).plusYears(1) - * ==> Answers 31/1/2019, a year forward - * - * new Date(day = 12, month = 5, year = 2018).plusYears(-1) - * ==> Answers 12/5/2017, a year back - */ - method plusYears(_years) native - - /** - * Checks if the year is a leap year, like 2000, 2004, 2008... - * - * Example: - * new Date(day = 12, month = 5, year = 2018).isLeapYear() ==> Answers false - */ - method isLeapYear() native - - /** Answers the day of the week of the Date with an object representation. - * There is a wko (well known object) for every day of the week. - * - * Example: - * new Date(day = 24, month = 2, year = 2018).dayOfWeek() ==> Answers saturday object - */ - method dayOfWeek() = daysOfWeek.get(self.internalDayOfWeek() - 1) - - /** Answers the day of week of the Date, where - * 1 = MONDAY - * 2 = TUESDAY - * 3 = WEDNESDAY - * ... - * 7 = SUNDAY - * - * Example: - * new Date(day = 24, month = 2, year = 2018).internalDayOfWeek() ==> Answers 6 (SATURDAY) - */ - method internalDayOfWeek() native - - /** - * Answers the difference in days between two dates, assuming self is minuend and _aDate is subtrahend. - * - * Examples: - * new Date().plusDays(4) - new Date() ==> Answers 4 - * new Date() - new Date().plusDays(2) ==> Answers -2 - */ - method -(_aDate) native - - /** - * Answers a copy of this date with the specified number of days subtracted. - * This instance is immutable and unaffected by this method call. - * Parameter must be an integer value. - * This operation has no side effect (a new date is returned). - * - * Examples: - * new Date(day = 1, month = 1, year = 2009).minusDays(1) - * ==> Answers 31/12/2008, a day back - * - * new Date(day = 1, month = 1, year = 2009).minusDays(-1) - * ==> Answers 2/1/2009, a day forward - */ - method minusDays(_days) native - - /** - * Answers a copy of this date with the specified number of months subtracted. - * Parameter must be an integer value. - * This operation has no side effect (a new date is returned). - * - * Examples: - * new Date(day = 1, month = 1, year = 2009).minusMonths(1) - * ==> Answers 1/12/2008, a month back - * - * new Date(day = 1, month = 1, year = 2009).minusMonths(-1) - * ==> Answers 1/2/2009, a month forward - */ - method minusMonths(_months) native - - /** - * Answers a copy of this date with the specified number of years subtracted. - * Parameter must be an integer value. - * This operation has no side effect (a new date is returned). - * - * Examples: - * new Date(day = 1, month = 1, year = 2009).minusYears(1) - * ==> Answers 1/1/2008, a year back - * - * new Date(day = 1, month = 1, year = 2009).minusYears(-1) - * ==> Answers 1/1/2010, a year forward - */ - method minusYears(_years) native - - method <(_aDate) native - method >(_aDate) native - method <=(_aDate) = (self < _aDate) || (self.equals(_aDate)) - method >=(_aDate) = (self > _aDate) || (self.equals(_aDate)) - - /** - * Answers whether self is between two dates (both inclusive comparison) - * - * Example: - * new Date(day = 2, month = 4, year = 2018).between(new Date(day = 1, month = 4, year = 2018), new Date(day = 2, month = 4, year = 2018)) - * ==> Answers true - */ - method between(_startDate, _endDate) = (self >= _startDate) && (self <= _endDate) - - /** Shows nicely an internal representation of a date **/ - override method toSmartString(alreadyShown) = - self.shortDescription() - - /** - * Shows a short, internal representation of a date - * (the result varies depending on user's locale) - * - * Example: - * new Date(day = 2, month = 4, year = 2018).shortDescription() - * ==> Answers 2/4/2018 - */ - override method shortDescription() native - -} - -object io { - const eventHandlers = new Dictionary() - var eventQueue = [] - - method queueEvent(event) { - eventQueue.add(event) - } - - // TODO: removeHandler - method addHandler(event, callback) { - if (!eventHandlers.containsKey(event)) eventHandlers.put(event, []) - eventHandlers.get(event).add(callback) - } - - method flushEvents() { - const currentEvents = eventQueue.copy() - eventQueue = [] - currentEvents.forEach{ event => - eventHandlers.getOrElse(event, { [] }).forEach{ callback => callback.apply() } - } - } -} diff --git a/org.uqbar.project.wollok.lib/src/wollok/lib.wlk b/org.uqbar.project.wollok.lib/src/wollok/lib.wlk deleted file mode 100644 index 78e904a87e..0000000000 --- a/org.uqbar.project.wollok.lib/src/wollok/lib.wlk +++ /dev/null @@ -1,253 +0,0 @@ -/** - * Console is a global wollok object that implements a character-based console device - * called "standard input/output" stream - */ -object console { - - /** Prints a String with end-of-line character */ - method println(obj) native - - /** Reads a line from input stream */ - method readLine() native - - /** Reads an int character from input stream */ - method readInt() native - - /** Returns the system's representation of a new line: - * - \n in Unix systems - * - \r\n in Windows systems - */ - method newline() native -} - -/** - * Exception to handle other values expected in assert.throwsException... methods - */ -class OtherValueExpectedException inherits wollok.lang.Exception {} - -/** - * Exception to handle difference between current and expected values - * in assert.throwsException... methods - */ -class AssertionException inherits Exception { - const property expected = null - const property actual = null -} - -/** - * Assert object simplifies testing conditions - */ -object assert { - - /** - * Tests whether value is true. Otherwise throws an exception. - * - * Example: - * assert.that(7.even()) ==> throws an exception "Value was not true" - * assert.that(8.even()) ==> ok, nothing happens - */ - method that(value) { - self.checkNotNull(value, "that") - if (!value) throw new AssertionException(message = "Value was not true") - } - - /** Tests whether value is false. Otherwise throws an exception. - * @see assert#that(value) - */ - method notThat(value) { - self.checkNotNull(value, "notThat") - if (value) throw new AssertionException(message = "Value was not false") - } - - /* - * This method avoids confusion with equals definition in Object - */ - override method equals(value) { - throw new AssertionException(message = "assert.equals(expected, actual): missing second parameter") - } - - /** - * Tests whether two values are equal, based on wollok ==, != methods - * - * Examples: - * assert.equals(10, 100.div(10)) ==> ok, nothing happens - * assert.equals(10.0, 100.div(10)) ==> ok, nothing happens - * assert.equals(10.01, 100.div(10)) ==> throws an exception - */ - method equals(expected, actual) { - if (expected != actual) throw new AssertionException(message = "Expected [" + expected.printString() + "] but found [" + actual.printString() + "]") - } - - /** - * Tests whether two values are equal, based on wollok ==, != methods - * - * Examples: - * const value = 5 - * assert.notEquals(10, value * 3) ==> ok, nothing happens - * assert.notEquals(10, value) ==> throws an exception - */ - method notEquals(expected, actual) { - if (expected == actual) throw new AssertionException(message = "Expected to be different, but [" + expected.printString() + "] and [" + actual.printString() + "] match") - } - - /** - * Tests whether a block throws an exception. Otherwise an exception is thrown. - * - * Examples: - * assert.throwsException({ 7 / 0 }) - * ==> Division by zero error, it is expected, ok - * - * assert.throwsException({ "hola".length() }) - * ==> throws an exception "Block should have failed" - */ - method throwsException(block) { - self.checkNotNull(block, "throwsException") - var failed = false - try { - block.apply() - } catch e { - failed = true - } - if (!failed) throw new AssertionException(message = "Block " + block + " should have failed") - } - - /** - * Tests whether a block throws an exception and this is the same expected. - * Otherwise an exception is thrown. - * - * Examples: - * assert.throwsExceptionLike(new BusinessException("hola"), - * { => throw new BusinessException("hola") } - * => Works! Exception class and message both match. - * - * assert.throwsExceptionLike(new BusinessException("chau"), - * { => throw new BusinessException("hola") } - * => Doesn't work. Exception class matches but messages are different. - * - * assert.throwsExceptionLike(new OtherException("hola"), - * { => throw new BusinessException("hola") } - * => Doesn't work. Messages matches but they are instances of different exceptions. - */ - method throwsExceptionLike(exceptionExpected, block) { - self.checkNotNull(exceptionExpected, "throwsExceptionLike") - self.checkNotNull(block, "throwsExceptionLike") - try - { - self.throwsExceptionByComparing(block, {a => a.equals(exceptionExpected)}) - } - catch ex : OtherValueExpectedException - { - throw new AssertionException(message = "The Exception expected was " + exceptionExpected + " but got " + ex.cause()) - } - } - - /** - * Tests whether a block throws an exception and it has the error message as is expected. - * Otherwise an exception is thrown. - * - * Examples: - * assert.throwsExceptionWithMessage("hola",{ => throw new BusinessException(message = "hola") } - * => Works! Both have the same message. - * - * assert.throwsExceptionWithMessage("hola",{ => throw new OtherException(message = "hola") } - * => Works! Both have the same message. - * - * assert.throwsExceptionWithMessage("chau",{ => throw new BusinessException(message = "hola") } - * => Doesn't work. Both are instances of BusinessException but their messages differ. - */ - method throwsExceptionWithMessage(errorMessage, block) { - self.checkNotNull(errorMessage, "throwsExceptionWithMessage") - self.checkNotNull(block, "throwsExceptionWithMessage") - try - { - self.throwsExceptionByComparing(block, {a => errorMessage.equals(a.message())}) - } - catch ex : OtherValueExpectedException - { - throw new AssertionException(message = "The error message expected was " + errorMessage + " but got " + ex.cause().message()) - } - } - - /** - * Tests whether a block throws an exception and this is the same exception class expected. - * Otherwise an exception is thrown. - * - * Examples: - * assert.throwsExceptionWithType(new BusinessException("hola"),{ => throw new BusinessException("hola") } - * => Works! Both exceptions are instances of the same class. - * - * assert.throwsExceptionWithType(new BusinessException("chau"),{ => throw new BusinessException("hola") } - * => Works again! Both exceptions are instances of the same class. - * - * assert.throwsExceptionWithType(new OtherException("hola"),{ => throw new BusinessException("hola") } - * => Doesn't work. Exception classes differ although they contain the same message. - */ - method throwsExceptionWithType(exceptionExpected, block) { - self.checkNotNull(exceptionExpected, "throwsExceptionWithType") - self.checkNotNull(block, "throwsExceptionWithType") - try - { - self.throwsExceptionByComparing(block,{a => exceptionExpected.className().equals(a.className())}) - } - catch ex : OtherValueExpectedException - { - throw new AssertionException(message = "The exception expected was " + exceptionExpected.className() + " but got " + ex.cause().className()) - } - } - - /** - * Tests whether a block throws an exception and compare this exception with other block - * called comparison. Otherwise an exception is thrown. The block comparison - * receives a value (an exception thrown) that is compared in a boolean expression - * returning the result. - * - * Examples: - * assert.throwsExceptionByComparing({ => throw new BusinessException("hola"),{ex => "hola".equals(ex.message())}} - * => Works!. - * - * assert.throwsExceptionByComparing({ => throw new BusinessException("hola"),{ex => new BusinessException("lele").className().equals(ex.className())} } - * => Works again! - * - * assert.throwsExceptionByComparing({ => throw new BusinessException("hola"),{ex => "chau!".equals(ex.message())} } - * => Doesn't work. The block evaluation resolves to a false value. - */ - method throwsExceptionByComparing(block, comparison){ - self.checkNotNull(block, "throwsExceptionByComparing") - self.checkNotNull(comparison, "throwsExceptionByComparing") - var continue = false - try - { - block.apply() - continue = true - } - catch ex - { - if(comparison.apply(ex)) - self.that(true) - else - throw new OtherValueExpectedException(message = "Expected other value", cause = ex) - } - if (continue) throw new AssertionException(message = "Should have thrown an exception") - } - - /** - * Throws an exception with a custom message. - * Useful when you reach code that should not be reached. - */ - method fail(message) { - self.checkNotNull(message, "fail") - throw new AssertionException(message = message) - } - -} - -class StringPrinter { - var buffer = "" - - method println(obj) { - const objAsString = if (obj === null) "null" else obj.toString() - buffer += objAsString + console.newline() - } - - method getBuffer() = buffer -} diff --git a/org.uqbar.project.wollok.lib/src/wollok/mirror.wlk b/org.uqbar.project.wollok.lib/src/wollok/mirror.wlk deleted file mode 100644 index 08ae25802c..0000000000 --- a/org.uqbar.project.wollok.lib/src/wollok/mirror.wlk +++ /dev/null @@ -1,13 +0,0 @@ -class InstanceVariableMirror { - const target - const property name - - method value() = target.resolve(name) - - method valueToSmartString(alreadyShown) { - const value = self.value() - return if (value == null) "null" else value.toSmartString(alreadyShown) - } - - override method toString() = name + "=" + self.value() -} diff --git a/org.uqbar.project.wollok.lib/src/wollok/vm.wlk b/org.uqbar.project.wollok.lib/src/wollok/vm.wlk deleted file mode 100644 index 17b74b0af9..0000000000 --- a/org.uqbar.project.wollok.lib/src/wollok/vm.wlk +++ /dev/null @@ -1,3 +0,0 @@ -object runtime { - method isInteractive() native -} From ab983268c32fe2b350aaa5f1eef486eb2bc8720b Mon Sep 17 00:00:00 2001 From: Fernando Dodino Date: Fri, 1 Nov 2019 23:26:42 -0300 Subject: [PATCH 092/133] Adding lib .wlk files to ignored files --- .gitignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 457b6ba85f..a6b1774a9a 100644 --- a/.gitignore +++ b/.gitignore @@ -31,4 +31,4 @@ scripts/wollok-site scripts/wollok-cli # Ignoring wollok-language files -# org.uqbar.project.wollok.lib/src/wollok/*.wlk +org.uqbar.project.wollok.lib/src/wollok/*.wlk From baa485100436451d8606f0d2c1bbc7c70559ee7b Mon Sep 17 00:00:00 2001 From: Fernando Dodino Date: Fri, 1 Nov 2019 23:33:13 -0300 Subject: [PATCH 093/133] Fix install.sh call in travis script --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 3a4e27d330..07dd65d78b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -17,7 +17,7 @@ after_success: cd .. fi script: -- install.sh +- ./install.sh - cd org.uqbar.project.wollok.releng/ - export PROFILES=normalProfile - export UPDATE_SITE=none From 177abf2d402a0e335640fdeb798a8b1aec5ae6bf Mon Sep 17 00:00:00 2001 From: Fernando Dodino Date: Fri, 1 Nov 2019 23:47:18 -0300 Subject: [PATCH 094/133] Fix appveyor script & travis script --- .travis.yml | 2 +- install.bat | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 07dd65d78b..11c1ef56ad 100644 --- a/.travis.yml +++ b/.travis.yml @@ -17,7 +17,7 @@ after_success: cd .. fi script: -- ./install.sh +- "./install.sh" - cd org.uqbar.project.wollok.releng/ - export PROFILES=normalProfile - export UPDATE_SITE=none diff --git a/install.bat b/install.bat index 77e107dbff..3a3ec83a97 100644 --- a/install.bat +++ b/install.bat @@ -1,2 +1,2 @@ git submodule update --init --recursive -for %%f in (./wollok-language/src/wollok/*.wlk) do mklink %%f "../../org.uqbar.project.wollok.lib/src/wollok/%%f" +for %%f in (./wollok-language/src/wollok/*.wlk) do mklink %%f "./org.uqbar.project.wollok.lib/src/wollok/%%f" From 157a03f9202d216802718365741b6e4615f3ea75 Mon Sep 17 00:00:00 2001 From: fdodino Date: Sat, 2 Nov 2019 03:19:28 -0300 Subject: [PATCH 095/133] Appveyor script fixed --- install.bat | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/install.bat b/install.bat index 3a3ec83a97..2677d524c4 100644 --- a/install.bat +++ b/install.bat @@ -1,2 +1,4 @@ git submodule update --init --recursive -for %%f in (./wollok-language/src/wollok/*.wlk) do mklink %%f "./org.uqbar.project.wollok.lib/src/wollok/%%f" +cd wollok-language/src/wollok +for %%f in (./*.wlk) do mklink /h "../../../org.uqbar.project.wollok.lib/src/wollok/%%f" %%f +cd ../../.. From 864ec444e1b72dd204a935b3e3b3041a950e37e7 Mon Sep 17 00:00:00 2001 From: Gonzalo Gras Cantou Date: Sat, 2 Nov 2019 17:29:52 -0300 Subject: [PATCH 096/133] Change the param (WMethodContainer) of validator to WName, because Suite is a MethodContainer --- ...plicatedReferenceFromImportsInDescribeName.wtest.xt | 8 ++++++++ .../project/wollok/validation/WollokDslValidator.xtend | 10 ++-------- 2 files changed, 10 insertions(+), 8 deletions(-) create mode 100644 org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/xpect/DuplicatedReferenceFromImportsInDescribeName.wtest.xt diff --git a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/xpect/DuplicatedReferenceFromImportsInDescribeName.wtest.xt b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/xpect/DuplicatedReferenceFromImportsInDescribeName.wtest.xt new file mode 100644 index 0000000000..a5c16861f5 --- /dev/null +++ b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/xpect/DuplicatedReferenceFromImportsInDescribeName.wtest.xt @@ -0,0 +1,8 @@ +/* XPECT_SETUP org.uqbar.project.wollok.tests.xpect.WollokXPectTest END_SETUP */ + +import libForImports.apu + +// XPECT warnings --> "Describe should not be empty" at ""apu"" +describe "apu" { + +} \ No newline at end of file diff --git a/org.uqbar.project.wollok/src/org/uqbar/project/wollok/validation/WollokDslValidator.xtend b/org.uqbar.project.wollok/src/org/uqbar/project/wollok/validation/WollokDslValidator.xtend index 64a9944c31..ec6450bcf7 100644 --- a/org.uqbar.project.wollok/src/org/uqbar/project/wollok/validation/WollokDslValidator.xtend +++ b/org.uqbar.project.wollok/src/org/uqbar/project/wollok/validation/WollokDslValidator.xtend @@ -40,6 +40,7 @@ import org.uqbar.project.wollok.wollokDsl.WMemberFeatureCall import org.uqbar.project.wollok.wollokDsl.WMethodContainer import org.uqbar.project.wollok.wollokDsl.WMethodDeclaration import org.uqbar.project.wollok.wollokDsl.WMixin +import org.uqbar.project.wollok.wollokDsl.WNamed import org.uqbar.project.wollok.wollokDsl.WNamedObject import org.uqbar.project.wollok.wollokDsl.WObjectLiteral import org.uqbar.project.wollok.wollokDsl.WPackage @@ -650,14 +651,7 @@ class WollokDslValidator extends AbstractConfigurableDslValidator { @Check @DefaultSeverity(WARN) @CheckGroup(WollokCheckGroup.POTENTIAL_PROGRAMMING_PROBLEM) - def duplicatedMethodContainerFromImports(WMethodContainer it) { - duplicatedReferenceFromImports(it) - } - - @Check - @DefaultSeverity(WARN) - @CheckGroup(WollokCheckGroup.POTENTIAL_PROGRAMMING_PROBLEM) - def duplicatedAtributteFromImports(WVariable it) { + def duplicatedMethodContainerFromImports(WNamed it) { duplicatedReferenceFromImports(it) } From d190b592e4b1d0b831442919c971c0c3adb1ae0e Mon Sep 17 00:00:00 2001 From: PalumboN Date: Sat, 2 Nov 2019 18:25:21 -0300 Subject: [PATCH 097/133] Testing inherited properties for TS --- .../wollok/tests/typesystem/xpect/inheritParameters.wlk.xt | 3 +++ 1 file changed, 3 insertions(+) diff --git a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/typesystem/xpect/inheritParameters.wlk.xt b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/typesystem/xpect/inheritParameters.wlk.xt index 7a2df0827a..9511fddcf5 100644 --- a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/typesystem/xpect/inheritParameters.wlk.xt +++ b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/typesystem/xpect/inheritParameters.wlk.xt @@ -10,6 +10,9 @@ class Ave { class Golondrina inherits Ave { + // XPECT methodType at energy --> () => Number + method energy() = self.energia() + method vola() { energia -= 10 } From d5a52e9e0cfec9e7c07975098e109aa90ed05dc7 Mon Sep 17 00:00:00 2001 From: PalumboN Date: Sat, 2 Nov 2019 18:33:05 -0300 Subject: [PATCH 098/133] findProperty uses allVariableDeclarations --- .../uqbar/project/wollok/model/WMethodContainerExtensions.xtend | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/org.uqbar.project.wollok/src/org/uqbar/project/wollok/model/WMethodContainerExtensions.xtend b/org.uqbar.project.wollok/src/org/uqbar/project/wollok/model/WMethodContainerExtensions.xtend index eb6bab52a6..c7517ae141 100644 --- a/org.uqbar.project.wollok/src/org/uqbar/project/wollok/model/WMethodContainerExtensions.xtend +++ b/org.uqbar.project.wollok/src/org/uqbar/project/wollok/model/WMethodContainerExtensions.xtend @@ -614,7 +614,7 @@ class WMethodContainerExtensions extends WollokModelExtensions { def static dispatch boolean isWritableVarRef(EObject it) { false } def static findProperty(WMethodContainer it, String propertyName, int parametersSize) { - variableDeclarations.findFirst [ variable | variable.matchesProperty(propertyName, parametersSize) ] + allVariableDeclarations.findFirst [ variable | variable.matchesProperty(propertyName, parametersSize) ] } def static dispatch boolean matchesProperty(EObject it, String propertyName, int parametersSize) { false } From e6a9a667b31378da2fcfab65788f20a1b9c17ec7 Mon Sep 17 00:00:00 2001 From: alete89 Date: Sat, 2 Nov 2019 21:51:33 -0300 Subject: [PATCH 099/133] feat: adds warning messages MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Nicolás Viotti --- .../src/org/uqbar/project/wollok/messages.properties | 1 + .../src/org/uqbar/project/wollok/messages_es.properties | 2 ++ 2 files changed, 3 insertions(+) diff --git a/org.uqbar.project.wollok/src/org/uqbar/project/wollok/messages.properties b/org.uqbar.project.wollok/src/org/uqbar/project/wollok/messages.properties index 84f9df6c71..c2c3b4b4dc 100644 --- a/org.uqbar.project.wollok/src/org/uqbar/project/wollok/messages.properties +++ b/org.uqbar.project.wollok/src/org/uqbar/project/wollok/messages.properties @@ -131,6 +131,7 @@ WollokDslValidator_SUPER_ONLY_OVERRIDING_METHOD = Super can only be used in an o WollokDslValidator_INITIALIZATION_VALUE_FOR_VARIABLE_NEVER_USED = Initial value for this variable is never used WollokDslValidator_VARIABLE_NEVER_USED = Unused variable +WollokDslValidator_VARIABLE_SHOULD_BE_CONST = Variable should be const WollokDslValidator_PARAMETER_NEVER_USED = Unused parameter WollokDslValidator_WARN_VARIABLE_NEVER_ASSIGNED = Variable could be never assigned diff --git a/org.uqbar.project.wollok/src/org/uqbar/project/wollok/messages_es.properties b/org.uqbar.project.wollok/src/org/uqbar/project/wollok/messages_es.properties index 8bf3a1ead0..6450b605d7 100644 --- a/org.uqbar.project.wollok/src/org/uqbar/project/wollok/messages_es.properties +++ b/org.uqbar.project.wollok/src/org/uqbar/project/wollok/messages_es.properties @@ -129,6 +129,8 @@ WollokDslValidator_SUPER_ONLY_OVERRIDING_METHOD = S\u00F3lo se puede utilizar 's WollokDslValidator_INITIALIZATION_VALUE_FOR_VARIABLE_NEVER_USED = El valor inicial definido nunca es utilizado WollokDslValidator_VARIABLE_NEVER_USED = Esta variable nunca se utiliza +WollokDslValidator_VARIABLE_SHOULD_BE_CONST = Esta variable debería ser una constante + WollokDslValidator_PARAMETER_NEVER_USED = Este par\u00E1metro nunca se utiliza WollokDslValidator_WARN_VARIABLE_NEVER_ASSIGNED = Esta variable podr\u00EDa no asignarse nunca From 05b845fe1123e887af88e4784fc07e6c2b6d5256 Mon Sep 17 00:00:00 2001 From: alete89 Date: Sat, 2 Nov 2019 21:51:55 -0300 Subject: [PATCH 100/133] test: adds test cases MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Nicolás Viotti --- .../tests/xpect/VariableShouldBeConst.wlk.xt | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/xpect/VariableShouldBeConst.wlk.xt diff --git a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/xpect/VariableShouldBeConst.wlk.xt b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/xpect/VariableShouldBeConst.wlk.xt new file mode 100644 index 0000000000..885aee883b --- /dev/null +++ b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/xpect/VariableShouldBeConst.wlk.xt @@ -0,0 +1,23 @@ +/* XPECT_SETUP org.uqbar.project.wollok.tests.xpect.WollokXPectTest END_SETUP */ + +object variableShouldBeConst { + var variable = 123 + // XPECT warnings --> "Variable should be const" at "constante" + var constante = 321 + + method doSomething() { + variable = 666 + return variable + constante + } +} + + +object variableWithSingleAssignmentNotRaisesWarningIfProperty { + var variable = 123 + var property constante = 321 + + method doSomething() { + variable = 666 + return variable + constante + } +} \ No newline at end of file From 0247c11bea986c98834d78ba3887dd8f09c5e5e9 Mon Sep 17 00:00:00 2001 From: alete89 Date: Sun, 3 Nov 2019 00:36:36 -0300 Subject: [PATCH 101/133] feat: added validation for variabless used as constants MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Nicolás Viotti --- .../src/org/uqbar/project/wollok/Messages.java | 1 + .../wollok/validation/WollokDslValidator.xtend | 11 +++++++++++ 2 files changed, 12 insertions(+) diff --git a/org.uqbar.project.wollok/src/org/uqbar/project/wollok/Messages.java b/org.uqbar.project.wollok/src/org/uqbar/project/wollok/Messages.java index 24ac678dfd..e19b251685 100644 --- a/org.uqbar.project.wollok/src/org/uqbar/project/wollok/Messages.java +++ b/org.uqbar.project.wollok/src/org/uqbar/project/wollok/Messages.java @@ -73,6 +73,7 @@ public class Messages extends NLS { public static String WollokDslValidator_GLOBAL_VARIABLE_NOT_ALLOWED; public static String WollokDslValidator_MISSING_ASSIGNMENTS_IN_CONSTRUCTOR_CALL; public static String WollokDslValidator_VARIABLE_NEVER_USED; + public static String WollokDslValidator_VARIABLE_SHOULD_BE_CONST; public static String WollokDslValidator_PARAMETER_NEVER_USED; public static String WollokDslValidator_SUPER_ONLY_IN_CLASSES; public static String WollokDslValidator_SUPER_ONLY_OVERRIDING_METHOD; diff --git a/org.uqbar.project.wollok/src/org/uqbar/project/wollok/validation/WollokDslValidator.xtend b/org.uqbar.project.wollok/src/org/uqbar/project/wollok/validation/WollokDslValidator.xtend index 64a9944c31..22aa16c0f7 100644 --- a/org.uqbar.project.wollok/src/org/uqbar/project/wollok/validation/WollokDslValidator.xtend +++ b/org.uqbar.project.wollok/src/org/uqbar/project/wollok/validation/WollokDslValidator.xtend @@ -152,6 +152,7 @@ class WollokDslValidator extends AbstractConfigurableDslValidator { // WARNING KEYS public static val WARNING_UNUSED_VARIABLE = "WARNING_UNUSED_VARIABLE" public static val WARNING_UNUSED_PARAMETER = "WARNING_UNUSED_PARAMETER" + public static val WARNING_VARIABLE_SHOULD_BE_CONST = "WARNING_VARIABLE_SHOULD_BE_CONST" def validatorExtensions() { if (wollokValidatorExtensions !== null) @@ -891,6 +892,16 @@ class WollokDslValidator extends AbstractConfigurableDslValidator { checkUnusedParameters(it.parameters) } + @Check + @CheckGroup(WollokCheckGroup.POTENTIAL_PROGRAMMING_PROBLEM) + def variableSingleAssignmentShouldBeConst(WVariableDeclaration it) { + val assignments = variable.assignments + if (assignments.length === 1 && writeable && !isProperty) { + warning(WollokDslValidator_VARIABLE_SHOULD_BE_CONST, it, WVARIABLE_DECLARATION__VARIABLE, WARNING_VARIABLE_SHOULD_BE_CONST) + } + } + + def void checkUnusedParameters(List parameters) { parameters.forEach [ parameter | if (!parameter.isUsed) { From 31d3fe94096a1b4c087faf69fc557479a9b4f557 Mon Sep 17 00:00:00 2001 From: Fernando Dodino Date: Mon, 4 Nov 2019 20:33:06 -0300 Subject: [PATCH 102/133] Moving monstersInc to wollok-language --- .../examples/MonstersIncTestCase.xtend | 20 ---- .../libraries/WollokLibExtensionsTest.xtend | 18 +-- ...ExceptionPropagationInNativeTestCase.xtend | 1 - wollok-language | 2 +- .../examples/monstersinc/actividades.wlk | 21 ---- .../examples/monstersinc/asistentes.wlk | 16 --- .../examples/monstersinc/asustables.wlk | 35 ------ .../examples/monstersinc/asustadores.wlk | 50 -------- .../wollok/examples/monstersinc/modelo.wlk | 57 --------- .../examples/monstersinc/monstersInc.wtest | 113 ------------------ .../examples/monstersinc/workspace.wpgm | 69 ----------- 11 files changed, 11 insertions(+), 391 deletions(-) delete mode 100644 org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/examples/MonstersIncTestCase.xtend delete mode 100644 wollok-tests/src/wollok/examples/monstersinc/actividades.wlk delete mode 100644 wollok-tests/src/wollok/examples/monstersinc/asistentes.wlk delete mode 100644 wollok-tests/src/wollok/examples/monstersinc/asustables.wlk delete mode 100644 wollok-tests/src/wollok/examples/monstersinc/asustadores.wlk delete mode 100644 wollok-tests/src/wollok/examples/monstersinc/modelo.wlk delete mode 100644 wollok-tests/src/wollok/examples/monstersinc/monstersInc.wtest delete mode 100644 wollok-tests/src/wollok/examples/monstersinc/workspace.wpgm diff --git a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/examples/MonstersIncTestCase.xtend b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/examples/MonstersIncTestCase.xtend deleted file mode 100644 index 634020aa18..0000000000 --- a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/examples/MonstersIncTestCase.xtend +++ /dev/null @@ -1,20 +0,0 @@ -package org.uqbar.project.wollok.tests.interpreter.examples - -import java.io.File -import org.junit.Test -import org.uqbar.project.wollok.tests.interpreter.AbstractWollokInterpreterTestCase - -/** - * Executes the monsters inc example - * - * @author jfernandes - */ -class MonstersIncTestCase extends AbstractWollokInterpreterTestCase { - val path = EXAMPLES_PROJECT_PATH + "/src/wollok/examples/monstersinc/monstersInc.wtest" - - @Test - def void run() { - new File(path).interpretPropagatingErrors - } - -} \ No newline at end of file diff --git a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/libraries/WollokLibExtensionsTest.xtend b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/libraries/WollokLibExtensionsTest.xtend index 5f9bf5cce8..d31ef5b30e 100644 --- a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/libraries/WollokLibExtensionsTest.xtend +++ b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/libraries/WollokLibExtensionsTest.xtend @@ -7,29 +7,31 @@ import static org.junit.Assert.assertFalse import static org.junit.Assert.assertTrue class WollokLibExtensionsTest { - + public static class IsCoreLibTest{ @Test() - def void whenPassALangFqnResponseTrue() { + def void libFQNisACoreLibrary() { val String exceptionFqn = "wollok.lang.Exception" assertTrue(WollokLibExtensions.isCoreLib(exceptionFqn)) } - + @Test() - def void whenPassALibFqnResponseTrue() { + def void langFQNisACoreLibrary() { val String libFqn = "wollok.lib" assertTrue(WollokLibExtensions.isCoreLib(libFqn)) } - + @Test() - def void whenPassANullResponseFalse() { + def void nullIsNotACoreLibrary() { assertFalse(WollokLibExtensions.isCoreLib(null)) } + @Test() - def void whenPassAFqnIsNotCoreLibResponseFalse() { + def void customClassIsNotACoreLibrary() { val String randomFqn = "randomfqn.aClass" assertFalse(WollokLibExtensions.isCoreLib(randomFqn)) } + } - + } diff --git a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/natives/ExceptionPropagationInNativeTestCase.xtend b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/natives/ExceptionPropagationInNativeTestCase.xtend index 6c11a9c7bb..6845e5c01f 100644 --- a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/natives/ExceptionPropagationInNativeTestCase.xtend +++ b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/natives/ExceptionPropagationInNativeTestCase.xtend @@ -6,7 +6,6 @@ import org.junit.Test /** * @author jfernandes */ -// TODO: this could have more tests, with more complex cases :P class ExceptionPropagationInNativeTestCase extends AbstractWollokInterpreterTestCase { @Test diff --git a/wollok-language b/wollok-language index e5ed9f1a41..bd8ac9c440 160000 --- a/wollok-language +++ b/wollok-language @@ -1 +1 @@ -Subproject commit e5ed9f1a416c9030258976a1527f790d8bbd6426 +Subproject commit bd8ac9c440f6cc5e425edad712ae4f3bfdc18e68 diff --git a/wollok-tests/src/wollok/examples/monstersinc/actividades.wlk b/wollok-tests/src/wollok/examples/monstersinc/actividades.wlk deleted file mode 100644 index a2aff9cc80..0000000000 --- a/wollok-tests/src/wollok/examples/monstersinc/actividades.wlk +++ /dev/null @@ -1,21 +0,0 @@ -class Actividad { - method calcularMejora() -} - -class EstudiarMateria inherits Actividad { - var materia - var puntos = 0 - - constructor(m, p) { - materia = m - puntos = p - } - - override method calcularMejora() = puntos -} - -class EjercitarEnSimulador inherits Actividad { - var horas = 0 - constructor(h) { horas = h } - override method calcularMejora() = 10 * horas -} \ No newline at end of file diff --git a/wollok-tests/src/wollok/examples/monstersinc/asistentes.wlk b/wollok-tests/src/wollok/examples/monstersinc/asistentes.wlk deleted file mode 100644 index e6303efce1..0000000000 --- a/wollok-tests/src/wollok/examples/monstersinc/asistentes.wlk +++ /dev/null @@ -1,16 +0,0 @@ - -class AsistenteNormal { - method calcularEnergia(energia) = energia -} - -class AsistenteIneficiente { - var reduce = 0 - constructor(cuanto) { reduce = cuanto } - method calcularEnergia(energia) = energia - reduce -} - -class AsistenteSupereficiente { - var factor - constructor(f) { factor = f } - method calcularEnergia(energia) = energia * (1 + factor) -} \ No newline at end of file diff --git a/wollok-tests/src/wollok/examples/monstersinc/asustables.wlk b/wollok-tests/src/wollok/examples/monstersinc/asustables.wlk deleted file mode 100644 index bba2277cbc..0000000000 --- a/wollok-tests/src/wollok/examples/monstersinc/asustables.wlk +++ /dev/null @@ -1,35 +0,0 @@ -class Asustable { - method teVaAAsustar(asustador) -} - -class Ninio inherits Asustable { - var edad = 0 - - constructor(e) { edad = e } - method setEdad(e) { edad = e } - method getEdad() = edad - override method teVaAAsustar(asustador) { - return asustador.asustar(self) - } -} - -class Piyamada inherits Asustable { - var ninios = [] - method agregarNinio(n) { ninios.add(n) } - override method teVaAAsustar(asustador) { - return ninios.fold(0, {a, n=> - a + asustador.asustar(n) - }) - } -} - -class Adulto inherits Asustable { -} - -class Adolescente inherits Asustable { - override method teVaAAsustar(asustador) { - var factor = 0.10 - asustador.reducirMotivacion(factor) - return 0 - } -} diff --git a/wollok-tests/src/wollok/examples/monstersinc/asustadores.wlk b/wollok-tests/src/wollok/examples/monstersinc/asustadores.wlk deleted file mode 100644 index 369ac9e7c4..0000000000 --- a/wollok-tests/src/wollok/examples/monstersinc/asustadores.wlk +++ /dev/null @@ -1,50 +0,0 @@ -class Asustador { - var edad = 0 - var nivelMotivacion = 100 - - constructor(e) { edad = e } - method getEdad() = edad - method setEdad(e) { edad = e } - - method getNivelMotivacion() = nivelMotivacion - - method entrarAPuerta(puerta) { - return puerta.entra(self) - } - - method asustar(ninio) { - const a = self.getPorcentaje() - return a * self.puntosDeTerror() / ninio.getEdad() - } - method getPorcentaje() { - return nivelMotivacion / 100 - } - - method puntosDeTerror() - - method reducirMotivacion(cuantoPorciento) { - nivelMotivacion -= cuantoPorciento * nivelMotivacion - } -} - -class AsustadorNato inherits Asustador { - var puntosTerrorInnatos - constructor(e, p) = super(e) { - puntosTerrorInnatos = p - } - override method puntosDeTerror() { - return puntosTerrorInnatos * self.getEdad() - } -} - -class AsustadorPerseverante inherits Asustador { - var puntosDeTerror = 0 - - constructor(e) = super(e) - - method mejora(actividad) { - puntosDeTerror += actividad.calcularMejora() - } - override method puntosDeTerror() = puntosDeTerror -} - diff --git a/wollok-tests/src/wollok/examples/monstersinc/modelo.wlk b/wollok-tests/src/wollok/examples/monstersinc/modelo.wlk deleted file mode 100644 index 65c0f3b090..0000000000 --- a/wollok-tests/src/wollok/examples/monstersinc/modelo.wlk +++ /dev/null @@ -1,57 +0,0 @@ -object monstersInc { - var equipos = [] - var puertas = [] - - method getEquipos() = equipos - method agregarPuerta(p) { puertas.add(p) } - method agregarEquipo(e) { equipos.add(e) } - method removerEquipo(e) { equipos.remove(e) } - method getEnergiaTotalGenerada() { - return equipos.sum({e=> e.getEnergiaGenerada()}) - } - - method cualquierPuerta() { - if (puertas.size() > 1) return puertas.any() - else if (puertas.size() == 1) return puertas.get(0) // Walk around issue #199 - else throw "No hay puertas" - } - - method diaLaboral() { - equipos.forEach({e=> e.visitar(self.cualquierPuerta())}) - } - - method equipoMasAsustador() { - return equipos.max({e=> e.getEnergiaGenerada()}) - } -} - -class Puerta { - var contenido - constructor(c) { contenido = c } - - method entra(asustador) { - return contenido.teVaAAsustar(asustador) - } -} - -class Equipo { - var asustador - var asistente - var energiaGenerada = 0 - - constructor(asus, asis) { - asustador = asus - asistente = asis - } - - method setAsistente(a) { - asistente = a - } - method visitar(puerta) { - const energiaPorAsustar = energiaGenerada + asustador.entrarAPuerta(puerta) - energiaGenerada = asistente.calcularEnergia(energiaPorAsustar) - } - method getEnergiaGenerada() = energiaGenerada - method nuevoDia() { energiaGenerada = 0 } -} - diff --git a/wollok-tests/src/wollok/examples/monstersinc/monstersInc.wtest b/wollok-tests/src/wollok/examples/monstersinc/monstersInc.wtest deleted file mode 100644 index 180717156d..0000000000 --- a/wollok-tests/src/wollok/examples/monstersinc/monstersInc.wtest +++ /dev/null @@ -1,113 +0,0 @@ -import asustadores.* - -import modelo.Puerta -import modelo.Equipo -import modelo.monstersInc - -import asustables.Ninio -import asustables.Piyamada -import asustables.Adolescente - -import asistentes.* -import actividades.* - -test "Asustador Nato con Ninio genera energia" { - // ----------------------------------------- - // punto 1 - const sullivan = new AsustadorNato(25, 200) - const puertaConNinio4 = new Puerta(new Ninio(4)) - assert.equals(1250, sullivan.entrarAPuerta(puertaConNinio4)) -} - -test "Asustador Perseverante mejora estudiando y ejercitando" { - // ----------------------------------------- - // punto 2 - const mike = new AsustadorPerseverante(0) - mike.mejora(new EstudiarMateria("Sustos 2", 50)) - mike.mejora(new EjercitarEnSimulador(2)) - - assert.equals(70, mike.puntosDeTerror()) -} - -test "Mike asusta una piyamada" { - const piyamada = new Piyamada() - piyamada.agregarNinio(new Ninio(2)) - piyamada.agregarNinio(new Ninio(3)) - piyamada.agregarNinio(new Ninio(4)) - - const puertaConPiyamada = new Puerta(piyamada) - - const mike = new AsustadorPerseverante(0) - mike.mejora(new EstudiarMateria("Sustos 2", 50)) - mike.mejora(new EjercitarEnSimulador(2)) - const energiaMike = mike.entrarAPuerta(puertaConPiyamada) - - assert.equals(75.83333, energiaMike) // 70/2 + 70/3 + 70/4 = 75 -} - -test "Asustar a un adolescente disminuye la motivacion" { - const puertaConNinio4 = new Puerta(new Ninio(4)) - const mike = new AsustadorPerseverante(0) - mike.mejora(new EstudiarMateria("Sustos 2", 50)) - mike.mejora(new EjercitarEnSimulador(2)) - const sullivan = new AsustadorNato(25, 200) - - // ----------------------------------------- - // punto 3 - const equipo = new Equipo(sullivan, new AsistenteNormal()) - equipo.visitar(new Puerta(new Adolescente())) - - assert.equals(90.0, sullivan.getNivelMotivacion()) - assert.that(0 == equipo.getEnergiaGenerada()) - - // ----------------------------------------- - // punto 4 - monstersInc.agregarEquipo(equipo) - monstersInc.agregarPuerta(puertaConNinio4) - - //monstersInc.agregarPuerta(puertaConPiyamada) - // TODO: deberia agregar otros - monstersInc.diaLaboral() - assert.equals(1125.0, equipo.getEnergiaGenerada()) - - // ----------------------------------------- - // punto 5 - assert.that(equipo == monstersInc.equipoMasAsustador()) - - const equipoCapo = object { - method getEnergiaGenerada() = 90000.0 - } - monstersInc.agregarEquipo(equipoCapo) - - assert.equals(equipoCapo, monstersInc.equipoMasAsustador()) - - monstersInc.removerEquipo(equipoCapo) - - // ----------------------------------------- - // punto 6 - assert.that(1125.0 == monstersInc.getEnergiaTotalGenerada()) - monstersInc.diaLaboral() - assert.that(2250.0 == monstersInc.getEnergiaTotalGenerada()) - - // ----------------------------------------- - // punto 7 - equipo.setAsistente(new AsistenteNormal()) - - equipo.nuevoDia() - equipo.visitar(puertaConNinio4) - assert.equals(1125.0, equipo.getEnergiaGenerada()) - - // ineficiente - equipo.setAsistente(new AsistenteIneficiente(100)) - - equipo.nuevoDia() - equipo.visitar(puertaConNinio4) - assert.equals(1025.0, equipo.getEnergiaGenerada()) - - // supereficiente - equipo.setAsistente(new AsistenteSupereficiente(1.25)) - - equipo.nuevoDia() - equipo.visitar(puertaConNinio4) - assert.equals(2531.25, equipo.getEnergiaGenerada()) -} diff --git a/wollok-tests/src/wollok/examples/monstersinc/workspace.wpgm b/wollok-tests/src/wollok/examples/monstersinc/workspace.wpgm deleted file mode 100644 index 07eb692462..0000000000 --- a/wollok-tests/src/wollok/examples/monstersinc/workspace.wpgm +++ /dev/null @@ -1,69 +0,0 @@ -import asustadores.* - -import modelo.Puerta -import modelo.Equipo -import modelo.monstersInc - -import asustables.Ninio -import asustables.Piyamada -import asustables.Adolescente - -import asistentes.* -import actividades.* - -/** - * - */ -program monstersInc { - - // 1) - const sullivan = new AsustadorNato(25, 200) - const puertaConNinio4 = new Puerta(new Ninio(4)) - - assert.equals(1250, sullivan.entrarAPuerta(puertaConNinio4)) - - // 2) - const mike = new AsustadorPerseverante(20) - mike.mejora(new EstudiarMateria("Sustos 2", 50)) - mike.mejora(new EjercitarEnSimulador(2)) - - assert.equals(70, mike.puntosDeTerror()) - - const piyamada = new Piyamada() - piyamada.agregarNinio(new Ninio(2)) - piyamada.agregarNinio(new Ninio(3)) - piyamada.agregarNinio(new Ninio(4)) - - const puertaConPiyamada = new Puerta(piyamada) - const energiaMike = mike.entrarAPuerta(puertaConPiyamada) - - assert.equals(75.83333, energiaMike) // 70/2 + 70/3 + 70/4 = 75 - - - // 3) - const equipo = new Equipo(sullivan, new AsistenteNormal()) - equipo.visitar(new Puerta(new Adolescente())) - - assert.equals(90.0, sullivan.getNivelMotivacion()) - assert.that(0 == equipo.getEnergiaGenerada()) - - - // 4) - - const emp = monstersInc - emp.agregarEquipo(equipo) - emp.agregarPuerta(puertaConNinio4) - emp.diaLaboral() - assert.equals(1125.0, equipo.getEnergiaGenerada()) - - // 5) - assert.that(equipo == emp.equipoMasAsustador()) - - const equipoCapo = object { - method getEnergiaGenerada() { return 90000.0 } - } - emp.agregarEquipo(equipoCapo) - - assert.that(equipoCapo == emp.equipoMasAsustador()) - -} \ No newline at end of file From 1130c3d48e1dc757a57db37d7d36880b4a0d51b5 Mon Sep 17 00:00:00 2001 From: Fernando Dodino Date: Sat, 9 Nov 2019 00:10:25 -0300 Subject: [PATCH 103/133] Moving import test cases to wollok-language --- .../interpreter/imports/ImportsTest.xtend | 371 +----------------- wollok-language | 2 +- 2 files changed, 3 insertions(+), 370 deletions(-) diff --git a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/imports/ImportsTest.xtend b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/imports/ImportsTest.xtend index 5204c5b86f..7e1c83cd47 100644 --- a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/imports/ImportsTest.xtend +++ b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/imports/ImportsTest.xtend @@ -13,227 +13,6 @@ import org.junit.Ignore */ class ImportsTest extends AbstractWollokInterpreterTestCase { - @Test - def void testImportObject() { - #['aves' -> ''' - object pepita { - method getNombre() = "pepita" - } - - ''', - 'entrenador' -> ''' - import aves.* - - object mostaza { - method entrenar() { - return pepita.getNombre() - } - } - ''', - 'programa' -> ''' - import entrenador.* - program a { - const nombre = mostaza.entrenar() - - assert.equals('pepita', nombre) - } - ''' - ].interpretAsFilesPropagatingErrors - } - - @Test - def void testImportObjectMultiLevel() { - #['model/aves' -> ''' - object pepita { - method getNombre() = "pepita" - } - - ''', - 'model/entrenador' -> ''' - import model.aves.* - - object mostaza { - method entrenar() { - return pepita.getNombre() - } - } - ''', - 'pgm/programa' -> ''' - import model.entrenador.* - program a { - const nombre = mostaza.entrenar() - - assert.equals('pepita', nombre) - } - ''' - ].interpretAsFilesPropagatingErrors - } - - @Test - def void testImportObjectMultiLevelRelative() { - #['model/aves' -> ''' - object pepita { - method getNombre() = "pepita" - } - - ''', - 'model/entrenador' -> ''' - import aves.* - - object mostaza { - method entrenar() { - return pepita.getNombre() - } - } - ''', - 'pgm/programa' -> ''' - import model.entrenador.* - program a { - const nombre = mostaza.entrenar() - - assert.equals('pepita', nombre) - } - ''' - ].interpretAsFilesPropagatingErrors - } - - - @Test - def void testImportObjectInSrc() { - #['src/model/aves' -> ''' - object pepita { - method getNombre() = "pepita" - } - - ''', - 'src/model/entrenador' -> ''' - import aves.* - - object mostaza { - method entrenar() { - return pepita.getNombre() - } - } - ''', - 'src/pgm/programa' -> ''' - import model.entrenador.* - program a { - const nombre = mostaza.entrenar() - - assert.equals('pepita', nombre) - } - ''' - ].interpretAsFilesPropagatingErrors - } - - - @Test - def void testMultipleObjectsImports() { - #['aves' -> ''' - object pepita { - method getNombre() = "pepita" - } - object pepona { - method getNombre() = "pepona" - } - ''', - 'entrenador' -> ''' - import aves.pepita - import aves.pepona - - object mostaza { - method entrenar() { - return [pepita, pepona].map{p => p.getNombre()}.join(',') - } - } - ''', - 'programa' -> ''' - import entrenador.mostaza - program a { - const nombre = mostaza.entrenar() - - assert.equals('pepita,pepona', nombre) - } - ''' - ].interpretAsFilesPropagatingErrors - } - - @Test - def void testMultipleObjectsImportsWithWildcard() { - #['aves' -> ''' - object pepita { - method getNombre() = "pepita" - } - object pepona { - method getNombre() = "pepona" - } - ''', - 'programa' -> ''' - import aves.* - program a { - assert.equals('pepita,pepona', [pepita, pepona].map{p => p.getNombre()}.join()) - } - ''' - ].interpretAsFilesPropagatingErrors - } - - @Test - def void testImportWithPackage() { - #['aves' -> ''' - package nadadoras { - object patitoFeo { - method getNombre() = "Patito Feo" - } - } - - object pepona { - method getNombre() = "pepona" - } - ''', - 'programa' -> ''' - import aves.nadadoras.patitoFeo - import aves.pepona - program a { - assert.equals('Patito Feo', patitoFeo.getNombre()) - assert.equals('pepona', pepona.getNombre()) - } - ''' - ].interpretAsFilesPropagatingErrors - } - - @Test - def void importWithPackages(){ - #["model/armas" -> ''' - package xxx { - - class Arma { - method disparar() { - } - } - } - - class Guerrero { - - } - ''', - "test/test" -> ''' - import model.* - import model.armas.* - - test "test con arma" { - const arma = new armas.xxx.Arma() - assert.that(true) - } - - test "thor pelea duro" { - const thor = new armas.Guerrero() - const thor2 = new Guerrero() - assert.that(true) - } - ''' - ].interpretAsFilesPropagatingErrors - } - @Test @Ignore // No puedo armar una gramática válida que funcione. def void mustUseFullNameToReferenceObjectFromSameFileButDifferentPackage() { @@ -254,140 +33,8 @@ class ImportsTest extends AbstractWollokInterpreterTestCase { } @Test - def void implicitObjectsAndClassesFromWollokSDKFromWithinAPackage() { - ''' - package aves { - object pepita { - method volar() { - console.println('abc') - const p = new Pair(x = 1, y = 2) - } - } - } - '''.interpretPropagatingErrors - } - - @Test - def void implicitClassesFromRootObjects() { - ''' - object pepita { - method volar() { - const p = new Pair(x = 1, y = 2) - } - } - '''.interpretPropagatingErrors - } - - @Test - def void implicitObjectsFromRootObjects() { - ''' - object pepita { - method volar() { - console.println("sarasa") - } - } - '''.interpretPropagatingErrors - } - - @Test - def void testUseFullClassNameWithFile() { - #['aves' -> ''' - class Golondrina { - } - ''', - 'programa' -> ''' - program a { - assert.that(new aves.Golondrina() != null) - } - ''' - ].interpretPropagatingErrors - } - - @Test - def void testImportClassNoPackage() { - #['aves' -> ''' - class Golondrina { - } - ''', - 'programa' -> ''' - import aves.Golondrina - program a { - assert.that(new Golondrina() != null) - } - ''' - ].interpretAsFilesPropagatingErrors - } - - @Test - def void testImportClassWithWildcardNoPackage() { - #['aves' -> ''' - class Golondrina { - } - ''', - 'programa' -> ''' - import aves.* - program a { - assert.that(new Golondrina() != null) - } - ''' - ].interpretAsFilesPropagatingErrors - } - - @Test - def void testImportClassWithPackage() { - #['aves' -> ''' - package nadadoras { - class Pato { - } - } - ''', - 'programa' -> ''' - import aves.nadadoras.Pato - program a { - assert.that(new Pato() != null) - } - ''' - ].interpretAsFilesPropagatingErrors - } - - @Test - def void testImportClassWithPackageAndWildcards() { - #['aves' -> ''' - package nadadoras { - class Pato { - } - } - ''', - 'programa' -> ''' - import aves.nadadoras.* - program a { - assert.that(new Pato() != null) - } - ''' - ].interpretAsFilesPropagatingErrors - } - - @Test - def void testClassReferencesBetweenPackages() { - #['aves' -> ''' - package nadadoras { - class Pato { - } - } - package voladoras { - class Gorrion { - method crearUnPato() { - new nadadoras.Pato() - } - } - } - ''' - ].interpretAsFilesPropagatingErrors - } - - @Test - def void testRefereceByFQNWithoutImport() { - + def void testReferenceByFQNWithoutImport() { + // Este test no lo pude llevar a wollok-cli => no reconoce a b.Golondrina sin el import #[ 'b' -> ''' class Golondrina { @@ -404,18 +51,4 @@ class ImportsTest extends AbstractWollokInterpreterTestCase { ].interpretAsFilesPropagatingErrors } - @Test - def void missingImportIssue1399() { - ''' - describe "Cuenta" { - test "depositar monto" { - assert.throwsExceptionWithMessage("Couldn't resolve reference to Cuenta", { - const cuenta = new Cuenta() - cuenta.depositar() - } - } - } - '''.interpretPropagatingErrorsWithoutStaticChecks - } - } diff --git a/wollok-language b/wollok-language index bd8ac9c440..f5dd0765ce 160000 --- a/wollok-language +++ b/wollok-language @@ -1 +1 @@ -Subproject commit bd8ac9c440f6cc5e425edad712ae4f3bfdc18e68 +Subproject commit f5dd0765ce011cc23d2bc6cbb09100884bf322bd From 69e2646873f31d9fb317148e30c31d9ffcdf6154 Mon Sep 17 00:00:00 2001 From: nicovio Date: Sat, 9 Nov 2019 03:05:27 -0300 Subject: [PATCH 104/133] show warning when var is assigned only in its definition or not at all --- .../project/wollok/validation/WollokDslValidator.xtend | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/org.uqbar.project.wollok/src/org/uqbar/project/wollok/validation/WollokDslValidator.xtend b/org.uqbar.project.wollok/src/org/uqbar/project/wollok/validation/WollokDslValidator.xtend index 22aa16c0f7..72d08d661c 100644 --- a/org.uqbar.project.wollok/src/org/uqbar/project/wollok/validation/WollokDslValidator.xtend +++ b/org.uqbar.project.wollok/src/org/uqbar/project/wollok/validation/WollokDslValidator.xtend @@ -896,12 +896,12 @@ class WollokDslValidator extends AbstractConfigurableDslValidator { @CheckGroup(WollokCheckGroup.POTENTIAL_PROGRAMMING_PROBLEM) def variableSingleAssignmentShouldBeConst(WVariableDeclaration it) { val assignments = variable.assignments - if (assignments.length === 1 && writeable && !isProperty) { - warning(WollokDslValidator_VARIABLE_SHOULD_BE_CONST, it, WVARIABLE_DECLARATION__VARIABLE, WARNING_VARIABLE_SHOULD_BE_CONST) + if (writeable && !isProperty && (assignments.isEmpty || (assignments.size === 1 && right !== null))) { + warning(WollokDslValidator_VARIABLE_SHOULD_BE_CONST, it, WVARIABLE_DECLARATION__VARIABLE, + WARNING_VARIABLE_SHOULD_BE_CONST) } } - def void checkUnusedParameters(List parameters) { parameters.forEach [ parameter | if (!parameter.isUsed) { From e5fcb2619b62886a6d09fedd1c098b0c189d3668 Mon Sep 17 00:00:00 2001 From: nicovio Date: Sat, 9 Nov 2019 03:29:35 -0300 Subject: [PATCH 105/133] don't show warning if var has no assignments --- .../uqbar/project/wollok/validation/WollokDslValidator.xtend | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/org.uqbar.project.wollok/src/org/uqbar/project/wollok/validation/WollokDslValidator.xtend b/org.uqbar.project.wollok/src/org/uqbar/project/wollok/validation/WollokDslValidator.xtend index 72d08d661c..8ab2da59c8 100644 --- a/org.uqbar.project.wollok/src/org/uqbar/project/wollok/validation/WollokDslValidator.xtend +++ b/org.uqbar.project.wollok/src/org/uqbar/project/wollok/validation/WollokDslValidator.xtend @@ -896,7 +896,7 @@ class WollokDslValidator extends AbstractConfigurableDslValidator { @CheckGroup(WollokCheckGroup.POTENTIAL_PROGRAMMING_PROBLEM) def variableSingleAssignmentShouldBeConst(WVariableDeclaration it) { val assignments = variable.assignments - if (writeable && !isProperty && (assignments.isEmpty || (assignments.size === 1 && right !== null))) { + if (writeable && !isProperty && assignments.size === 1 && right !== null) { warning(WollokDslValidator_VARIABLE_SHOULD_BE_CONST, it, WVARIABLE_DECLARATION__VARIABLE, WARNING_VARIABLE_SHOULD_BE_CONST) } From 18b4d6b2b1562c82926b6255a0f9736418e64543 Mon Sep 17 00:00:00 2001 From: nicovio Date: Sat, 9 Nov 2019 04:01:38 -0300 Subject: [PATCH 106/133] dont' show warning if it is a global variable --- .../uqbar/project/wollok/validation/WollokDslValidator.xtend | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/org.uqbar.project.wollok/src/org/uqbar/project/wollok/validation/WollokDslValidator.xtend b/org.uqbar.project.wollok/src/org/uqbar/project/wollok/validation/WollokDslValidator.xtend index 8ab2da59c8..22c356315d 100644 --- a/org.uqbar.project.wollok/src/org/uqbar/project/wollok/validation/WollokDslValidator.xtend +++ b/org.uqbar.project.wollok/src/org/uqbar/project/wollok/validation/WollokDslValidator.xtend @@ -896,7 +896,7 @@ class WollokDslValidator extends AbstractConfigurableDslValidator { @CheckGroup(WollokCheckGroup.POTENTIAL_PROGRAMMING_PROBLEM) def variableSingleAssignmentShouldBeConst(WVariableDeclaration it) { val assignments = variable.assignments - if (writeable && !isProperty && assignments.size === 1 && right !== null) { + if (writeable && !isProperty && assignments.size === 1 && right !== null && !isGlobal) { warning(WollokDslValidator_VARIABLE_SHOULD_BE_CONST, it, WVARIABLE_DECLARATION__VARIABLE, WARNING_VARIABLE_SHOULD_BE_CONST) } From ed08734413767e8d14bfac53bc2902287cc7ae70 Mon Sep 17 00:00:00 2001 From: nicovio Date: Sat, 9 Nov 2019 05:08:19 -0300 Subject: [PATCH 107/133] fix tests that failed due to the new validation --- .../tests/parser/MethodParserTest.xtend | 6 +- .../tests/proposals/GetterBodyProposal.wlk.xt | 2 +- .../quickfix/ConstructorsQuickFixTest.xtend | 64 +++++++++---------- ...MethodOnSelfDoesntExistsQuickFixTest.xtend | 4 +- .../quickfix/OverridingQuickFixTest.xtend | 12 ++-- .../quickfix/PropertiesQuickFixTest.xtend | 6 +- .../wollok/tests/quickfix/QuickFixTest.xtend | 16 ++--- .../xpect/PolimorfismoLoboFeroz.wlk.xt | 14 ++-- .../tests/typesystem/xpect/booleans.wlk.xt | 4 +- .../tests/typesystem/xpect/closures.wpgm.xt | 2 +- .../typesystem/xpect/constructors.wlk.xt | 2 +- .../typesystem/xpect/instantiation.wpgm.xt | 8 +-- .../tests/typesystem/xpect/methods.wpgm.xt | 2 +- .../typesystem/xpect/objectLiterals.wlk.xt | 10 +-- .../xpect/AssignmentToTheSameVariable.wlk.xt | 4 +- .../wollok/tests/xpect/BadIfUsage.wlk.xt | 4 +- .../xpect/CheckInitialValueAssignment.wlk.xt | 4 +- .../tests/xpect/CheckMessagesToWKO.wlk.xt | 4 +- .../tests/xpect/CheckOnNameStyles.wlk.xt | 6 +- .../tests/xpect/ConstructorDelegation.wlk.xt | 4 +- .../xpect/DuplicatedInstanceVariable.wtest.xt | 4 +- ...plicatedInstanceVariableInHierarchy.wlk.xt | 8 +-- .../DuplicatedReferenceFromImports.wlk.xt | 4 +- .../DuplicatedReferenceFromImports.wtest.xt | 2 +- .../EffectlessExpressionsInSequence.wlk.xt | 2 +- .../tests/xpect/GetterMethodReturn.wlk.xt | 4 +- .../wollok/tests/xpect/NamedParameters.wlk.xt | 10 +-- .../tests/xpect/PropertiesDefinition.wpgm.xt | 2 +- .../tests/xpect/PropertiesDefinition.wtest.xt | 2 +- .../wollok/tests/xpect/SuperInvocation.wlk.xt | 2 +- .../wollok/tests/xpect/UnusedVariable.wlk.xt | 4 +- .../tests/xpect/UnusedVariable.wtest.xt | 2 +- .../tests/xpect/VoidMethodsUsage.wlk.xt | 2 +- .../xpect/cannotUseSelfInAProgram.wpgm.xt | 6 +- .../xpect/dontUseLocalVarOnlyToReturn.wlk.xt | 10 +-- ...achableCodeInBooleanBinaryOperation.wlk.xt | 2 +- 36 files changed, 123 insertions(+), 121 deletions(-) diff --git a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/parser/MethodParserTest.xtend b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/parser/MethodParserTest.xtend index a1b6940de1..148bce512a 100644 --- a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/parser/MethodParserTest.xtend +++ b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/parser/MethodParserTest.xtend @@ -55,7 +55,7 @@ class MethodParserTest extends AbstractWollokInterpreterTestCase { def void FourEqualsOperatorErrorMessage() { ''' object pepita { - var energia = 0 + const energia = 0 method estaCansada() { return energia ==== 0 } @@ -67,7 +67,7 @@ class MethodParserTest extends AbstractWollokInterpreterTestCase { def void FourNotEqualsOperatorErrorMessage() { ''' object pepita { - var energia = 0 + const energia = 0 method estaConEnergia() { return energia !=== 0 } @@ -79,7 +79,7 @@ class MethodParserTest extends AbstractWollokInterpreterTestCase { def void UnexistentMessageErrorMessage() { ''' object pepita { - var energia = 0 + const energia = 0 method estaCansada() { return energia.esSiempreIgualA(0) } diff --git a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/proposals/GetterBodyProposal.wlk.xt b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/proposals/GetterBodyProposal.wlk.xt index 25cdce9213..e6c6f60386 100644 --- a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/proposals/GetterBodyProposal.wlk.xt +++ b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/proposals/GetterBodyProposal.wlk.xt @@ -1,7 +1,7 @@ /* XPECT_SETUP org.uqbar.project.wollok.tests.proposals.WollokContentAssistTest END_SETUP */ class Golondrina { - var energia = 100 + const energia = 100 method getEnergia() { /* XPECT proposals at 'energia' --- "Value", #, (, diff --git a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/quickfix/ConstructorsQuickFixTest.xtend b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/quickfix/ConstructorsQuickFixTest.xtend index e15a5d7a54..f078155be8 100644 --- a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/quickfix/ConstructorsQuickFixTest.xtend +++ b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/quickfix/ConstructorsQuickFixTest.xtend @@ -433,7 +433,7 @@ class ConstructorsQuickFixTest extends AbstractWollokQuickFixTestCase { val initial = #[ ''' class A { - var y = 0 + const y = 0 method someMethod(){ return y } @@ -450,7 +450,7 @@ class ConstructorsQuickFixTest extends AbstractWollokQuickFixTestCase { val result = #[ ''' class A { - var y = 0 + const y = 0 constructor(param1) { //TODO: Autogenerated Code ! } @@ -474,7 +474,7 @@ class ConstructorsQuickFixTest extends AbstractWollokQuickFixTestCase { val initial = #[ ''' class A { - var y = 0 + const y = 0 method someMethod(){ return y } @@ -491,7 +491,7 @@ class ConstructorsQuickFixTest extends AbstractWollokQuickFixTestCase { val result = #[ ''' class A { - var y = 0 + const y = 0 constructor(param1, param2) { //TODO: Autogenerated Code ! } @@ -659,7 +659,7 @@ class ConstructorsQuickFixTest extends AbstractWollokQuickFixTestCase { val initial = #[ ''' class A { - var y = 0 + const y = 0 method y() = y } class B { @@ -673,7 +673,7 @@ class ConstructorsQuickFixTest extends AbstractWollokQuickFixTestCase { val result = #[ ''' class A { - var y = 0 + const y = 0 method y() = y } class B { @@ -783,8 +783,8 @@ class ConstructorsQuickFixTest extends AbstractWollokQuickFixTestCase { val initial = #[ ''' class Ave { - var energia = 1 - var saludo = "Hola" + const energia = 1 + const saludo = "Hola" method energiaCalculada() = saludo.size() + energia } object aveBuilder { @@ -797,8 +797,8 @@ class ConstructorsQuickFixTest extends AbstractWollokQuickFixTestCase { val result = #[ ''' class Ave { - var energia = 1 - var saludo = "Hola" + const energia = 1 + const saludo = "Hola" method energiaCalculada() = saludo.size() + energia } object aveBuilder { @@ -815,8 +815,8 @@ class ConstructorsQuickFixTest extends AbstractWollokQuickFixTestCase { val initial = #[ ''' class Ave { - var energia = 1 - var saludo = "Hola" + const energia = 1 + const saludo = "Hola" method energiaCalculada() = saludo.size() + energia } object aveBuilder { @@ -829,8 +829,8 @@ class ConstructorsQuickFixTest extends AbstractWollokQuickFixTestCase { val result = #[ ''' class Ave { - var energia = 1 - var saludo = "Hola" + const energia = 1 + const saludo = "Hola" method energiaCalculada() = saludo.size() + energia } object aveBuilder { @@ -847,8 +847,8 @@ class ConstructorsQuickFixTest extends AbstractWollokQuickFixTestCase { val initial = #[ ''' class Ave { - var energia = 1 - var saludo = "Hola" + const energia = 1 + const saludo = "Hola" method energiaCalculada() = saludo.size() + energia } object aveBuilder { @@ -861,8 +861,8 @@ class ConstructorsQuickFixTest extends AbstractWollokQuickFixTestCase { val result = #[ ''' class Ave { - var energia = 1 - var saludo = "Hola" + const energia = 1 + const saludo = "Hola" method energiaCalculada() = saludo.size() + energia } object aveBuilder { @@ -879,8 +879,8 @@ class ConstructorsQuickFixTest extends AbstractWollokQuickFixTestCase { val initial = #[ ''' class Ave { - var energia = 1 - var saludo = "Hola" + const energia = 1 + const saludo = "Hola" method energiaCalculada() = saludo.size() + energia } object aveBuilder { @@ -893,8 +893,8 @@ class ConstructorsQuickFixTest extends AbstractWollokQuickFixTestCase { val result = #[ ''' class Ave { - var energia = 1 - var saludo = "Hola" + const energia = 1 + const saludo = "Hola" method energiaCalculada() = saludo.size() + energia } object aveBuilder { @@ -911,8 +911,8 @@ class ConstructorsQuickFixTest extends AbstractWollokQuickFixTestCase { val initial = #[ ''' class Ave { - var energia = 1 - var saludo = "Hola" + const energia = 1 + const saludo = "Hola" method energiaCalculada() = saludo.size() + energia } object aveBuilder { @@ -925,8 +925,8 @@ class ConstructorsQuickFixTest extends AbstractWollokQuickFixTestCase { val result = #[ ''' class Ave { - var energia = 1 - var saludo = "Hola" + const energia = 1 + const saludo = "Hola" method energiaCalculada() = saludo.size() + energia } object aveBuilder { @@ -943,8 +943,8 @@ class ConstructorsQuickFixTest extends AbstractWollokQuickFixTestCase { val initial = #[ ''' class Ave { - var energia = 1 - var saludo = "Hola" + const energia = 1 + const saludo = "Hola" method energiaCalculada() = saludo.size() + energia } object aveBuilder { @@ -957,8 +957,8 @@ class ConstructorsQuickFixTest extends AbstractWollokQuickFixTestCase { val result = #[ ''' class Ave { - var energia = 1 - var saludo = "Hola" + const energia = 1 + const saludo = "Hola" method energiaCalculada() = saludo.size() + energia } object aveBuilder { @@ -1008,7 +1008,7 @@ class ConstructorsQuickFixTest extends AbstractWollokQuickFixTestCase { ''' class Ave { var energia - var saludo = 0 + const saludo = 0 var color } object aveBuilder { @@ -1022,7 +1022,7 @@ class ConstructorsQuickFixTest extends AbstractWollokQuickFixTestCase { ''' class Ave { var energia - var saludo = 0 + const saludo = 0 var color } object aveBuilder { diff --git a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/quickfix/MethodOnSelfDoesntExistsQuickFixTest.xtend b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/quickfix/MethodOnSelfDoesntExistsQuickFixTest.xtend index f4556f3ba5..6cd4ecb194 100644 --- a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/quickfix/MethodOnSelfDoesntExistsQuickFixTest.xtend +++ b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/quickfix/MethodOnSelfDoesntExistsQuickFixTest.xtend @@ -106,7 +106,7 @@ class MethodOnSelfDoesntExistsQuickFixTest extends AbstractWollokQuickFixTestCas val initial = #[''' class MyClass{ method aMethod(){ - var a = 1 + const a = 1 if (a === 1) self.otherMethod() } @@ -116,7 +116,7 @@ class MethodOnSelfDoesntExistsQuickFixTest extends AbstractWollokQuickFixTestCas val result = #[''' class MyClass{ method aMethod(){ - var a = 1 + const a = 1 if (a === 1) self.otherMethod() } diff --git a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/quickfix/OverridingQuickFixTest.xtend b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/quickfix/OverridingQuickFixTest.xtend index d830f41504..38fa2cb093 100644 --- a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/quickfix/OverridingQuickFixTest.xtend +++ b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/quickfix/OverridingQuickFixTest.xtend @@ -17,7 +17,7 @@ class OverridingQuickFixTest extends AbstractWollokQuickFixTestCase { } class PirataEspecial inherits Pirata { - var misiones = [] + const misiones = [] method cantidadMisiones() = misiones.size() @@ -37,7 +37,7 @@ class OverridingQuickFixTest extends AbstractWollokQuickFixTestCase { } class PirataEspecial inherits Pirata { - var misiones = [] + const misiones = [] method cantidadMisiones() = misiones.size() @@ -51,13 +51,13 @@ class OverridingQuickFixTest extends AbstractWollokQuickFixTestCase { def removeUnnecesaryOverridenMethod2(){ val initial = #[''' class Pirata { - var bravura = 70 + const bravura = 70 method bravura() = bravura } class PirataEspecial inherits Pirata { - var misiones = [] + const misiones = [] method cantidadMisiones() = misiones.size() @@ -67,13 +67,13 @@ class OverridingQuickFixTest extends AbstractWollokQuickFixTestCase { val result = #[''' class Pirata { - var bravura = 70 + const bravura = 70 method bravura() = bravura } class PirataEspecial inherits Pirata { - var misiones = [] + const misiones = [] method cantidadMisiones() = misiones.size() diff --git a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/quickfix/PropertiesQuickFixTest.xtend b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/quickfix/PropertiesQuickFixTest.xtend index 85cdf9e5cc..a38daed2c1 100644 --- a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/quickfix/PropertiesQuickFixTest.xtend +++ b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/quickfix/PropertiesQuickFixTest.xtend @@ -248,7 +248,7 @@ class PropertiesQuickFixTest extends AbstractWollokQuickFixTestCase { def testAddPropertyVarToWko(){ val initial = #[''' object pepita { - var energia = 0 + const energia = 0 method valentia() = energia } @@ -262,7 +262,7 @@ class PropertiesQuickFixTest extends AbstractWollokQuickFixTestCase { val result = #[''' object pepita { - var property energia = 0 + const property energia = 0 method valentia() = energia } @@ -344,7 +344,7 @@ class PropertiesQuickFixTest extends AbstractWollokQuickFixTestCase { def testAddPropertyWritableToWko2(){ val initial = #[''' object pepita { - var energia = 0 + const energia = 0 method valentia() = energia } diff --git a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/quickfix/QuickFixTest.xtend b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/quickfix/QuickFixTest.xtend index 4a82a515c0..dfefa3dc2a 100644 --- a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/quickfix/QuickFixTest.xtend +++ b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/quickfix/QuickFixTest.xtend @@ -97,7 +97,7 @@ class QuickFixTest extends AbstractWollokQuickFixTestCase { def testMethodWithExpressionNotReturning(){ val initial = #[''' class MyClass{ - var y = 0 + const y = 0 method getX(){ y + 1 } @@ -106,7 +106,7 @@ class QuickFixTest extends AbstractWollokQuickFixTestCase { val result = #[''' class MyClass{ - var y = 0 + const y = 0 method getX(){ return y + 1 } @@ -119,14 +119,14 @@ class QuickFixTest extends AbstractWollokQuickFixTestCase { def ifInsteadOfConditionalExpression(){ val initial = #[''' class MyClass{ - var a = 1 + const a = 1 method aIsEven() = if (a.even()) true else false } '''] val result = #[''' class MyClass{ - var a = 1 + const a = 1 method aIsEven() = a.even() } '''] @@ -137,7 +137,7 @@ class QuickFixTest extends AbstractWollokQuickFixTestCase { def ifInsteadOfConditionalExpression2(){ val initial = #[''' class MyClass{ - var a = 1 + const a = 1 method aIsEven() { if (a.even()) return true else return false } @@ -146,7 +146,7 @@ class QuickFixTest extends AbstractWollokQuickFixTestCase { val result = #[''' class MyClass{ - var a = 1 + const a = 1 method aIsEven() { return a.even() } @@ -159,14 +159,14 @@ class QuickFixTest extends AbstractWollokQuickFixTestCase { def ifInsteadOfConditionalExpressionNot(){ val initial = #[''' class MyClass{ - var a = 1 + const a = 1 method aIsOdd() = if (a.even()) false else true } '''] val result = #[''' class MyClass{ - var a = 1 + const a = 1 method aIsOdd() = !(a.even()) } '''] diff --git a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/typesystem/xpect/PolimorfismoLoboFeroz.wlk.xt b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/typesystem/xpect/PolimorfismoLoboFeroz.wlk.xt index c3664fa038..acb18eb686 100644 --- a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/typesystem/xpect/PolimorfismoLoboFeroz.wlk.xt +++ b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/typesystem/xpect/PolimorfismoLoboFeroz.wlk.xt @@ -54,7 +54,7 @@ object chanchitoCasaMadera{ } object chanchitoTrabajador{ - var edad = 2 + const edad = 2 method peso(){ return edad * 5 @@ -80,7 +80,7 @@ object casaPaja{ } object casaMadera{ - var minutos = 15 + const minutos = 15 var visitante // var visitante = chanchito @@ -104,9 +104,9 @@ object casaMadera{ object casaLadrillos{ - var ladrillos = 10 + const ladrillos = 10 var pesoOcupado = chanchitoTrabajador.peso() -// var pesoOcupado = 10 +// const pesoOcupado = 10 method llega(chanchito){ pesoOcupado = pesoOcupado + chanchito.peso() @@ -133,7 +133,7 @@ object abuela{ } object casaAbuela{ - var minutos = 5 + const minutos = 5 method minutos(){ return minutos @@ -141,7 +141,7 @@ object casaAbuela{ } object oveja{ - var nombre = "Dolly" + const nombre = "Dolly" method caloriasQueAporta(){ return nombre.size()*5 @@ -169,7 +169,7 @@ object bosque{ } object canasta { - var cantidadManzanas = 2 + const cantidadManzanas = 2 method peso() { return 2 * cantidadManzanas } diff --git a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/typesystem/xpect/booleans.wlk.xt b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/typesystem/xpect/booleans.wlk.xt index b0431aec14..de1f54382d 100644 --- a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/typesystem/xpect/booleans.wlk.xt +++ b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/typesystem/xpect/booleans.wlk.xt @@ -1,8 +1,8 @@ /* XPECT_SETUP org.uqbar.project.wollok.tests.typesystem.xpect.TypeSystemXpectTestCase END_SETUP */ object booleanConditionError { - var a = 2 - var b = 3 + const a = 2 + const b = 3 method m() { return rules.a() diff --git a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/typesystem/xpect/closures.wpgm.xt b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/typesystem/xpect/closures.wpgm.xt index 3eafb218c9..a9a7b3aa9a 100644 --- a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/typesystem/xpect/closures.wpgm.xt +++ b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/typesystem/xpect/closures.wpgm.xt @@ -1,7 +1,7 @@ /* XPECT_SETUP org.uqbar.project.wollok.tests.typesystem.xpect.TypeSystemXpectTestCase END_SETUP */ program p { - var bool = true + const bool = true // XPECT type at c1 --> {() => String} const c1 = { "Hello" } diff --git a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/typesystem/xpect/constructors.wlk.xt b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/typesystem/xpect/constructors.wlk.xt index a69f938115..5fa905abc3 100644 --- a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/typesystem/xpect/constructors.wlk.xt +++ b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/typesystem/xpect/constructors.wlk.xt @@ -9,7 +9,7 @@ object constructorTests { } class C { - var number + const number constructor(n, dog) { number = n * 2 diff --git a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/typesystem/xpect/instantiation.wpgm.xt b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/typesystem/xpect/instantiation.wpgm.xt index 1c46baeeff..3a33e4b8de 100644 --- a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/typesystem/xpect/instantiation.wpgm.xt +++ b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/typesystem/xpect/instantiation.wpgm.xt @@ -9,8 +9,8 @@ class Persona { // Clase sin constructores para instanciación directa class Direccion { - var calle = "Medrano" - var numero = 951 + const calle = "Medrano" + const numero = 951 // Esto garantiza los tipos de calle y número method tipar() = calle.charAt(numero) @@ -18,7 +18,7 @@ class Direccion { // Clase sin constructores, instanciación directa usando variables de superclase class DireccionRemota inherits Direccion { - var ciudad = new Ciudad(km = 0) + const ciudad = new Ciudad(km = 0) override method tipar() = ciudad.nombreCiudad() } @@ -47,7 +47,7 @@ class Point { // Clase con constructores heredados class Point3D inherits Point { - var z = 0 + const z = 0 override method tipar() = z.even() } diff --git a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/typesystem/xpect/methods.wpgm.xt b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/typesystem/xpect/methods.wpgm.xt index 0c062d565f..eaa6fcdd33 100644 --- a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/typesystem/xpect/methods.wpgm.xt +++ b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/typesystem/xpect/methods.wpgm.xt @@ -65,7 +65,7 @@ class Entrenador { // XPECT methodType at alimentar --> (Golondrina, Number) => Void method alimentar(golondrina, comida) { - var c = { g => g.come(comida) } + const c = { g => g.come(comida) } c.apply(golondrina) } diff --git a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/typesystem/xpect/objectLiterals.wlk.xt b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/typesystem/xpect/objectLiterals.wlk.xt index 1e38e2e93f..96fb793057 100644 --- a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/typesystem/xpect/objectLiterals.wlk.xt +++ b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/typesystem/xpect/objectLiterals.wlk.xt @@ -3,8 +3,8 @@ class Persona { // XPECT type at hambriento --> { cena } - var hambriento = object { - var a = 0 + const hambriento = object { + const a = 0 // XPECT methodType at cena() --> () => Number method cena() { @@ -13,13 +13,13 @@ class Persona { } // XPECT type at charlatan --> { habla } - var charlatan = object { + const charlatan = object { // XPECT methodType at habla() --> () => String method habla() = "Hola" } // XPECT type at multifacetico --> { habla; cena } - var multifacetico = object { + const multifacetico = object { // XPECT methodType at habla() --> () => String method habla() = "Chau" @@ -28,7 +28,7 @@ class Persona { } // XPECT type at friki --> { habla; cena } - var friki = object { + const friki = object { // XPECT methodType at habla() --> () => Number method habla() = 42 diff --git a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/xpect/AssignmentToTheSameVariable.wlk.xt b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/xpect/AssignmentToTheSameVariable.wlk.xt index b8fbff7dfd..a5c7c4dc34 100644 --- a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/xpect/AssignmentToTheSameVariable.wlk.xt +++ b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/xpect/AssignmentToTheSameVariable.wlk.xt @@ -15,10 +15,10 @@ class Golondrina { } // XPECT errors --> "Cannot assign a variable to itself. It does not have any effect" at "y" - var y = y + const y = y var z = 24 z = y - var w = y + const w = y alimento.hacerAlgo(x,y,z,w) } diff --git a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/xpect/BadIfUsage.wlk.xt b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/xpect/BadIfUsage.wlk.xt index ac95c96776..3cd9c59e9f 100644 --- a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/xpect/BadIfUsage.wlk.xt +++ b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/xpect/BadIfUsage.wlk.xt @@ -1,7 +1,7 @@ /* XPECT_SETUP org.uqbar.project.wollok.tests.xpect.WollokXPectTest END_SETUP */ object joaquin { - var tocaEnGrupo = false + const tocaEnGrupo = false var gradoAlegria // XPECT errors --> "If-statements without else cannot be considered valid expressions as they cannot always yield a value" at "tocaEnGrupo" @@ -118,7 +118,7 @@ object sarasita { method ifInsideExpressionWithoutElseShouldFailInAssignment() { // XPECT errors --> "If-statements without else cannot be considered valid expressions as they cannot always yield a value" at "1 == 2" var failed = if(1 == 2) 2 - var ok = if (1 == 2) 2 else 3 + const ok = if (1 == 2) 2 else 3 failed = ok return ok == 3 } diff --git a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/xpect/CheckInitialValueAssignment.wlk.xt b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/xpect/CheckInitialValueAssignment.wlk.xt index 9cea321fc4..53ae6b1bf1 100644 --- a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/xpect/CheckInitialValueAssignment.wlk.xt +++ b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/xpect/CheckInitialValueAssignment.wlk.xt @@ -12,14 +12,14 @@ class A { } class B { - var energia = 1 + const energia = 1 constructor() { } method energia() = energia } class C { - var energia = 1 + const energia = 1 method energia() = energia } diff --git a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/xpect/CheckMessagesToWKO.wlk.xt b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/xpect/CheckMessagesToWKO.wlk.xt index 4ce0e3d9a8..7d72e50cfb 100644 --- a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/xpect/CheckMessagesToWKO.wlk.xt +++ b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/xpect/CheckMessagesToWKO.wlk.xt @@ -29,9 +29,9 @@ class Persona { } class B { - var i = pepita.foo() + const i = pepita.foo() // XPECT errors --> "pepita does not understand zoo()" at "zoo" - var x = pepita.zoo() + const x = pepita.zoo() method a() = i + x } diff --git a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/xpect/CheckOnNameStyles.wlk.xt b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/xpect/CheckOnNameStyles.wlk.xt index 9b55ff54a4..6e3c46add4 100644 --- a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/xpect/CheckOnNameStyles.wlk.xt +++ b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/xpect/CheckOnNameStyles.wlk.xt @@ -23,12 +23,12 @@ method run() { - var car = 23 + const car = 23 // XPECT warnings --> "Variable name should start with lowercase" at "Lota" - var Lota = "lota" + const Lota = "lota" - var aBlock = + const aBlock = // XPECT warnings --> "Parameter name should start with lowercase" at "A" {A => A > 23 diff --git a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/xpect/ConstructorDelegation.wlk.xt b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/xpect/ConstructorDelegation.wlk.xt index 85db12e525..661c050165 100644 --- a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/xpect/ConstructorDelegation.wlk.xt +++ b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/xpect/ConstructorDelegation.wlk.xt @@ -90,7 +90,7 @@ class Superclase { } class InvalidInstanceAccessOnConstructorDelegation inherits Superclase { - var x = 1 + const x = 1 // XPECT warnings --> "Accessing instance methods within constructor delegation is dangerous because object might not be completely initialized." at "self" constructor() = super(self.getX()) @@ -104,7 +104,7 @@ class InvalidInstanceAccessOnConstructorDelegation2 inherits Superclase { } class InvalidInstanceAccessOnConstructorDelegation3 inherits Superclase { - var x = 2 + const x = 2 // XPECT errors --> "Accessing instance variables within constructor delegation is dangerous because object might not be completely initialized." at "x" constructor() = super(x) diff --git a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/xpect/DuplicatedInstanceVariable.wtest.xt b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/xpect/DuplicatedInstanceVariable.wtest.xt index 29e49a3641..565bbdeec7 100644 --- a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/xpect/DuplicatedInstanceVariable.wtest.xt +++ b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/xpect/DuplicatedInstanceVariable.wtest.xt @@ -12,7 +12,7 @@ class Camion { describe "Carga de camiones" { var duplic = 2 - var duplic2 = 0 + const duplic2 = 0 method camion(unEstado) = new Camion(pesoMaximo = 200, estado = unEstado) @@ -25,7 +25,7 @@ describe "Carga de camiones" { method conVariableDuplicada() { // XPECT errors --> "Duplicated Name" at "duplic2" - var duplic2 = 3 + const duplic2 = 3 return 0 + duplic2 } diff --git a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/xpect/DuplicatedInstanceVariableInHierarchy.wlk.xt b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/xpect/DuplicatedInstanceVariableInHierarchy.wlk.xt index be816b598a..8a19ec600d 100644 --- a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/xpect/DuplicatedInstanceVariableInHierarchy.wlk.xt +++ b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/xpect/DuplicatedInstanceVariableInHierarchy.wlk.xt @@ -1,14 +1,14 @@ /* XPECT_SETUP org.uqbar.project.wollok.tests.xpect.WollokXPectTest END_SETUP */ class Levadura { - var biomasa = 100 + const biomasa = 100 method getBiomasa() = biomasa } class Ale inherits Levadura { // XPECT errors --> "There is already an instance variable with this name in the hierarchy" at "biomasa" - var biomasa = 200 + const biomasa = 200 method algoConBiomasaParaEvitarWarning() { return biomasa @@ -24,7 +24,7 @@ class B inherits Levadura { */ class C inherits B { // XPECT errors --> "There is already an instance variable with this name in the hierarchy" at "biomasa" - var biomasa = 200 + const biomasa = 200 method algoConBiomasaParaEvitarWarning() { return biomasa @@ -34,7 +34,7 @@ class C inherits B { // same for objects object anObject inherits Levadura { // XPECT errors --> "There is already an instance variable with this name in the hierarchy" at "biomasa" - var biomasa = 200 + const biomasa = 200 method algoConBiomasaParaEvitarWarning() { return biomasa diff --git a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/xpect/DuplicatedReferenceFromImports.wlk.xt b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/xpect/DuplicatedReferenceFromImports.wlk.xt index 817b66272b..f621f5bc87 100644 --- a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/xpect/DuplicatedReferenceFromImports.wlk.xt +++ b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/xpect/DuplicatedReferenceFromImports.wlk.xt @@ -9,7 +9,9 @@ object apu { // XPECT warnings --> "This name is already defined (imported from libForImports.wlk)" at "mod" var mod = 20 - method getMod() = mod + method addModSix() { + mod = mod + 6 + } } // XPECT warnings --> "This name is already defined (imported from libForImports.wlk)" at "Burns" diff --git a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/xpect/DuplicatedReferenceFromImports.wtest.xt b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/xpect/DuplicatedReferenceFromImports.wtest.xt index 0a3f5ec376..73a40bf9f1 100644 --- a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/xpect/DuplicatedReferenceFromImports.wtest.xt +++ b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/xpect/DuplicatedReferenceFromImports.wtest.xt @@ -6,7 +6,7 @@ describe "duplicated references" { test "with duplicated variable" { // XPECT warnings --> "This name is already defined (imported from libForImports.wlk)" at "apu" - var apu = 2 + const apu = 2 assert.equals(apu, 2) } } \ No newline at end of file diff --git a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/xpect/EffectlessExpressionsInSequence.wlk.xt b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/xpect/EffectlessExpressionsInSequence.wlk.xt index 512985e922..e1db440229 100644 --- a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/xpect/EffectlessExpressionsInSequence.wlk.xt +++ b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/xpect/EffectlessExpressionsInSequence.wlk.xt @@ -21,5 +21,5 @@ object testObject { // XPECT warnings --> "This expression does not make sense in a sequence, as it does not produce any effects." at "helper" method invalidBlock() = { helper(100) } - method validBlock() = { var a = helper; [a] } + method validBlock() = { const a = helper; [a] } } diff --git a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/xpect/GetterMethodReturn.wlk.xt b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/xpect/GetterMethodReturn.wlk.xt index 4dab8842d7..55c726627f 100644 --- a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/xpect/GetterMethodReturn.wlk.xt +++ b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/xpect/GetterMethodReturn.wlk.xt @@ -1,7 +1,7 @@ /* XPECT_SETUP org.uqbar.project.wollok.tests.xpect.WollokXPectTest END_SETUP */ class A { - var age = 2 + const age = 2 method getFirstName() { return "John" } method getLastName() = "Doe" @@ -19,7 +19,7 @@ class A { // same goes for objects object anObject { - var age = 23 + const age = 23 method getFirstName() { return "John" } method getLastName() = "Doe" diff --git a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/xpect/NamedParameters.wlk.xt b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/xpect/NamedParameters.wlk.xt index dff0fc2418..3317210cc9 100644 --- a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/xpect/NamedParameters.wlk.xt +++ b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/xpect/NamedParameters.wlk.xt @@ -9,7 +9,7 @@ class Ave { method volar() { energia -= 10 } } class Golondrina inherits Ave { - var peso + const peso method estaGorda() = peso > 100 } class Torcaza inherits Ave { @@ -52,8 +52,8 @@ class Entrenador { } class Heroe { - var nombre = null - var traje = null + const nombre = null + const traje = null method quienSoy() = nombre method tengoTraje() = traje != null @@ -67,8 +67,8 @@ object deadpool inherits Heroe(apellido = "Wilson") { } object charlie { // XPECT errors --> "Reference apellido not found in class Heroe" at "apellido = \"Fawcett\"" - var angel1 = object inherits Heroe(apellido = "Fawcett") {} - var angel2 = object inherits Heroe(nombre = "") {} + const angel1 = object inherits Heroe(apellido = "Fawcett") {} + const angel2 = object inherits Heroe(nombre = "") {} method quienCumpleMision() = [angel1, angel2] } diff --git a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/xpect/PropertiesDefinition.wpgm.xt b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/xpect/PropertiesDefinition.wpgm.xt index c8634cd160..22776e7ee1 100644 --- a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/xpect/PropertiesDefinition.wpgm.xt +++ b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/xpect/PropertiesDefinition.wpgm.xt @@ -23,7 +23,7 @@ class Ave { var property energia = 10 const property peso = 5 var property color = "azul" - var alas = [] + const alas = [] constructor() { // XPECT errors --> "Property are only allowed in objects, classes and mixins" at "property" diff --git a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/xpect/PropertiesDefinition.wtest.xt b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/xpect/PropertiesDefinition.wtest.xt index 2733436348..84d94d1677 100644 --- a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/xpect/PropertiesDefinition.wtest.xt +++ b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/xpect/PropertiesDefinition.wtest.xt @@ -25,7 +25,7 @@ class C inherits A { describe "group of tests" { - var valor = 4 + const valor = 4 // XPECT errors --> "Property are only allowed in objects, classes and mixins" at "property" var property valor2 = 0 diff --git a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/xpect/SuperInvocation.wlk.xt b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/xpect/SuperInvocation.wlk.xt index 8a18746c4c..6e12a6e0f3 100644 --- a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/xpect/SuperInvocation.wlk.xt +++ b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/xpect/SuperInvocation.wlk.xt @@ -2,7 +2,7 @@ class Golondrina { var energia = 100 - var nivelAturdimiento = 0 + const nivelAturdimiento = 0 method energia() { // XPECT warnings --> "Super can only be used in an overriding method" at "super()" diff --git a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/xpect/UnusedVariable.wlk.xt b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/xpect/UnusedVariable.wlk.xt index 74bc06ee6e..327d688b1c 100644 --- a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/xpect/UnusedVariable.wlk.xt +++ b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/xpect/UnusedVariable.wlk.xt @@ -3,7 +3,7 @@ class WithUnusedVariables { var a = 123 // XPECT warnings --> "Unused variable" at "b" - var b = 123 + const b = 123 var c var d const x @@ -11,7 +11,7 @@ class WithUnusedVariables { const usedOnlyWithUnary = "" - var equipos = [] + const equipos = [] method doSomething() { a = a + 1 + c + x diff --git a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/xpect/UnusedVariable.wtest.xt b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/xpect/UnusedVariable.wtest.xt index 365c603ab9..0f522f1a8c 100644 --- a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/xpect/UnusedVariable.wtest.xt +++ b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/xpect/UnusedVariable.wtest.xt @@ -2,7 +2,7 @@ class HechizoComercial {} class Personaje { - var hechizoPreferido = null + const hechizoPreferido = null method hechizoPreferido() = hechizoPreferido } describe "entregas punto 3" { diff --git a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/xpect/VoidMethodsUsage.wlk.xt b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/xpect/VoidMethodsUsage.wlk.xt index b43152e65d..dce3c74658 100644 --- a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/xpect/VoidMethodsUsage.wlk.xt +++ b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/xpect/VoidMethodsUsage.wlk.xt @@ -52,7 +52,7 @@ class MethodsCalledOnWellKnowObjects inherits A { } method asABinaryOperatorArgument() { - var cond = true + const cond = true return [ // XPECT errors --> "Message send "eat(10)" produces no value (missing return in method?)" at "eat" 10 + pepita.eat(10), diff --git a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/xpect/cannotUseSelfInAProgram.wpgm.xt b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/xpect/cannotUseSelfInAProgram.wpgm.xt index 5fbf0fd45a..70527cd8db 100644 --- a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/xpect/cannotUseSelfInAProgram.wpgm.xt +++ b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/xpect/cannotUseSelfInAProgram.wpgm.xt @@ -4,20 +4,20 @@ program a { // XPECT errors --> "Cannot use 'self' keyword outside an object, class, mixin or describe." at "self" self.println() - var a = true + const a = true if (a) { // XPECT errors --> "Cannot use 'self' keyword outside an object, class, mixin or describe." at "self" self.println() } - var collection = ['a', 'b', 'c'] + const collection = ['a', 'b', 'c'] // XPECT errors --> "Cannot use 'self' keyword outside an object, class, mixin or describe." at "self" collection.contains(self) // safe ! - var anObject = object { + const anObject = object { method aMethod() { return self } diff --git a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/xpect/dontUseLocalVarOnlyToReturn.wlk.xt b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/xpect/dontUseLocalVarOnlyToReturn.wlk.xt index 3237b2d99d..4320a1811d 100644 --- a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/xpect/dontUseLocalVarOnlyToReturn.wlk.xt +++ b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/xpect/dontUseLocalVarOnlyToReturn.wlk.xt @@ -1,22 +1,22 @@ /* XPECT_SETUP org.uqbar.project.wollok.tests.xpect.WollokXPectTest END_SETUP */ class A { - var empleados = [] - var ahorros = 2 + const empleados = [] + const ahorros = 2 method costos(persona, cant_hambiente, cant_pisos) { // XPECT warnings --> "Local variable used just to return. Consider removing it" at "costo" - var costo = empleados.sum { per => persona.presupuesto(cant_hambiente, cant_pisos) } + const costo = empleados.sum { per => persona.presupuesto(cant_hambiente, cant_pisos) } return costo } method presupuestoMaximo() { // XPECT warnings --> "Local variable used just to return. Consider removing it" at "presupuesto_maximo" - var presupuesto_maximo = 0.20 * ahorros + const presupuesto_maximo = 0.20 * ahorros return presupuesto_maximo } method localVarWithoutReturningItDirectly() { - var a = 23 + const a = 23 return a * 3 } diff --git a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/xpect/unreachableCodeInBooleanBinaryOperation.wlk.xt b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/xpect/unreachableCodeInBooleanBinaryOperation.wlk.xt index 3b6e3b32ef..49724bab5f 100644 --- a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/xpect/unreachableCodeInBooleanBinaryOperation.wlk.xt +++ b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/xpect/unreachableCodeInBooleanBinaryOperation.wlk.xt @@ -6,7 +6,7 @@ object pepita { object p { method run() { var cond = true - var algo = true + const algo = true // // AND From b1108e9ff14708982c035bc190cbe1382e12665a Mon Sep 17 00:00:00 2001 From: Fernando Dodino Date: Sat, 9 Nov 2019 11:38:22 -0300 Subject: [PATCH 108/133] Removing regression test cases => moved to wollok-language --- .../tests/regression/RegressionTestCase.xtend | 232 ------------------ wollok-language | 2 +- 2 files changed, 1 insertion(+), 233 deletions(-) delete mode 100644 org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/regression/RegressionTestCase.xtend diff --git a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/regression/RegressionTestCase.xtend b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/regression/RegressionTestCase.xtend deleted file mode 100644 index d9cb5ec705..0000000000 --- a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/regression/RegressionTestCase.xtend +++ /dev/null @@ -1,232 +0,0 @@ -package org.uqbar.project.wollok.tests.regression - -import org.junit.Ignore -import org.junit.Test -import org.uqbar.project.wollok.tests.interpreter.AbstractWollokInterpreterTestCase - -/** - * - * @author jfernandes - */ -class RegressionTestCase extends AbstractWollokInterpreterTestCase { - - @Test - def void bug_38() { - ''' - object pajarera { - var pajaros = [pepita,pepe,pepona] - - method agregarA(pajaro){ - pajaros.add(pajaro) - } - - method sacarA(pajaro){ - pajaros.remove(pajaro) - } - - method cuantosHay(){ - return pajaros.size() - } - - method getPajaros(){ - return pajaros - } - - method alimentarATodosCon(comida){ - pajaros.forEach{p=>p.comer(comida)} - } - - method hacerVolarATodas20M(metros){ - pajaros.forEach{p=>p.volar(metros)} - } - - method cualEstaSaludable(){ - return pajaros.filter{p=>p.energia() > 100} - } - - method retornaEnergias(energiaMinima){ - return pajaros.filter{p=>p.energia() < energiaMinima} - } - - method el(){ - var filtro1 = [] - var filtro2 = [] - var filtro3 = [] - - filtro1 = pajaros.filter{p=>p.energia() <= pepita.energia()} - filtro2 = filtro1.filter{pp=>pp.energia() <= pepona.energia()} - filtro3 = filtro2.filter{ppp=>ppp.energia() <= pepe.energia()} - - - //var filtro2 = filtro1.filter{pp=>pp.energia() > pepe.energia()} - //return filtro2.filter{ppp=>ppp.energia() > pepona.energia()} - - return self.comparaEnergia(filtro3) - } - - method alimentaBajaEnergia(filtro3){ - filtro3.forEach{pppp=>pppp.com()} - //pepe.com() - self.comparaEnergia(filtro3) - } - - method comparaEnergia(filtro3){ - var filtro4 = [] - filtro4 = filtro3.filter{p=>p.energia() >= 30} - - if (filtro4.size() == 0) { - self.alimentaBajaEnergia(filtro3) - return pepe.energia() - }else{ - return "La energia de pepe es 30" - } - } - - method esta(pajaro){ - return pajaros.contains(pajaro) - } - - method getEnergias(){ - return pajaros.map{p=>p.energia()} - } - - method estanTodosVivos(){ - return pajaros.forAll{p=>p.energia() > 0} - } - } - object pepita { - var energia = 30 - - method volar(metros){ - return energia -= 10 - } - - method comer(comida){ - energia -= comida.energia() - } - method energia(){ - return energia - } - } - - object pepona { - var energia = 20 - - method volar(metros){ - return energia -= 20 - } - - method comer(comida){ - energia -= comida.energia() - } - method energia(){ - return energia - } - } - - object pepe { - var energia = 10 - - method volar(metros){ - return energia -= 5 - } - - method comer(comida){ - energia -= comida.energia() - } - - method com(){ - energia += 10 - } - - method energia(){ - return energia - } - - }'''.interpretPropagatingErrors -} - - @Test - def void bug_213() { - '''object pepita inherits Golondrina { - } - - class Golondrina { - var energia = 100 - method volar(kms) { - self.modificar(-kms * 2) - } - method modificar(n) { - energia += n - } - method getEnergia() = energia - } - - program p { - pepita.volar(2) - } - '''.interpretPropagatingErrors - } - - @Test - def void bug_578() { - ''' - object link { - var arma - method atacarA(alguien) { - arma.causarDanio(alguien) - } - } - object captainFalcon {} - - program p { - try { - #{1}.forEach({ each => link.atacarA(captainFalcon)}) - assert.fail("should have thrown a wollok exception") - } - catch e { - // OK ! a NPE - } - - } - '''.interpretPropagatingErrors - } - - @Test - @Ignore - def void bug_896_stackOverFlow() { - '''object juan { - method blah() { - self.blah() - } - } - - - program a { - try { - juan.blah() - throw new Exception("Should have failed!") - } - catch e : StackOverflowException { - // fine ! - } - }'''.interpretPropagatingErrors - } - - @Test - def void bug_868() { - ''' - object juan { - var mascota = firulais - } - - object firulais { - var duenio = juan - } - program a { - console.println(juan) - } - '''.interpretPropagatingErrors - } - -} \ No newline at end of file diff --git a/wollok-language b/wollok-language index f5dd0765ce..074af4d859 160000 --- a/wollok-language +++ b/wollok-language @@ -1 +1 @@ -Subproject commit f5dd0765ce011cc23d2bc6cbb09100884bf322bd +Subproject commit 074af4d859dbc84666b10c9fa2e1ffa3f6f9de98 From 276de7725f2a10417b458aac3e29fe3d6c4aeb77 Mon Sep 17 00:00:00 2001 From: nicovio Date: Sat, 9 Nov 2019 22:55:52 -0300 Subject: [PATCH 109/133] add PR review changes --- .../tests/xpect/VariableShouldBeConst.wlk.xt | 78 ++++++++++++++++++- .../xpect/VariableShouldBeConst.wtest.xt | 23 ++++++ 2 files changed, 99 insertions(+), 2 deletions(-) create mode 100644 org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/xpect/VariableShouldBeConst.wtest.xt diff --git a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/xpect/VariableShouldBeConst.wlk.xt b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/xpect/VariableShouldBeConst.wlk.xt index 885aee883b..e5bf7a3c11 100644 --- a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/xpect/VariableShouldBeConst.wlk.xt +++ b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/xpect/VariableShouldBeConst.wlk.xt @@ -11,8 +11,50 @@ object variableShouldBeConst { } } +object localVariableInMethodShouldBeConst { + var variable = 123 + + method doSomething() { + // XPECT warnings --> "Variable should be const" at "constante" + var constante = 321 + variable = 666 + return variable + constante + } +} + +object variableWithSingleAssignmentAtInitializationNotRaisesWarningIfProperty { + var variable = 123 + var property constante = 321 + + method doSomething() { + variable = 666 + return variable + constante + } +} + +class VariableShouldBeConst { + var variable = 123 + // XPECT warnings --> "Variable should be const" at "constante" + var constante = 321 + + method doSomething() { + variable = 666 + return variable + constante + } +} + +class LocalVariableInMethodShouldBeConst { + var variable = 123 + + method doSomething() { + // XPECT warnings --> "Variable should be const" at "constante" + var constante = 321 + variable = 666 + return variable + constante + } +} -object variableWithSingleAssignmentNotRaisesWarningIfProperty { +class VariableWithSingleAssignmentAtInitializationNotRaisesWarningIfProperty { var variable = 123 var property constante = 321 @@ -20,4 +62,36 @@ object variableWithSingleAssignmentNotRaisesWarningIfProperty { variable = 666 return variable + constante } -} \ No newline at end of file +} + +mixin VariableShouldBeConstMixin { + var variable = 123 + // XPECT warnings --> "Variable should be const" at "constante" + var constante = 321 + + method doSomething() { + variable = 666 + return variable + constante + } +} + +mixin LocalVariableInMethodShouldBeConstMixin { + var variable = 123 + + method doSomething() { + // XPECT warnings --> "Variable should be const" at "constante" + var constante = 321 + variable = 666 + return variable + constante + } +} + +mixin VariableWithSingleAssignmentAtInitializationNotRaisesWarningIfPropertyMixin { + var variable = 123 + var property constante = 321 + + method doSomething() { + variable = 666 + return variable + constante + } +} diff --git a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/xpect/VariableShouldBeConst.wtest.xt b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/xpect/VariableShouldBeConst.wtest.xt new file mode 100644 index 0000000000..debdb90025 --- /dev/null +++ b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/xpect/VariableShouldBeConst.wtest.xt @@ -0,0 +1,23 @@ +/* XPECT_SETUP org.uqbar.project.wollok.tests.xpect.WollokXPectTest END_SETUP */ + +describe "Variable should be const" { + var variable = 123 + // XPECT warnings --> "Variable should be const" at "constante" + var constante = 321 + + test "666 es distinto a 321" { + variable = 666 + assert.notEquals(variable, constante) + } +} + +describe "Local variable in test should be const" { + var variable = 123 + + test "666 es distinto a 321" { + // XPECT warnings --> "Variable should be const" at "constante" + var constante = 321 + variable = 666 + assert.notEquals(variable, constante) + } +} From ed2b2cc60fd1de69a4ebaadbee32368edfc0eccf Mon Sep 17 00:00:00 2001 From: nicovio Date: Sun, 10 Nov 2019 00:34:34 -0300 Subject: [PATCH 110/133] add 'Change to const' quick fix messages in spanish and english --- .../src/org/uqbar/project/wollok/ui/Messages.java | 2 ++ .../src/org/uqbar/project/wollok/ui/messages.properties | 3 +++ .../src/org/uqbar/project/wollok/ui/messages_es.properties | 3 +++ 3 files changed, 8 insertions(+) diff --git a/org.uqbar.project.wollok.ui/src/org/uqbar/project/wollok/ui/Messages.java b/org.uqbar.project.wollok.ui/src/org/uqbar/project/wollok/ui/Messages.java index 55a57b09d7..3d49430b53 100644 --- a/org.uqbar.project.wollok.ui/src/org/uqbar/project/wollok/ui/Messages.java +++ b/org.uqbar.project.wollok.ui/src/org/uqbar/project/wollok/ui/Messages.java @@ -100,6 +100,8 @@ public class Messages extends NLS { public static String WollokDslQuickfixProvider_lowercase_description; public static String WollokDslQuickfixProvider_changeToVar_name; public static String WollokDslQuickfixProvider_changeToVar_description; + public static String WollokDslQuickfixProvider_changeToConst_name; + public static String WollokDslQuickfixProvider_changeToConst_description; public static String WollokDslQuickfixProvider_createMethod_name; public static String WollokDslQuickfixProvider_createMethod_description; public static String WollokDslQuickfixProvider_createMethod_stub; diff --git a/org.uqbar.project.wollok.ui/src/org/uqbar/project/wollok/ui/messages.properties b/org.uqbar.project.wollok.ui/src/org/uqbar/project/wollok/ui/messages.properties index b17e786348..3a11a0d353 100644 --- a/org.uqbar.project.wollok.ui/src/org/uqbar/project/wollok/ui/messages.properties +++ b/org.uqbar.project.wollok.ui/src/org/uqbar/project/wollok/ui/messages.properties @@ -90,6 +90,9 @@ WollokDslQuickfixProvider_return_last_expression_description = Modifies the last WollokDslQuickfixProvider_changeToVar_name = Change to var WollokDslQuickfixProvider_changeToVar_description = Change declaration to var +WollokDslQuickfixProvider_changeToConst_name = Change to const +WollokDslQuickfixProvider_changeToConst_description = Change declaration to const + WollokDslQuickfixProvider_createMethod_name = Create method WollokDslQuickfixProvider_createMethod_description = Create new method diff --git a/org.uqbar.project.wollok.ui/src/org/uqbar/project/wollok/ui/messages_es.properties b/org.uqbar.project.wollok.ui/src/org/uqbar/project/wollok/ui/messages_es.properties index 568d94ee0d..10eacc2239 100644 --- a/org.uqbar.project.wollok.ui/src/org/uqbar/project/wollok/ui/messages_es.properties +++ b/org.uqbar.project.wollok.ui/src/org/uqbar/project/wollok/ui/messages_es.properties @@ -90,6 +90,9 @@ WollokDslQuickfixProvider_changeToVar_description = Cambiar declaraci\u00F3n a " WollokDslQuickfixProvider_changeToVar_name = Cambiar a "var" WollokDslQuickfixProvider_createMethod_description = Crear m\u00E9todo inexistente +WollokDslQuickfixProvider_changeToConst_name = Cambiar a "const" +WollokDslQuickfixProvider_changeToConst_description = Cambiar declaraci\u00F3n a "const" + WollokDslQuickfixProvider_createMethod_name = Crear nuevo m\u00E9todo WollokDslQuickfixProvider_createMethod_stub = C\u00F3digo autogenerado From 199ba4a6f20009d007aa496264bc917ba88ac42d Mon Sep 17 00:00:00 2001 From: nicovio Date: Sun, 10 Nov 2019 01:00:24 -0300 Subject: [PATCH 111/133] add change var to const quick fix --- .../ui/quickfix/WollokDslQuickfixProvider.xtend | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/org.uqbar.project.wollok.ui/src/org/uqbar/project/wollok/ui/quickfix/WollokDslQuickfixProvider.xtend b/org.uqbar.project.wollok.ui/src/org/uqbar/project/wollok/ui/quickfix/WollokDslQuickfixProvider.xtend index 2a9a5d9aa2..08b348299f 100644 --- a/org.uqbar.project.wollok.ui/src/org/uqbar/project/wollok/ui/quickfix/WollokDslQuickfixProvider.xtend +++ b/org.uqbar.project.wollok.ui/src/org/uqbar/project/wollok/ui/quickfix/WollokDslQuickfixProvider.xtend @@ -426,6 +426,19 @@ class WollokDslQuickfixProvider extends DefaultQuickfixProvider { ] } + @Fix(WollokDslValidator.WARNING_VARIABLE_SHOULD_BE_CONST) + def changeDeclarationToConst(Issue issue, IssueResolutionAcceptor acceptor) { + acceptor.accept(issue, Messages.WollokDslQuickfixProvider_changeToConst_name, + Messages.WollokDslQuickfixProvider_changeToConst_description, null) [ e, context | + if (e instanceof WVariableDeclaration) { + val varDef = e as WVariableDeclaration + val value = " =" + varDef.right.node.text + context.xtextDocument.replace(varDef.before, varDef.node.length, + CONST + " " + varDef.variable.name + value) + } + ] + } + @Fix(DONT_USE_WKONAME_WITHIN_IT) def replaceWkoNameWithSelf(Issue issue, IssueResolutionAcceptor acceptor) { acceptor.accept(issue, Messages.WollokDslQuickFixProvider_replace_wkoname_with_self_name, From 40f7de02f44707c4d5decdbc221df94b58ce363b Mon Sep 17 00:00:00 2001 From: nicovio Date: Sun, 10 Nov 2019 01:19:13 -0300 Subject: [PATCH 112/133] create change var to const quick fix test --- .../ChangeVarToConstQuickFixTest.xtend | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/quickfix/ChangeVarToConstQuickFixTest.xtend diff --git a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/quickfix/ChangeVarToConstQuickFixTest.xtend b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/quickfix/ChangeVarToConstQuickFixTest.xtend new file mode 100644 index 0000000000..10db2565e9 --- /dev/null +++ b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/quickfix/ChangeVarToConstQuickFixTest.xtend @@ -0,0 +1,29 @@ +package org.uqbar.project.wollok.tests.quickfix + +import org.junit.Test +import org.uqbar.project.wollok.ui.Messages + +class ChangeVarToConstQuickFixTest extends AbstractWollokQuickFixTestCase { + + @Test + def testChangeToConst() { + val initial = #[''' + object anObject { + var shouldBeConst = 10 + method getShouldBeConst() { + return shouldBeConst + } + } + '''] + + val result = #[''' + object anObject { + const shouldBeConst = 10 + method getShouldBeConst() { + return shouldBeConst + } + } + '''] + assertQuickfix(initial, result, Messages.WollokDslQuickfixProvider_changeToConst_name) + } +} From 3eaa2e10a9386ec71100ce6fb623ac2540d4d250 Mon Sep 17 00:00:00 2001 From: nicovio Date: Sun, 10 Nov 2019 01:54:13 -0300 Subject: [PATCH 113/133] add tests to ChangeVarToConstQuickFixTest --- .../ChangeVarToConstQuickFixTest.xtend | 180 +++++++++++++++++- 1 file changed, 179 insertions(+), 1 deletion(-) diff --git a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/quickfix/ChangeVarToConstQuickFixTest.xtend b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/quickfix/ChangeVarToConstQuickFixTest.xtend index 10db2565e9..727ed0e291 100644 --- a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/quickfix/ChangeVarToConstQuickFixTest.xtend +++ b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/quickfix/ChangeVarToConstQuickFixTest.xtend @@ -6,7 +6,7 @@ import org.uqbar.project.wollok.ui.Messages class ChangeVarToConstQuickFixTest extends AbstractWollokQuickFixTestCase { @Test - def testChangeToConst() { + def testChangeVarToConstInObject() { val initial = #[''' object anObject { var shouldBeConst = 10 @@ -26,4 +26,182 @@ class ChangeVarToConstQuickFixTest extends AbstractWollokQuickFixTestCase { '''] assertQuickfix(initial, result, Messages.WollokDslQuickfixProvider_changeToConst_name) } + + @Test + def testChangeMethodLocalVarToConstInObject() { + val initial = #[''' + object anObject { + method getShouldBeConst(valor) { + var shouldBeConst = 10 + if (valor == 10) { + return shouldBeConst + 10 + } else { + return shouldBeConst - 10 + } + } + } + '''] + + val result = #[''' + object anObject { + method getShouldBeConst(valor) { + const shouldBeConst = 10 + if (valor == 10) { + return shouldBeConst + 10 + } else { + return shouldBeConst - 10 + } + } + } + '''] + assertQuickfix(initial, result, Messages.WollokDslQuickfixProvider_changeToConst_name) + } + + @Test + def testChangeVarToConstInClass() { + val initial = #[''' + class MyClass { + var shouldBeConst = 10 + method getShouldBeConst() { + return shouldBeConst + } + } + '''] + + val result = #[''' + class MyClass { + const shouldBeConst = 10 + method getShouldBeConst() { + return shouldBeConst + } + } + '''] + assertQuickfix(initial, result, Messages.WollokDslQuickfixProvider_changeToConst_name) + } + + @Test + def testChangeMethodLocalVarToConstInClass() { + val initial = #[''' + class MyClass { + method getShouldBeConst(valor) { + var shouldBeConst = 10 + if (valor == 10) { + return shouldBeConst + 10 + } else { + return shouldBeConst - 10 + } + } + } + '''] + + val result = #[''' + class MyClass { + method getShouldBeConst(valor) { + const shouldBeConst = 10 + if (valor == 10) { + return shouldBeConst + 10 + } else { + return shouldBeConst - 10 + } + } + } + '''] + assertQuickfix(initial, result, Messages.WollokDslQuickfixProvider_changeToConst_name) + } + + @Test + def testChangeVarToConstInMixin() { + val initial = #[''' + mixin MyMixin { + var shouldBeConst = 10 + method getShouldBeConst() { + return shouldBeConst + } + } + '''] + + val result = #[''' + mixin MyMixin { + const shouldBeConst = 10 + method getShouldBeConst() { + return shouldBeConst + } + } + '''] + assertQuickfix(initial, result, Messages.WollokDslQuickfixProvider_changeToConst_name) + } + + @Test + def testChangeMethodLocalVarToConstInMixin() { + val initial = #[''' + mixin MyMixin { + method getShouldBeConst(valor) { + var shouldBeConst = 10 + if (valor == 10) { + return shouldBeConst + 10 + } else { + return shouldBeConst - 10 + } + } + } + '''] + + val result = #[''' + mixin MyMixin { + method getShouldBeConst(valor) { + const shouldBeConst = 10 + if (valor == 10) { + return shouldBeConst + 10 + } else { + return shouldBeConst - 10 + } + } + } + '''] + assertQuickfix(initial, result, Messages.WollokDslQuickfixProvider_changeToConst_name) + } + + @Test + def testChangeVarToConstInDescribe() { + val initial = #[''' + describe "Variable should be const" { + var variable = 123 + test "trivial" { + assert.notEquals(variable, 123) + } + } + '''] + + val result = #[''' + describe "Variable should be const" { + const variable = 123 + test "trivial" { + assert.notEquals(variable, 123) + } + } + '''] + assertQuickfix(initial, result, Messages.WollokDslQuickfixProvider_changeToConst_name) + } + + @Test + def testChangeVarToConstInTest() { + val initial = #[''' + describe "Variable should be const" { + test "trivial" { + var variable = 123 + assert.notEquals(variable, 123) + } + } + '''] + + val result = #[''' + describe "Variable should be const" { + test "trivial" { + const variable = 123 + assert.notEquals(variable, 123) + } + } + '''] + assertQuickfix(initial, result, Messages.WollokDslQuickfixProvider_changeToConst_name) + } } From 386c9d39ace8571890e825123e21d6ce6a7330f9 Mon Sep 17 00:00:00 2001 From: Fernando Dodino Date: Mon, 11 Nov 2019 08:04:09 -0300 Subject: [PATCH 114/133] Game test cases moved to wollok-language | Wollok scripts installation renamed (back to soft links in Linux) --- .travis.yml | 2 +- appveyor.yml | 2 +- .../project/wollok/tests/sdk/GameTest.xtend | 168 +--------------- .../wollok/tests/sdk/PositionTest.xtend | 181 ++---------------- wollok-language | 2 +- install.bat => wollokInstall.bat | 0 install.sh => wollokInstall.sh | 2 +- 7 files changed, 17 insertions(+), 340 deletions(-) rename install.bat => wollokInstall.bat (100%) mode change 100644 => 100755 rename install.sh => wollokInstall.sh (65%) diff --git a/.travis.yml b/.travis.yml index 11c1ef56ad..378efc22eb 100644 --- a/.travis.yml +++ b/.travis.yml @@ -17,7 +17,7 @@ after_success: cd .. fi script: -- "./install.sh" +- "./wollokInstall.sh" - cd org.uqbar.project.wollok.releng/ - export PROFILES=normalProfile - export UPDATE_SITE=none diff --git a/appveyor.yml b/appveyor.yml index cbd806b411..93e52eb72c 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -2,7 +2,7 @@ version: '{build}' os: Windows Server 2012 install: - cd %APPVEYOR_BUILD_FOLDER% - - install.bat + - wollokInstall.bat - ps: | Add-Type -AssemblyName System.IO.Compression.FileSystem if (!(Test-Path -Path "C:\maven" )) { diff --git a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/sdk/GameTest.xtend b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/sdk/GameTest.xtend index bec46b7e0b..4853537a8f 100644 --- a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/sdk/GameTest.xtend +++ b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/sdk/GameTest.xtend @@ -7,58 +7,14 @@ import org.uqbar.project.wollok.tests.interpreter.AbstractWollokInterpreterTestC class GameTest extends AbstractWollokInterpreterTestCase { - var gameboard = Gameboard.getInstance + val gameboard = Gameboard.getInstance @Before def void init() { gameboard.clear } - @Test - def void canInstanceNewPosition() { - ''' - assert.equals(«position(1,2)», game.at(1,2)) - '''.test - } - - @Test - def void originShouldReturnOriginCoordinatePosition() { - ''' - assert.equals(«position(0,0)», game.origin()) - '''.test - } - - @Test - def void centerShouldReturnCenteredCoordinatePosition() { - ''' - game.width(2) - game.height(5) - assert.equals(«position(1,2)», game.center()) - '''.test - } - - @Test - def void shouldReturnVisualColliders() { - ''' - «position(0,0)».drawElement(myVisual) - 2.times{ i => «position(0,0)».drawElement(new Visual()) } - «position(0,1)».drawElement(new Visual()) - - assert.equals(2, game.colliders(myVisual).size()) - '''.gameTest - } - - @Test - def void shouldReturnUniqueCollider() { - ''' - «position(0,0)».drawElement(myVisual) - const otherVisual = new Visual() - «position(0,0)».drawElement(otherVisual) - - assert.equals(otherVisual, game.uniqueCollider(myVisual)) - '''.gameTest - } - + // Este test solo funciona internamente, no es posible llevarlo a wollok-language @Test def void movingCharacterShouldSetObjectPosition() { ''' @@ -70,123 +26,6 @@ class GameTest extends AbstractWollokInterpreterTestCase { '''.test } - @Test - def void addSameObjectToGameShouldFail() { - ''' - «position(0,0)».drawElement(myVisual) - assert.throwsExceptionWithMessage("myVisual[] is already in the game.", { «position(1,1)».drawElement(myVisual) }) - '''.gameTest - } - - @Test - def void addVisualUsingNullMustFail() { - ''' - assert.throwsExceptionWithMessage("Operation addVisual doesn't support null parameters", { => game.addVisual(null) }) - '''.test - } - - @Test - def void addVisualInUsingNullMustFail() { - ''' - assert.throwsExceptionWithMessage("Operation addVisualIn doesn't support null parameters", { => game.addVisualIn(null, null) }) - '''.test - } - - @Test - def void collidersUsingNullMustFail() { - ''' - assert.throwsExceptionWithMessage("Operation colliders doesn't support null parameters", { => game.colliders(null) }) - '''.test - } - - @Test - def void onTickUsingNullMustFail() { - ''' - assert.throwsExceptionWithMessage("Operation onTick doesn't support null parameters", { => game.onTick(null, null, null) }) - '''.test - } - - @Test - def void whenKeyPressedDoUsingNullMustFail() { - ''' - assert.throwsExceptionWithMessage("Operation whenKeyPressedDo doesn't support null parameters", { => game.whenKeyPressedDo(null, null) }) - '''.test - } - - @Test - def void whenAddingAnObjectAndCheckingIfItIsInTheBoardItReturnsTrue() { - ''' - import wollok.game.* - - object myVisual { } - - program a { - game.addVisualIn(myVisual, game.at(0, 0)) - assert.that(game.hasVisual(myVisual)) - } - '''.interpretPropagatingErrors - } - - @Test - def void whenAddingAnObjectAndCheckingIfOtherIsInTheBoardItReturnsFalse() { - ''' - import wollok.game.* - - object myVisual { } - object myVisual2 { } - - program a { - game.addVisualIn(myVisual, game.at(0, 0)) - assert.notThat(game.hasVisual(myVisual2)) - } - '''.interpretPropagatingErrors - } - - @Test - def void whenNoObjectIsAddedAndGetAllVisualsItReturnsNoElement() { - ''' - import wollok.game.* - - program a { - assert.equals(0, game.allVisuals().size()) - } - '''.interpretPropagatingErrors - } - - @Test - def void whenAddingAnObjectAndGettingAllVisualsItReturnsOneElement() { - ''' - import wollok.game.* - - object myVisual { } - - program a { - game.addVisualIn(myVisual, game.at(0, 0)) - assert.equals(1, game.allVisuals().size()) - assert.equals(myVisual, game.allVisuals().get(0)) - } - '''.interpretPropagatingErrors - } - - @Test - def void whenAddingSomeObjectAndGettingAllVisualsItReturnsAllTheAddedElements() { - ''' - import wollok.game.* - - object myVisual { } - object myVisual2 { } - object myVisual3 { } - - program a { - game.addVisualIn(myVisual, game.at(0, 0)) - game.addVisualIn(myVisual2, game.at(0, 0)) - game.addVisualIn(myVisual3, game.at(0, 0)) - assert.equals(3, game.allVisuals().size()) - assert.equals([myVisual, myVisual2, myVisual3].asSet(), game.allVisuals().asSet()) - } - '''.interpretPropagatingErrors - } - def gameTest(CharSequence test) { ''' import wollok.game.* @@ -204,7 +43,4 @@ class GameTest extends AbstractWollokInterpreterTestCase { '''.interpretPropagatingErrors } - private def position(int x, int y) { - '''new Position(x = «x», y = «y»)''' - } } diff --git a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/sdk/PositionTest.xtend b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/sdk/PositionTest.xtend index 80f5a543bf..b55caccab6 100644 --- a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/sdk/PositionTest.xtend +++ b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/sdk/PositionTest.xtend @@ -4,7 +4,6 @@ import org.junit.Before import org.junit.Test import org.junit.runners.Parameterized.Parameter import org.junit.runners.Parameterized.Parameters -import org.uqbar.project.wollok.game.WGPosition import org.uqbar.project.wollok.game.gameboard.Gameboard import org.uqbar.project.wollok.lib.WollokConventionExtensions import org.uqbar.project.wollok.tests.base.AbstractWollokParameterizedInterpreterTest @@ -20,161 +19,13 @@ class PositionTest extends AbstractWollokParameterizedInterpreterTest { var position = "new Position(x = 0, y = 0)" var gameboard = Gameboard.getInstance - + @Before def void init() { gameboard.clear } - @Test - def void canInstancePosition() { - ''' - var p = «position» - '''.test - } - - @Test - def void equalityByCoordinates() { - ''' - assert.equals(new Position(x = 0, y = 0), «position») - '''.test - } - - @Test - def void testToString() { - ''' - assert.equals("(0,0)", «position».toString()) - '''.test - } - - @Test - def void distanceUsingNull() { - ''' - assert.throwsExceptionWithMessage("Operation distance doesn't support null parameters", { => new Position(x = 1, y = 2).distance(null) }) - '''.test - } - - @Test - def void testDistance() { - ''' - assert.equals(5, «position».distance(new Position(x = 3, y = 4))) - '''.test - } - - @Test - def void shouldDrawVisualObjectsInBoard() { - assertEquals(0, components.size) - - ''' - «visualObjectWithoutPosition» - program p { - «position».drawElement(visual) - }'''.interpretPropagatingErrors - - assertEquals(1, components.size) - } - - @Test - def void positionCanBeAccessedByGetterMethod() { - ''' - import wollok.game.* - - object aVisual { - method «convention»() = «position» - «imageMethod» - } - - object otherVisual { - method «convention»() = «position» - «imageMethod» - } - - program p { - game.addVisual(aVisual) - game.addVisual(otherVisual) - }'''.interpretPropagatingErrors - - validatePosition - } - - @Test - def void positionCanBeAccessedByProperty() { - ''' - import wollok.game.* - - object visual { - var property «convention» = «position» - «imageMethod» - } - - program p { - game.addVisual(visual) - }'''.interpretPropagatingErrors - - validatePosition - } - - @Test - def void positionCannotBeAccessedByAttribute() { - ''' - import wollok.game.* - - object visual { - var «convention» = «position» - «imageMethod» - } - - program p { - assert.throwsExceptionWithMessage("visual[position=a Position[x=0, y=0]] does not understand position()", { game.addVisual(visual) }) - }'''.interpretPropagatingErrors - } - - @Test - def void visualsWithoutPositionCantBeRendered() { - ''' - «visualObjectWithoutPosition» - program p { - assert.throwsException{ game.addVisual(visual) } - }'''.interpretPropagatingErrors - } - - @Test - def void positionsCanDrawVisualsWithoutPosition() { - ''' - «visualObjectWithoutPosition» - program p { - var position = «position» - position.drawElement(visual) - var expected = position.allElements().head() - assert.equals(expected, visual) - }'''.interpretPropagatingErrors - } - - @Test - def void whenClearShouldRemoveAllVisualsInIt() { - ''' - import wollok.game.* - - class Visual { - «imageMethod» - } - - program p { - 2.times{ i => «position».drawElement(new Visual()) } - new Position(x = 1, y = 1).drawElement(new Visual()) - }'''.interpretPropagatingErrors - - assertEquals(3, gameboard.components.size) - ''' - import wollok.game.* - - program p { - «position».clear() - }'''.interpretPropagatingErrors - - assertEquals(1, gameboard.components.size) - } - + // Este test solo funciona internamente, no es posible llevarlo a wollok-language @Test def void sayShouldAddBallonMessageToVisualObject() { var message = "A message" @@ -185,33 +36,23 @@ class PositionTest extends AbstractWollokParameterizedInterpreterTest { position.drawCharacter(visual) position.say(visual, "«message»") }'''.interpretPropagatingErrors - + assertEquals(message, gameboard.character.balloonMessages.head.text) } - - def validatePosition() { - components.forEach[ - assertEquals(new WGPosition(0,0), it.position) - ] - } - - def components() { - gameboard.components - } - + def visualObjectWithoutPosition() { ''' - import wollok.game.* - - object visual { - «imageMethod» - } + import wollok.game.* + + object visual { + «imageMethod» + } ''' } - + def imageMethod() { ''' - method getImage() = "image.png" + method getImage() = "image.png" ''' } } diff --git a/wollok-language b/wollok-language index 074af4d859..54fd16ef1c 160000 --- a/wollok-language +++ b/wollok-language @@ -1 +1 @@ -Subproject commit 074af4d859dbc84666b10c9fa2e1ffa3f6f9de98 +Subproject commit 54fd16ef1c849c7929b09ffb780ff7b1e65f8980 diff --git a/install.bat b/wollokInstall.bat old mode 100644 new mode 100755 similarity index 100% rename from install.bat rename to wollokInstall.bat diff --git a/install.sh b/wollokInstall.sh similarity index 65% rename from install.sh rename to wollokInstall.sh index 94368e0b88..5ff13487dc 100755 --- a/install.sh +++ b/wollokInstall.sh @@ -1,4 +1,4 @@ #!/bin/bash git submodule update --init --recursive cd org.uqbar.project.wollok.lib/src/wollok -ln ../../../wollok-language/src/wollok/*.wlk ./ +ln -s ../../../wollok-language/src/wollok/*.wlk ./ From 46a2b3ccb48151fa362da0b90fd64ac565aa55d2 Mon Sep 17 00:00:00 2001 From: Fernando Dodino Date: Mon, 11 Nov 2019 22:46:25 -0300 Subject: [PATCH 115/133] Fix Wollok-TS implementation in wollok-language --- org.uqbar.project.wollok.lib/src/wollok/lang/WDictionary.xtend | 2 ++ wollok-language | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/org.uqbar.project.wollok.lib/src/wollok/lang/WDictionary.xtend b/org.uqbar.project.wollok.lib/src/wollok/lang/WDictionary.xtend index 6046295276..fffd819607 100644 --- a/org.uqbar.project.wollok.lib/src/wollok/lang/WDictionary.xtend +++ b/org.uqbar.project.wollok.lib/src/wollok/lang/WDictionary.xtend @@ -24,6 +24,8 @@ class WDictionary implements JavaWrapper> { wrapped = new TreeMap(new WollokObjectComparator) } + def void initialize() {} + def void clear() { wrapped.clear } diff --git a/wollok-language b/wollok-language index 54fd16ef1c..cab19d8024 160000 --- a/wollok-language +++ b/wollok-language @@ -1 +1 @@ -Subproject commit 54fd16ef1c849c7929b09ffb780ff7b1e65f8980 +Subproject commit cab19d8024f267718c514a00e2e0e07f7390065d From dc21f299f3b3ab2138dee122905fbc95f4fdcfa4 Mon Sep 17 00:00:00 2001 From: Fernando Dodino Date: Mon, 11 Nov 2019 23:31:38 -0300 Subject: [PATCH 116/133] Fix Wollok unification --- .../wollok/tests/xpect/Issue1284_VariableInitialization.wlk.xt | 2 +- wollok-language | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/xpect/Issue1284_VariableInitialization.wlk.xt b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/xpect/Issue1284_VariableInitialization.wlk.xt index 70088d1261..4910928a53 100644 --- a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/xpect/Issue1284_VariableInitialization.wlk.xt +++ b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/xpect/Issue1284_VariableInitialization.wlk.xt @@ -15,7 +15,7 @@ class Producto { self.precioRegular(valor1 + valor2) } - method initialize() { + override method initialize() { self.initialize(0) } diff --git a/wollok-language b/wollok-language index cab19d8024..e41e79f596 160000 --- a/wollok-language +++ b/wollok-language @@ -1 +1 @@ -Subproject commit cab19d8024f267718c514a00e2e0e07f7390065d +Subproject commit e41e79f59627326d4f1f2d3dd35eec58ca842ff2 From 59c822630891958fb8dc36339fff9786ec254f72 Mon Sep 17 00:00:00 2001 From: nicovio Date: Tue, 12 Nov 2019 17:39:34 -0300 Subject: [PATCH 117/133] fix should be const warning --- .../uqbar/project/wollok/validation/WollokDslValidator.xtend | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/org.uqbar.project.wollok/src/org/uqbar/project/wollok/validation/WollokDslValidator.xtend b/org.uqbar.project.wollok/src/org/uqbar/project/wollok/validation/WollokDslValidator.xtend index 22c356315d..985e5e5789 100644 --- a/org.uqbar.project.wollok/src/org/uqbar/project/wollok/validation/WollokDslValidator.xtend +++ b/org.uqbar.project.wollok/src/org/uqbar/project/wollok/validation/WollokDslValidator.xtend @@ -895,7 +895,7 @@ class WollokDslValidator extends AbstractConfigurableDslValidator { @Check @CheckGroup(WollokCheckGroup.POTENTIAL_PROGRAMMING_PROBLEM) def variableSingleAssignmentShouldBeConst(WVariableDeclaration it) { - val assignments = variable.assignments + val assignments = variable.assignments(container) if (writeable && !isProperty && assignments.size === 1 && right !== null && !isGlobal) { warning(WollokDslValidator_VARIABLE_SHOULD_BE_CONST, it, WVARIABLE_DECLARATION__VARIABLE, WARNING_VARIABLE_SHOULD_BE_CONST) From b5a624bd287c40fa7fdea39e3b2365504f132d95 Mon Sep 17 00:00:00 2001 From: nicovio Date: Tue, 12 Nov 2019 18:06:34 -0300 Subject: [PATCH 118/133] add PR review changes --- .../ChangeVarToConstQuickFixTest.xtend | 38 ++++++++++-- .../tests/xpect/VariableShouldBeConst.wlk.xt | 62 +++++++++++++++++++ 2 files changed, 94 insertions(+), 6 deletions(-) diff --git a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/quickfix/ChangeVarToConstQuickFixTest.xtend b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/quickfix/ChangeVarToConstQuickFixTest.xtend index 727ed0e291..323e959165 100644 --- a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/quickfix/ChangeVarToConstQuickFixTest.xtend +++ b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/quickfix/ChangeVarToConstQuickFixTest.xtend @@ -56,6 +56,32 @@ class ChangeVarToConstQuickFixTest extends AbstractWollokQuickFixTestCase { '''] assertQuickfix(initial, result, Messages.WollokDslQuickfixProvider_changeToConst_name) } + + @Test + def testChangeVarToConstInLambda() { + val initial = #[''' + object anObject { + method shouldBeConst() { + return [ 1, 2 ].map{ numero => + var otroNumero = numero + 1 + return otroNumero + 10 + } + } + } + '''] + + val result = #[''' + object anObject { + method shouldBeConst() { + return [ 1, 2 ].map{ numero => + const otroNumero = numero + 1 + return otroNumero + 10 + } + } + } + '''] + assertQuickfix(initial, result, Messages.WollokDslQuickfixProvider_changeToConst_name) + } @Test def testChangeVarToConstInClass() { @@ -167,7 +193,7 @@ class ChangeVarToConstQuickFixTest extends AbstractWollokQuickFixTestCase { describe "Variable should be const" { var variable = 123 test "trivial" { - assert.notEquals(variable, 123) + assert.notEquals(variable, 123) } } '''] @@ -176,7 +202,7 @@ class ChangeVarToConstQuickFixTest extends AbstractWollokQuickFixTestCase { describe "Variable should be const" { const variable = 123 test "trivial" { - assert.notEquals(variable, 123) + assert.notEquals(variable, 123) } } '''] @@ -188,8 +214,8 @@ class ChangeVarToConstQuickFixTest extends AbstractWollokQuickFixTestCase { val initial = #[''' describe "Variable should be const" { test "trivial" { - var variable = 123 - assert.notEquals(variable, 123) + var variable = 123 + assert.notEquals(variable, 123) } } '''] @@ -197,8 +223,8 @@ class ChangeVarToConstQuickFixTest extends AbstractWollokQuickFixTestCase { val result = #[''' describe "Variable should be const" { test "trivial" { - const variable = 123 - assert.notEquals(variable, 123) + const variable = 123 + assert.notEquals(variable, 123) } } '''] diff --git a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/xpect/VariableShouldBeConst.wlk.xt b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/xpect/VariableShouldBeConst.wlk.xt index e5bf7a3c11..44ee54222c 100644 --- a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/xpect/VariableShouldBeConst.wlk.xt +++ b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/xpect/VariableShouldBeConst.wlk.xt @@ -95,3 +95,65 @@ mixin VariableWithSingleAssignmentAtInitializationNotRaisesWarningIfPropertyMixi return variable + constante } } + +object variableWithReassignmentInIfNotRaisesWarning { + var energia = 100 + + method volar(minutos) { + var minutosReales = minutos + if (1 > 2) { + minutosReales = 10 + } + energia -= minutosReales * 2 + } +} + +object variableWithReassignmentInIfNotRaisesWarning2 { + var energia = 100 + + method volar(minutos) { + var minutosReales = minutos + if (1 > 2) { + minutosReales = minutosReales + 2 + } + energia -= minutosReales * 2 + } +} + +object variableDefinedOutsideCatchWithReassignmentInCatchNotRaisesWarning { + var energia = 100 + + method volar(minutos) { + try { + var minutosReales = minutos + } catch e { + minutosReales = 10 + } + energia -= minutosReales * 2 + } +} + +object variableDefinedInCatchWithReassignmentNotRaisesWarning { + var energia = 100 + + method volar(minutos) { + try { + } catch e { + var minutosReales = minutos + minutosReales = 10 + console.println(minutosReales) + } + energia -= 10 + } +} + +object variableDefinedInLambdaWithReassignmentNotRaisesWarning { + + method volar() { + [ 1, 2 ].map{ numero => + // XPECT warnings --> "Variable should be const" at "otroNumero" + var otroNumero = numero + 1 + return otroNumero + 2 + } + } +} From e71824d46416db87bbdfea4cd91504a54fbbe138 Mon Sep 17 00:00:00 2001 From: alete89 Date: Tue, 12 Nov 2019 20:38:34 -0300 Subject: [PATCH 119/133] fix test MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Nicolás Viotti --- .../project/wollok/tests/xpect/VariableShouldBeConst.wlk.xt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/xpect/VariableShouldBeConst.wlk.xt b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/xpect/VariableShouldBeConst.wlk.xt index 44ee54222c..cbec94b6e7 100644 --- a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/xpect/VariableShouldBeConst.wlk.xt +++ b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/xpect/VariableShouldBeConst.wlk.xt @@ -126,10 +126,10 @@ object variableDefinedOutsideCatchWithReassignmentInCatchNotRaisesWarning { method volar(minutos) { try { var minutosReales = minutos + energia -= minutosReales * 2 } catch e { minutosReales = 10 } - energia -= minutosReales * 2 } } From 3d79190ad11bf26319274d57dc27896a7b3c8314 Mon Sep 17 00:00:00 2001 From: Fernando Dodino Date: Tue, 12 Nov 2019 22:04:32 -0300 Subject: [PATCH 120/133] Moving train example and image test cases to wollok-language --- .../interpreter/examples/TrenesTestCase.xtend | 20 ------ .../interpreter/language/RuntimeTest.xtend | 10 +-- .../tests/libraries/LoadLibraryTest.xtend | 13 ++-- .../project/wollok/tests/sdk/ImageTest.xtend | 6 ++ wollok-language | 2 +- .../src/wollok/examples/trenes/trenes.wlk | 62 ------------------- .../src/wollok/examples/trenes/workspace.wpgm | 52 ---------------- 7 files changed, 17 insertions(+), 148 deletions(-) delete mode 100644 org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/examples/TrenesTestCase.xtend delete mode 100644 wollok-tests/src/wollok/examples/trenes/trenes.wlk delete mode 100644 wollok-tests/src/wollok/examples/trenes/workspace.wpgm diff --git a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/examples/TrenesTestCase.xtend b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/examples/TrenesTestCase.xtend deleted file mode 100644 index 7084e4577a..0000000000 --- a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/examples/TrenesTestCase.xtend +++ /dev/null @@ -1,20 +0,0 @@ -package org.uqbar.project.wollok.tests.interpreter.examples - -import java.io.File -import org.junit.Test -import org.uqbar.project.wollok.tests.interpreter.AbstractWollokInterpreterTestCase - -/** - * Executes the "Trenes" example - * - * @author tesonep - */ -class TrenesTestCase extends AbstractWollokInterpreterTestCase { - val path = EXAMPLES_PROJECT_PATH + "/src/wollok/examples/trenes/workspace.wpgm" - - @Test - def void run() { - new File(path).interpretPropagatingErrors - } - -} \ No newline at end of file diff --git a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/language/RuntimeTest.xtend b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/language/RuntimeTest.xtend index 814bbe6fac..ee85225903 100644 --- a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/language/RuntimeTest.xtend +++ b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/language/RuntimeTest.xtend @@ -6,11 +6,11 @@ class RuntimeTest extends org.uqbar.project.wollok.tests.interpreter.AbstractWol @Test def void testInteractive() { ''' - import wollok.vm.runtime - - program p { - assert.notThat(runtime.isInteractive()) - } + import wollok.vm.runtime + + program p { + assert.notThat(runtime.isInteractive()) + } '''.interpretPropagatingErrors } } diff --git a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/libraries/LoadLibraryTest.xtend b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/libraries/LoadLibraryTest.xtend index 7e59093d69..f4c8359239 100644 --- a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/libraries/LoadLibraryTest.xtend +++ b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/libraries/LoadLibraryTest.xtend @@ -19,9 +19,8 @@ class LoadLibraryTest extends AbstractWollokInterpreterTestCase { '''.interpretPropagatingErrors } - - -/* probar cuando esté listo el problema de los directorios + + /* probar cuando esté listo el problema de los directorios @Test def void testInnerLocationObjectExist() { ''' @@ -32,8 +31,8 @@ class LoadLibraryTest extends AbstractWollokInterpreterTestCase { '''.interpretPropagatingErrors } - -*/ + */ + @Test def void nativeObjectInLibrary() { ''' @@ -46,8 +45,6 @@ class LoadLibraryTest extends AbstractWollokInterpreterTestCase { assert.notThat(f.value()) } '''.interpretPropagatingErrors - - } - + } \ No newline at end of file diff --git a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/sdk/ImageTest.xtend b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/sdk/ImageTest.xtend index ef450c9200..b2121ee5b4 100644 --- a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/sdk/ImageTest.xtend +++ b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/sdk/ImageTest.xtend @@ -9,6 +9,12 @@ import org.uqbar.project.wollok.game.gameboard.Gameboard import org.uqbar.project.wollok.game.Image import org.junit.Before +/** + * Nota de dodain + * + * Estos métodos no fueron enteramente reemplazados por su versión en wollok-language + * ya que validan parte de la implementación de image + */ class ImageTest extends AbstractWollokParameterizedInterpreterTest { @Parameter(0) public String convention diff --git a/wollok-language b/wollok-language index e41e79f596..6ac0ce1e74 160000 --- a/wollok-language +++ b/wollok-language @@ -1 +1 @@ -Subproject commit e41e79f59627326d4f1f2d3dd35eec58ca842ff2 +Subproject commit 6ac0ce1e744b6fc77eab51e3ec5ee7f41e569e51 diff --git a/wollok-tests/src/wollok/examples/trenes/trenes.wlk b/wollok-tests/src/wollok/examples/trenes/trenes.wlk deleted file mode 100644 index 0b30250263..0000000000 --- a/wollok-tests/src/wollok/examples/trenes/trenes.wlk +++ /dev/null @@ -1,62 +0,0 @@ -class Deposito { - const formaciones = [] - - method agregarFormacion(unTren) { formaciones.add(unTren) } - method vagonesMasPesados() { return formaciones.map { t => t.vagonMasPesado()} } -} - -class Tren { - const vagones = [] - const locomotoras = [] - - method agregarVagon(v) { vagones.add(v) } - method getCantidadPasajeros() = vagones.sum{v=> v.getCantidadPasajeros()} - method getCantidadVagonesLivianos() = vagones.count{v=> v.esLiviano()} - method getVelocidadMaxima() = locomotoras.min{l=> l.getVelocidadMaxima() }.getVelocidadMaxima() - method agregarLocomotora(loco) { locomotoras.add(loco) } - method esEficiente() = locomotoras.all{l=> l.esEficiente()} - method puedeMoverse() = self.arrastreUtilTotalLocomotoras() >= self.pesoMaximoTotalDeVagones() - method arrastreUtilTotalLocomotoras() = locomotoras.sum {l=> l.arrastreUtil() } - method pesoMaximoTotalDeVagones() = vagones.sum{v=> v.getPesoMaximo()} - method getKilosEmpujeFaltantes() = - if (self.puedeMoverse()) - 0 - else - self.pesoMaximoTotalDeVagones() - self.arrastreUtilTotalLocomotoras() - method vagonMasPesado() = vagones.max({v=> v.getPesoMaximo() }) -} - -class Locomotora { - var peso - var pesoMaximoArrastre - var velocidadMaxima - method getVelocidadMaxima() = velocidadMaxima - - method esEficiente() = pesoMaximoArrastre >= 5 * peso - method arrastreUtil() = pesoMaximoArrastre - peso -} - -class Vagon { - method esLiviano() = self.getPesoMaximo() < 2500 - method getCantidadPasajeros() - method getPesoMaximo() -} - -class VagonPasajeros inherits Vagon { - var ancho - var largo - - override method getCantidadPasajeros() { - return largo * if (ancho < 2.5) 8 else 10 - } - override method getPesoMaximo() { - return self.getCantidadPasajeros() * 80 - } -} - -class VagonCarga inherits Vagon { - var cargaMaxima - override method getCantidadPasajeros() = 0 - override method getPesoMaximo() = cargaMaxima + 160 -} - diff --git a/wollok-tests/src/wollok/examples/trenes/workspace.wpgm b/wollok-tests/src/wollok/examples/trenes/workspace.wpgm deleted file mode 100644 index 5b6a5070f0..0000000000 --- a/wollok-tests/src/wollok/examples/trenes/workspace.wpgm +++ /dev/null @@ -1,52 +0,0 @@ -import trenes.* - -// 1) -program trenes { - - const tren = new Tren() - tren.agregarVagon(new VagonPasajeros(ancho = 2, largo = 10)) - assert.equals(80, tren.getCantidadPasajeros()) - - tren.agregarVagon(new VagonPasajeros(ancho = 3, largo = 10)) - assert.equals(180, tren.getCantidadPasajeros()) - - tren.agregarVagon(new VagonCarga(cargaMaxima = 1000)) - assert.equals(180, tren.getCantidadPasajeros()) - - // 2) Cuántos vagones livianos tiene una formación; - assert.equals(1, tren.getCantidadVagonesLivianos()) // el de carga - - - // 3) La velocidad máxima de una formación, - tren.agregarLocomotora(new Locomotora(peso = 1020, pesoMaximoArrastre = 8100, velocidadMaxima = 60)) // de 60 kpm - tren.agregarLocomotora(new Locomotora(peso = 1400, pesoMaximoArrastre = 10000,velocidadMaxima = 75)) // de 60 kpm - - assert.equals(60, tren.getVelocidadMaxima()) - - // 4) Si una formación es eficiente; - assert.that(new Locomotora(peso = 10, pesoMaximoArrastre = 50, velocidadMaxima = 0).esEficiente()) - assert.that(new Locomotora(peso = 10, pesoMaximoArrastre = 51, velocidadMaxima = 0).esEficiente()) - assert.notThat(new Locomotora(peso = 10, pesoMaximoArrastre = 49, velocidadMaxima = 0).esEficiente()) - - assert.that(tren.esEficiente()) - - // 5) Si una formación puede moverse. - assert.that(tren.puedeMoverse()) - - // 6) Cuántos kilos de empuje le faltan a una formación para poder moverse, - assert.equals(0, tren.getKilosEmpujeFaltantes()) - - const trenNoSeMueve = new Tren() - trenNoSeMueve.agregarVagon(new VagonPasajeros(ancho = 3, largo = 12)) - trenNoSeMueve.agregarLocomotora(new Locomotora(peso = 1200, pesoMaximoArrastre = 4000, velocidadMaxima = 55)) - assert.notThat(trenNoSeMueve.puedeMoverse()) - assert.equals(6800, trenNoSeMueve.getKilosEmpujeFaltantes()) - - // 7) Dado un depósito, obtener el conjunto formado por el vagón más pesado de cada formación; - - const deposito = new Deposito() - deposito.agregarFormacion(tren) - deposito.agregarFormacion(trenNoSeMueve) - - assert.equals(2, deposito.vagonesMasPesados().size()) -} \ No newline at end of file From 45416ffeaba12919d2542d10adf30007986abd66 Mon Sep 17 00:00:00 2001 From: Fernando Dodino Date: Wed, 13 Nov 2019 19:22:29 -0300 Subject: [PATCH 121/133] Moving wollok-examples to wollok-language --- .../wollok/tests/natives/NativeTestCase.xtend | 5 + wollok-language | 2 +- wollok-tests/src/basic/1.1_booleans.wpgm | 84 ------------- wollok-tests/src/basic/1.2_console.wpgm | 22 ---- .../src/basic/10_collection_literals.wpgm | 54 -------- .../src/basic/1_variables_and_numbers.wpgm | 46 ------- wollok-tests/src/basic/2_object_literals.wpgm | 33 ----- wollok-tests/src/basic/3_polymorphism.wpgm | 23 ---- .../basic/4_objectliteral_as_parameter.wpgm | 17 --- .../src/basic/5_var_ref_vs_methodcall.wpgm | 28 ----- wollok-tests/src/basic/6_custom_toString.wpgm | 11 -- .../src/basic/7_operator_overloading.wpgm | 12 -- wollok-tests/src/basic/9_closures.wpgm | 25 ---- wollok-tests/src/basic/if.wpgm | 24 ---- wollok-tests/src/basic/localVarInMethod.wlk | 6 - wollok-tests/src/basic/namedObjects.wpgm | 7 -- wollok-tests/src/basic/namedObjectsLib.wlk | 26 ---- .../src/basic/operatorOverloading.wtest | 10 ++ wollok-tests/src/bugs/b40.wlk | 38 ------ wollok-tests/src/bugs/b40.wtest | 5 - wollok-tests/src/bugs/b44.wtest | 7 -- wollok-tests/src/bugs/recursiveToString.wpgm | 25 ---- .../src/wollok/classes/basics/simpleClass.wlk | 22 ---- .../classes/basics/simpleClass_program.wpgm | 19 --- .../classes/basics/simpleInheritance.wlk | 13 -- .../basics/simpleInheritance_program.wpgm | 7 -- .../wollok/classes/basics/templateMethod.wlk | 16 --- .../basics/templateMethod_program.wpgm | 13 -- .../src/wollok/classes/basics/zuper.wlk | 27 ---- .../classes/constructors/constructors.wpgm | 7 -- .../classes/constructors/constructorsLib.wlk | 22 ---- .../wollok/classes/constructors/info.showcase | 4 - .../src/wollok/classes/mixins/mixins.wtest | 118 ------------------ .../src/wollok/classes/natives/info.showcase | 4 - .../classes/natives/sample_program.wpgm | 16 --- .../src/wollok/classes/natives/wollok.wlk | 11 -- .../classes/natives/wollok/MyNative.class | Bin 320 -> 0 bytes .../classes/natives/wollok/MyNative.java | 12 -- .../src/wollok/debugger/printing.wpgm | 21 ---- .../src/wollok/debugger/withClasses.wpgm | 8 -- .../src/wollok/debugger/withClassesLib.wlk | 8 -- .../wollok/examples/tomyjerry/tomyjerry.wpgm | 41 ------ .../src/wollok/exceptions/exceptions.wpgm | 24 ---- .../src/wollok/exceptions/exceptionsLib.wlk | 19 --- wollok-tests/src/wollok/imports/importing.wlk | 5 - .../src/wollok/imports/packageA/file1.wlk | 3 - .../src/wollok/imports/packageB/file2.wlk | 5 - wollok-tests/src/wollok/imports/wollok.root | 0 wollok-tests/src/wollok/lang/exceptions.wlk | 7 -- wollok-tests/src/wollok/tests/test.wtest | 17 --- 50 files changed, 16 insertions(+), 963 deletions(-) delete mode 100644 wollok-tests/src/basic/1.1_booleans.wpgm delete mode 100644 wollok-tests/src/basic/1.2_console.wpgm delete mode 100644 wollok-tests/src/basic/10_collection_literals.wpgm delete mode 100644 wollok-tests/src/basic/1_variables_and_numbers.wpgm delete mode 100644 wollok-tests/src/basic/2_object_literals.wpgm delete mode 100644 wollok-tests/src/basic/3_polymorphism.wpgm delete mode 100644 wollok-tests/src/basic/4_objectliteral_as_parameter.wpgm delete mode 100644 wollok-tests/src/basic/5_var_ref_vs_methodcall.wpgm delete mode 100644 wollok-tests/src/basic/6_custom_toString.wpgm delete mode 100644 wollok-tests/src/basic/7_operator_overloading.wpgm delete mode 100644 wollok-tests/src/basic/9_closures.wpgm delete mode 100644 wollok-tests/src/basic/if.wpgm delete mode 100644 wollok-tests/src/basic/localVarInMethod.wlk delete mode 100644 wollok-tests/src/basic/namedObjects.wpgm delete mode 100644 wollok-tests/src/basic/namedObjectsLib.wlk create mode 100644 wollok-tests/src/basic/operatorOverloading.wtest delete mode 100644 wollok-tests/src/bugs/b40.wlk delete mode 100644 wollok-tests/src/bugs/b40.wtest delete mode 100644 wollok-tests/src/bugs/b44.wtest delete mode 100644 wollok-tests/src/bugs/recursiveToString.wpgm delete mode 100644 wollok-tests/src/wollok/classes/basics/simpleClass.wlk delete mode 100644 wollok-tests/src/wollok/classes/basics/simpleClass_program.wpgm delete mode 100644 wollok-tests/src/wollok/classes/basics/simpleInheritance.wlk delete mode 100644 wollok-tests/src/wollok/classes/basics/simpleInheritance_program.wpgm delete mode 100644 wollok-tests/src/wollok/classes/basics/templateMethod.wlk delete mode 100644 wollok-tests/src/wollok/classes/basics/templateMethod_program.wpgm delete mode 100644 wollok-tests/src/wollok/classes/basics/zuper.wlk delete mode 100644 wollok-tests/src/wollok/classes/constructors/constructors.wpgm delete mode 100644 wollok-tests/src/wollok/classes/constructors/constructorsLib.wlk delete mode 100644 wollok-tests/src/wollok/classes/constructors/info.showcase delete mode 100644 wollok-tests/src/wollok/classes/mixins/mixins.wtest delete mode 100644 wollok-tests/src/wollok/classes/natives/info.showcase delete mode 100644 wollok-tests/src/wollok/classes/natives/sample_program.wpgm delete mode 100644 wollok-tests/src/wollok/classes/natives/wollok.wlk delete mode 100644 wollok-tests/src/wollok/classes/natives/wollok/MyNative.class delete mode 100644 wollok-tests/src/wollok/classes/natives/wollok/MyNative.java delete mode 100644 wollok-tests/src/wollok/debugger/printing.wpgm delete mode 100644 wollok-tests/src/wollok/debugger/withClasses.wpgm delete mode 100644 wollok-tests/src/wollok/debugger/withClassesLib.wlk delete mode 100644 wollok-tests/src/wollok/examples/tomyjerry/tomyjerry.wpgm delete mode 100644 wollok-tests/src/wollok/exceptions/exceptions.wpgm delete mode 100644 wollok-tests/src/wollok/exceptions/exceptionsLib.wlk delete mode 100644 wollok-tests/src/wollok/imports/importing.wlk delete mode 100644 wollok-tests/src/wollok/imports/packageA/file1.wlk delete mode 100644 wollok-tests/src/wollok/imports/packageB/file2.wlk delete mode 100644 wollok-tests/src/wollok/imports/wollok.root delete mode 100644 wollok-tests/src/wollok/lang/exceptions.wlk delete mode 100644 wollok-tests/src/wollok/tests/test.wtest diff --git a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/natives/NativeTestCase.xtend b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/natives/NativeTestCase.xtend index fa181ab34e..4baf647065 100644 --- a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/natives/NativeTestCase.xtend +++ b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/natives/NativeTestCase.xtend @@ -4,6 +4,11 @@ import org.junit.Test import org.uqbar.project.wollok.tests.interpreter.AbstractWollokInterpreterTestCase /** + * + * If you want to run this test, you have to copy `wollok` folder with MyNative Java + * definitions into your `src` folder (or any other source folder that belongs to the + * classpath) + * * @author jfernandes */ class NativeTestCase extends AbstractWollokInterpreterTestCase { diff --git a/wollok-language b/wollok-language index 6ac0ce1e74..e02bee3e10 160000 --- a/wollok-language +++ b/wollok-language @@ -1 +1 @@ -Subproject commit 6ac0ce1e744b6fc77eab51e3ec5ee7f41e569e51 +Subproject commit e02bee3e10d222f41b25acd0a7d6a3c79ab09ed4 diff --git a/wollok-tests/src/basic/1.1_booleans.wpgm b/wollok-tests/src/basic/1.1_booleans.wpgm deleted file mode 100644 index b8f3b3a39f..0000000000 --- a/wollok-tests/src/basic/1.1_booleans.wpgm +++ /dev/null @@ -1,84 +0,0 @@ -// ************ -// BOOLEANS -program booleans { - - -const trueB = true -var a = "a" -// a = 1 // FAILS OK! - -assert.that(trueB) - -assert.that(true) -assert.notThat(false) - -//AND -assert.that(true and true) -assert.that(true && true) - -assert.notThat(true and false) -assert.notThat(true && false) - -assert.notThat(false && true) -assert.notThat(false && false) - -// or -assert.that(true or true) -assert.that(true || true) - -assert.that(true || false) -assert.that(false || true) - -assert.notThat(false or false) -assert.notThat(false || false) - -// not operator - -assert.that(not false) -assert.that(!false) - -assert.notThat(not true) -assert.notThat(!true) - -assert.that(not(3>5)) -assert.that(!(3>5)) - -// equals -assert.that(2 == 2) -var n1 = 2 -var n2 = 2 -assert.that(n1 == n2) -assert.notThat(2 == 3) - -const object1 = object {} -const object2 = object {} -assert.that(object1 == object1) -assert.notThat(object1 == object2) - -// not equals -assert.that(2 != 3) - -//// >, >=, <, <= -assert.that(2 < 3) -assert.that(2 <= 3) -assert.that(2 <= 2) - -assert.that(3 > 2) -assert.that(3 >= 1) -assert.that(3 >= 3) - - -// ************************** -// ** errores de tipos (PASAR A UN XPect) -// ************************** - -//const unN = 2 -//const otroN = 4 -// -//const unoYotro = unN && otroN -//const otraComp = true && otroN -// -//const compValida = true && false -//console.println(compValida) - -} \ No newline at end of file diff --git a/wollok-tests/src/basic/1.2_console.wpgm b/wollok-tests/src/basic/1.2_console.wpgm deleted file mode 100644 index a08176f162..0000000000 --- a/wollok-tests/src/basic/1.2_console.wpgm +++ /dev/null @@ -1,22 +0,0 @@ -program console { -// const console = self // TODO esto debería volar - - // console es un objeto que me permite escribir en pantalla - // otros objetos útiles son los strings - console.println("Hello Wollok !!!") - console.println(1) - - // Los números también son objetos - console.println(1+2) - - // Las constantes y variables me sirven para guardarme 'referencias' a un objeto - const x = 2 - console.println(x) - - const y = 3 - var z = 0 - console.println(z) - - z = x + y - console.println(z) -} diff --git a/wollok-tests/src/basic/10_collection_literals.wpgm b/wollok-tests/src/basic/10_collection_literals.wpgm deleted file mode 100644 index e2aeeb61c2..0000000000 --- a/wollok-tests/src/basic/10_collection_literals.wpgm +++ /dev/null @@ -1,54 +0,0 @@ -program collections { - const numbers = [2, 23, 25] - - const y = 23 - const z = 2.2 - - const x = "Hola" - const bag = [x,y,z] - - // *************************** - // ** calling native methods - // *************************** - - // size (a forwarded message to java.util.List) - assert.equals(3, numbers.size()) - assert.that(numbers.contains(23)) - assert.notThat(numbers.contains(1)) - - // all - assert.that([20, 22, 34].all({n => n > 18})) - assert.notThat([20, 22, 34].all({n => n > 30})) - - // forEach - const vaca1 = object { - var peso = 1000 - method engordar(cuanto) { - peso = peso + cuanto - } - method peso() = peso - } - - const vaca2 = object { - var peso = 1000 - method engordar(cuanto) { - peso = peso + cuanto - } - method peso() = peso - } - const vacas = [vaca1, vaca2] - - vacas.forEach{v => v.engordar(2)} - assert.that(vacas.all{v => v.peso() == 1002}) - - // map - const mapped = vacas.map{v => v.peso()} - assert.that(mapped.all{p => p == 1002}) - - // filter - const r = [10, 20, 30, 40, 50].filter{n=> n > 30} - assert.that(r.size() == 2) - assert.that(r.contains(40)) - assert.that(r.contains(50)) - -} \ No newline at end of file diff --git a/wollok-tests/src/basic/1_variables_and_numbers.wpgm b/wollok-tests/src/basic/1_variables_and_numbers.wpgm deleted file mode 100644 index 8c09e3e66e..0000000000 --- a/wollok-tests/src/basic/1_variables_and_numbers.wpgm +++ /dev/null @@ -1,46 +0,0 @@ -program variablesAndNumbers { - - // values - const a = 23 - const b = a + 1 - - //const y = a + "23" - - //b = 23 //CANNOT MODIFY VALUES! - - // variables - var c = 23 - c = 24 //OK! - - assert.that(b == 24) - - assert.that(10 - 5 == 5) - assert.that(10 * a == 230) - assert.that(100 / 10 == 10) - assert.that(100 % 10 == 0) - assert.that(2 ** 4 == 16.0) - assert.equals(16.0, 2**4) - - assert.that(2 * 2.0 == 2.0 * 2) - assert.that(2 + 2.0 == 2.0 + 2) - - assert.equals(0 - 1, -1) - assert.equals(0 - 4, -4) - - var d = 1 - d++ - assert.equals(2, d) - - d-- - assert.equals(1, d) - - d += 3 - assert.equals(4, d) - - d -= 1 - assert.equals(3, d) - - d *= 2 - assert.equals(6, d) - -} \ No newline at end of file diff --git a/wollok-tests/src/basic/2_object_literals.wpgm b/wollok-tests/src/basic/2_object_literals.wpgm deleted file mode 100644 index a18248055b..0000000000 --- a/wollok-tests/src/basic/2_object_literals.wpgm +++ /dev/null @@ -1,33 +0,0 @@ -program objectLiterals { - - var pepita = object { - var energia = 120 - - method comer(cuanto) { - energia = energia + cuanto - } - method energia() { - return energia - } - method algoConPerro(perro) { - perro.ladrar() - perro.ladrar() - perro.saltar() - } - } - - pepita.comer(5) - assert.that(pepita.energia() == 125) - - // assignments to check type system - //pepita = 23 // FAIL (OK) - - pepita = object { - method comer(cuanto) {} - method energia() {} - method algoConPerro(p) { - p.echate() - } - } - -} \ No newline at end of file diff --git a/wollok-tests/src/basic/3_polymorphism.wpgm b/wollok-tests/src/basic/3_polymorphism.wpgm deleted file mode 100644 index a8d5ede979..0000000000 --- a/wollok-tests/src/basic/3_polymorphism.wpgm +++ /dev/null @@ -1,23 +0,0 @@ -program polymorphism { - - // golondrina pepona con energia - const pepona = object { - var energia = 100 - method comer(comida) { - energia = energia + comida.energia() - } - method energia() { return energia } - } - - /* el alpiste tambien tiene energia */ - const alpiste = object { - method energia() { - return 5 - } - } - - pepona.comer(alpiste) - - assert.that(pepona.energia() == 105) - -} \ No newline at end of file diff --git a/wollok-tests/src/basic/4_objectliteral_as_parameter.wpgm b/wollok-tests/src/basic/4_objectliteral_as_parameter.wpgm deleted file mode 100644 index 701e1f1cca..0000000000 --- a/wollok-tests/src/basic/4_objectliteral_as_parameter.wpgm +++ /dev/null @@ -1,17 +0,0 @@ -program objectLiteralsAsParameters { - -// 4to: polimorfismo con objeto literal como parametro - - const pepona = object { - var energia = 100 - method comer(comida) { - energia = energia + comida.energia() - } - method energia() = energia - } - - pepona.comer(object { method energia() = 100.0 }) - - assert.that(pepona.energia() == 200) - -} \ No newline at end of file diff --git a/wollok-tests/src/basic/5_var_ref_vs_methodcall.wpgm b/wollok-tests/src/basic/5_var_ref_vs_methodcall.wpgm deleted file mode 100644 index cbbe655957..0000000000 --- a/wollok-tests/src/basic/5_var_ref_vs_methodcall.wpgm +++ /dev/null @@ -1,28 +0,0 @@ -program varRefVsMethodCalls { - -// 5to diferenciar acceso a properties de methods - -const pepin = object { - var altura = 1.40 - - method crecer(cuanto) { - altura = altura + cuanto - } - - method ponerseZancos() { - self.crecer(0.2) - } - method altura() { - return altura - } -} - -assert.that(pepin.altura() == 1.4) - -pepin.crecer(0.1) -assert.that(pepin.altura() == 1.5) - -pepin.ponerseZancos() -assert.that(pepin.altura() == 1.7) - -} \ No newline at end of file diff --git a/wollok-tests/src/basic/6_custom_toString.wpgm b/wollok-tests/src/basic/6_custom_toString.wpgm deleted file mode 100644 index 3ff6e76ee9..0000000000 --- a/wollok-tests/src/basic/6_custom_toString.wpgm +++ /dev/null @@ -1,11 +0,0 @@ -program customToString { - - const pepe = object { - override method toString() { - return 'Pepe' - } - } - - assert.equals(pepe.toString(), 'Pepe') - -} \ No newline at end of file diff --git a/wollok-tests/src/basic/7_operator_overloading.wpgm b/wollok-tests/src/basic/7_operator_overloading.wpgm deleted file mode 100644 index 7f20e97668..0000000000 --- a/wollok-tests/src/basic/7_operator_overloading.wpgm +++ /dev/null @@ -1,12 +0,0 @@ -program operatorOverloading { - - -const sumable = object { - const value = 15 - method +(otro) = value + otro -} - -console.println(sumable + 15) -assert.that(sumable + 15 == 30) - -} \ No newline at end of file diff --git a/wollok-tests/src/basic/9_closures.wpgm b/wollok-tests/src/basic/9_closures.wpgm deleted file mode 100644 index 191d9712a6..0000000000 --- a/wollok-tests/src/basic/9_closures.wpgm +++ /dev/null @@ -1,25 +0,0 @@ -program closures { -// 1 param -const incrementClosure = {param => param + 1} -assert.that(incrementClosure.apply(2) == 3) - -// 2 params -const addition = {a, b => a + b} -assert.that(addition.apply(10, 15) == 25) - - -// using outside context VALUE -const n1 = 2 -const multiplyByN1 = {i=> i * n1} - -assert.that(multiplyByN1.apply(3) == 6) - - -// using outside context VARIABLE (mutating) -var n2 = 2 -const multiplyByN2 = {i=> i * n2} -n2 = 10 - -assert.equals(30,multiplyByN2.apply(3)) - -} \ No newline at end of file diff --git a/wollok-tests/src/basic/if.wpgm b/wollok-tests/src/basic/if.wpgm deleted file mode 100644 index 252098453c..0000000000 --- a/wollok-tests/src/basic/if.wpgm +++ /dev/null @@ -1,24 +0,0 @@ -class S { - method whatIf(x) { - return if (x % 2 == 0) - "even" - else - "odd" - } -} - -program ifs { - const number = 2 - const oddOrEven = if (number % 2 == 0) "even" else "odd" - - assert.that("even" == oddOrEven) - - assert.that("odd" == if (3 % 2 == 0) "even" else "odd") - - // now in a method - - const s = new S() - - assert.that("even" == s.whatIf(2)) - assert.that("odd" == s.whatIf(3)) -} \ No newline at end of file diff --git a/wollok-tests/src/basic/localVarInMethod.wlk b/wollok-tests/src/basic/localVarInMethod.wlk deleted file mode 100644 index 1a16217fe2..0000000000 --- a/wollok-tests/src/basic/localVarInMethod.wlk +++ /dev/null @@ -1,6 +0,0 @@ -class SampleClass { - method sampleMethod() { - var sampleLocal = "Yo Soy Cola " - sampleLocal = sampleLocal + "Tu Pegamento" - } -} \ No newline at end of file diff --git a/wollok-tests/src/basic/namedObjects.wpgm b/wollok-tests/src/basic/namedObjects.wpgm deleted file mode 100644 index e623331392..0000000000 --- a/wollok-tests/src/basic/namedObjects.wpgm +++ /dev/null @@ -1,7 +0,0 @@ -import namedObjectsLib.named_object_pepita - -program namedObjects{ - assert.equals(0, named_object_pepita.energyLevel()) - named_object_pepita.addEnergy(10) - assert.equals(10, named_object_pepita.energyLevel()) -} \ No newline at end of file diff --git a/wollok-tests/src/basic/namedObjectsLib.wlk b/wollok-tests/src/basic/namedObjectsLib.wlk deleted file mode 100644 index 79405fe6e5..0000000000 --- a/wollok-tests/src/basic/namedObjectsLib.wlk +++ /dev/null @@ -1,26 +0,0 @@ - -object named_object_pepita { - var energy = 0 - method energyLevel() { - return energy - } - - method addEnergy(amount) { - energy = energy + amount - } - - method retornoNull() { - return null - } - - method saludar() { - console.println("Hola") - } -} - -object foo { - method bar() { - console.println("") - console.println("") - } -} diff --git a/wollok-tests/src/basic/operatorOverloading.wtest b/wollok-tests/src/basic/operatorOverloading.wtest new file mode 100644 index 0000000000..074bb4f61e --- /dev/null +++ b/wollok-tests/src/basic/operatorOverloading.wtest @@ -0,0 +1,10 @@ +test "+ operator overloading" { + const sumable = object { + const value = 15 + method +(otro) = value + otro.valor() + } + const otroSumable = object { + method valor() = 10 + } + assert.equals(25, sumable + otroSumable) +} diff --git a/wollok-tests/src/bugs/b40.wlk b/wollok-tests/src/bugs/b40.wlk deleted file mode 100644 index e6e3ea98b4..0000000000 --- a/wollok-tests/src/bugs/b40.wlk +++ /dev/null @@ -1,38 +0,0 @@ -object pajarera { - var energiaMenor = 100 - var pajaros = [pepita, pepe] - method menorValor(){ - pajaros.forEach{a=>a.sosMenor(energiaMenor)} - return energiaMenor - } - - method setEnergiaMenor(valor){ - energiaMenor = valor - } -} - -object pepe { - method sosMenor(energiaMenor){ - pajarera.setEnergiaMenor(10) - } -} - -object pepita { - method sosMenor(energiaMenor){ - pajarera.setEnergiaMenor(25) - } -} - -class Arturo { - var energiaMenor = 100 - var pajaros = [pepita, pepe] - method menorValor(){ - pajaros.forEach{a => a.sosMenor(energiaMenor)} - return energiaMenor - } - - method setEnergiaMenor(valor){ - energiaMenor = valor - } -} - diff --git a/wollok-tests/src/bugs/b40.wtest b/wollok-tests/src/bugs/b40.wtest deleted file mode 100644 index 4044998868..0000000000 --- a/wollok-tests/src/bugs/b40.wtest +++ /dev/null @@ -1,5 +0,0 @@ -import b40.* - -test "regression of bug #40" { - assert.equals(10, pajarera.menorValor()) -} \ No newline at end of file diff --git a/wollok-tests/src/bugs/b44.wtest b/wollok-tests/src/bugs/b44.wtest deleted file mode 100644 index cfc12b2ffd..0000000000 --- a/wollok-tests/src/bugs/b44.wtest +++ /dev/null @@ -1,7 +0,0 @@ - -test "Testing regression of Bug #44" { - const aList = [ 1, 2, 3, 4 ] - const clone = aList.copy() - - assert.equals(aList.className(), clone.className()) -} \ No newline at end of file diff --git a/wollok-tests/src/bugs/recursiveToString.wpgm b/wollok-tests/src/bugs/recursiveToString.wpgm deleted file mode 100644 index 420c2e154d..0000000000 --- a/wollok-tests/src/bugs/recursiveToString.wpgm +++ /dev/null @@ -1,25 +0,0 @@ -object obj2 { - var y - method setY(anObject){ - y = anObject - } -} - -object obj1 { - var x = [] - method addX(anObject){ - x.add(anObject) - } -} - -class Prb { - -} - -program a { - obj1.addX(obj2) - obj2.setY(obj1) - obj1.addX(new Prb()) - - assert.equals('obj2[y=obj1[x=[obj2, a Prb[]]]]', obj2.toString()) -} \ No newline at end of file diff --git a/wollok-tests/src/wollok/classes/basics/simpleClass.wlk b/wollok-tests/src/wollok/classes/basics/simpleClass.wlk deleted file mode 100644 index 35b2cd042a..0000000000 --- a/wollok-tests/src/wollok/classes/basics/simpleClass.wlk +++ /dev/null @@ -1,22 +0,0 @@ -/** - * A package for sarasa - * - * @author jfernandes - */ -class Golondrina { - var energia = 50 /** Retorna la energia actual */ - method getEnergia() { - return energia - } - - /** Setea la energia */ - method setEnergia(e) { - energia = e - } - - /** Hace que vuele */ - method volar(kms) { - energia -= kms - } -} - diff --git a/wollok-tests/src/wollok/classes/basics/simpleClass_program.wpgm b/wollok-tests/src/wollok/classes/basics/simpleClass_program.wpgm deleted file mode 100644 index 0a7af482fc..0000000000 --- a/wollok-tests/src/wollok/classes/basics/simpleClass_program.wpgm +++ /dev/null @@ -1,19 +0,0 @@ -import simpleClass.Golondrina - -program simpleClass { - - const pepita = new Golondrina() - - var r = pepita.getEnergia() == 50 - assert.that(r) - - //// una segunda - // - const pepona = new Golondrina() - pepona.volar(2) - assert.equals(48, pepona.getEnergia()) - assert.equals(50, pepita.getEnergia()) // pepita no se altero - // - // - -} \ No newline at end of file diff --git a/wollok-tests/src/wollok/classes/basics/simpleInheritance.wlk b/wollok-tests/src/wollok/classes/basics/simpleInheritance.wlk deleted file mode 100644 index 37c58ddc16..0000000000 --- a/wollok-tests/src/wollok/classes/basics/simpleInheritance.wlk +++ /dev/null @@ -1,13 +0,0 @@ - class Ave { - var energia = 100 - - method energia( ) = energia - method setEnergia(newEnergia) { - energia = newEnergia - } - } - class Golondrina inherits Ave { - method volar(kms) { - self.setEnergia(self.energia() - kms) // Uso métodos de la superclase - } - } diff --git a/wollok-tests/src/wollok/classes/basics/simpleInheritance_program.wpgm b/wollok-tests/src/wollok/classes/basics/simpleInheritance_program.wpgm deleted file mode 100644 index 5554d293d9..0000000000 --- a/wollok-tests/src/wollok/classes/basics/simpleInheritance_program.wpgm +++ /dev/null @@ -1,7 +0,0 @@ -import simpleInheritance.* - -program simpleInheritance { - const pepita = new Golondrina() - pepita.volar(40) - assert.equals(pepita.energia(), 60) // Mando mensaje en superclase -} \ No newline at end of file diff --git a/wollok-tests/src/wollok/classes/basics/templateMethod.wlk b/wollok-tests/src/wollok/classes/basics/templateMethod.wlk deleted file mode 100644 index c7722dd802..0000000000 --- a/wollok-tests/src/wollok/classes/basics/templateMethod.wlk +++ /dev/null @@ -1,16 +0,0 @@ -class Golondrina { - var energia = 100 - - method energia() = energia - - method volar(kms) { - energia = energia - self.gastoParaVolar(kms) // Invocacion a método que se va a sobreescribir - } - - method gastoParaVolar(kms) = kms -} - -class NoSeCansa inherits Golondrina { - override method gastoParaVolar(kms) = 0 -} - diff --git a/wollok-tests/src/wollok/classes/basics/templateMethod_program.wpgm b/wollok-tests/src/wollok/classes/basics/templateMethod_program.wpgm deleted file mode 100644 index d2bf2b03df..0000000000 --- a/wollok-tests/src/wollok/classes/basics/templateMethod_program.wpgm +++ /dev/null @@ -1,13 +0,0 @@ -import templateMethod.* - -program templateMethod { - - const pepita = new Golondrina() - pepita.volar(50) - assert.that(pepita.energia() == 50) // Mismo comportamiento de siempre - - const pepona = new NoSeCansa() - pepona.volar(50) - assert.that(pepona.energia() == 100) // Mantiene energía inicial - -} \ No newline at end of file diff --git a/wollok-tests/src/wollok/classes/basics/zuper.wlk b/wollok-tests/src/wollok/classes/basics/zuper.wlk deleted file mode 100644 index 9c406e3857..0000000000 --- a/wollok-tests/src/wollok/classes/basics/zuper.wlk +++ /dev/null @@ -1,27 +0,0 @@ -package zuper { - - class Golondrina { - var energia = 100 - - method energia() = energia - - method volar(kms) { - energia = energia - self.gastoParaVolar(kms) // Invocacion a método que se va a sobreescribir - } - - method gastoParaVolar(kms) = kms - - method blah(a) { - self.gastoParaVolar(a) - // super(a) // FAIL OK ! - } - } - - class SeCansaMucho inherits Golondrina { - override method gastoParaVolar(kms) { - const r = super(kms) - return 2 * r - } - } - -} \ No newline at end of file diff --git a/wollok-tests/src/wollok/classes/constructors/constructors.wpgm b/wollok-tests/src/wollok/classes/constructors/constructors.wpgm deleted file mode 100644 index 70ad41ddb6..0000000000 --- a/wollok-tests/src/wollok/classes/constructors/constructors.wpgm +++ /dev/null @@ -1,7 +0,0 @@ -import constructorsLib.* - -program constructors { - const direccion = new Direccion("Jose Marti", 155) - assert.equals("Jose Marti", direccion.getCalle()) - assert.equals(155, direccion.getNumero()) -} \ No newline at end of file diff --git a/wollok-tests/src/wollok/classes/constructors/constructorsLib.wlk b/wollok-tests/src/wollok/classes/constructors/constructorsLib.wlk deleted file mode 100644 index a54bf7302b..0000000000 --- a/wollok-tests/src/wollok/classes/constructors/constructorsLib.wlk +++ /dev/null @@ -1,22 +0,0 @@ -class Direccion { - var calle = "" - var numero = 0 - const a - - constructor(c, n) { - calle = c - numero = n - a = 23 - } - - constructor (c) = self(c, 3) { - // ... - } - - method getCalle() { return calle } - method getNumero() { return numero } -} - - -// new Direccion { calle = "Humberto 1mo", numero = 1080, a = 23 } - diff --git a/wollok-tests/src/wollok/classes/constructors/info.showcase b/wollok-tests/src/wollok/classes/constructors/info.showcase deleted file mode 100644 index e998792152..0000000000 --- a/wollok-tests/src/wollok/classes/constructors/info.showcase +++ /dev/null @@ -1,4 +0,0 @@ -{ - "id" : "classes-constructors", - "title" : "Constructors" -} diff --git a/wollok-tests/src/wollok/classes/mixins/mixins.wtest b/wollok-tests/src/wollok/classes/mixins/mixins.wtest deleted file mode 100644 index c948a85979..0000000000 --- a/wollok-tests/src/wollok/classes/mixins/mixins.wtest +++ /dev/null @@ -1,118 +0,0 @@ -mixin Energy { - var energy = 100 -} - -class Birdo mixed with Energy { - method fly(meters) { - energy -= meters - } - method energy() = energy -} - - -mixin Flies { - method fly() { - } -} - -class Bird mixed with Flies {} - -mixin Walks { - var walkedDistance = 0 - method walk(distance) { - walkedDistance += distance - } - method walkedDistance() = walkedDistance -} - -class WalkingBird mixed with Walks {} - -mixin Energyo { - var energy = 100 - method reduceEnergy(amount) { energy -= amount } - method energy() = energy -} - -class Birdo mixed with Energyo { - override method reduceEnergy(amount) { - super(1) - } -} - -mixin ReducableEnergy { - var energy = 100 - method energy() = energy - method reduceEnergy(amount) { - energy -= amount - } -} - -mixin Flying { - var fliedMeters = 0 - method fly(meters) { - self.reduceEnergy(meters) - fliedMeters += meters - } - method fliedMeters() = fliedMeters - method reduceEnergy(meters) -} - -class BirdWithEnergyThatFlies mixed with ReducableEnergy, Flying {} - - -mixin FlyingShortcuts { - method fly100Meters() { - self.fly(100) - } - method fly(amount) -} - -class BirdWithFlyingShortCuts mixed with FlyingShortcuts { - var energy = 200 - override method fly(meters) { energy -= meters } - method energy() = energy -} - - object example { - method aList() = [1,2,3] - method useTheList() { - const pepe = self.aList() - console.println(pepe) - } - } - -object pepita mixed with Flies {} - -// ************************** -// ** tests -// ************************** - -test "Class with simple mixin inherits a method" { - const b = new Bird() - b.fly() -} - -test "Class with mixin modifying its own state from the mixin" { - const b = new WalkingBird() - b.walk(10) - const walked = b.walkedDistance() - assert.equals(10, walked) -} - -test "asd" { - const b = new BirdWithEnergyThatFlies() - b.fly(10) - assert.equals(90, b.energy()) - assert.equals(10, b.fliedMeters()) -} - - -test "Mixin method calls a method on the class" { - const b = new BirdWithFlyingShortCuts() - b.fly100Meters() - assert.equals(100, b.energy()) -} - -test "WKO with mixin" { - pepita.fly() -} diff --git a/wollok-tests/src/wollok/classes/natives/info.showcase b/wollok-tests/src/wollok/classes/natives/info.showcase deleted file mode 100644 index 72c36164d9..0000000000 --- a/wollok-tests/src/wollok/classes/natives/info.showcase +++ /dev/null @@ -1,4 +0,0 @@ -{ - "id" : "classes-natives", - "title" : "Natives" -} diff --git a/wollok-tests/src/wollok/classes/natives/sample_program.wpgm b/wollok-tests/src/wollok/classes/natives/sample_program.wpgm deleted file mode 100644 index c87aca176c..0000000000 --- a/wollok-tests/src/wollok/classes/natives/sample_program.wpgm +++ /dev/null @@ -1,16 +0,0 @@ -import wollok.classes.natives.MyNative - -/** - * If you want to run this test, you have to copy `wollok` folder with MyNative Java - * definitions into your `src` folder (or any other source folder that belongs to the - * classpath) - */ - -program nativeSample { - const obj = new MyNative() - const response = obj.aNativeMethod() - - console.println(response) - - console.println(obj.uppercased()) -} \ No newline at end of file diff --git a/wollok-tests/src/wollok/classes/natives/wollok.wlk b/wollok-tests/src/wollok/classes/natives/wollok.wlk deleted file mode 100644 index 8e74964d61..0000000000 --- a/wollok-tests/src/wollok/classes/natives/wollok.wlk +++ /dev/null @@ -1,11 +0,0 @@ -package classes.natives { - - class MyNative { - method aNativeMethod() native - - method uppercased() { - return self.aNativeMethod().toUpperCase() - } - } - -} diff --git a/wollok-tests/src/wollok/classes/natives/wollok/MyNative.class b/wollok-tests/src/wollok/classes/natives/wollok/MyNative.class deleted file mode 100644 index ee229f65e1e298ada6e9aacb9630ab43fbfb0637..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 320 zcmYjM!A`8jjDMvk6AyfVA7z}S zF*=9$X5PG+$$Wi(?f_ilC`1jNCJqC11M~=uvCegQOYn!ICqnJcESS)p=$vPpbswh)=8qLc>=jjb0oSRLN@V(y8Okb;^E9Y#Zjt1eh zlKM-|GSgqPwJPNS;o`-J@Ej$XvX*U>@6XxjcL$;OckdxyaZ+LcU*2)yf!un*K&o?L m60To raton.getVelocidad() - } - method correA(raton) { - var distancia = raton.getPosicion() - posicion - energia -= 0.5 * self.getVelocidad() * distancia - posicion = raton.getPosicion() - } - method comeA(raton) { - self.correA(raton) - energia += 12 + raton.getPeso() - } - } - - const jerry = object { - var peso = 10 - var posicion = 10 - method getVelocidad() { - return 10 - peso - } - method getPosicion() { - return posicion - } - method getPeso() { - return peso - } - } - - assert.that(tom.puedeAtraparA(jerry)) - tom.correA(jerry) - - tom.comeA(jerry) -} \ No newline at end of file diff --git a/wollok-tests/src/wollok/exceptions/exceptions.wpgm b/wollok-tests/src/wollok/exceptions/exceptions.wpgm deleted file mode 100644 index dbd8235fa4..0000000000 --- a/wollok-tests/src/wollok/exceptions/exceptions.wpgm +++ /dev/null @@ -1,24 +0,0 @@ -import exceptionsLib.* - -program exceptions { - const a = new A() - - var i = 0 - try { - a.m0() - console.println("No exception raised") - } - catch e : MyException - e.printStackTrace() - then always - i = i + 1 - - if (i > 0) { - console.println("i is positive") - } - else { - console.println("i is zero !") - } - console.println("End of program") - -} \ No newline at end of file diff --git a/wollok-tests/src/wollok/exceptions/exceptionsLib.wlk b/wollok-tests/src/wollok/exceptions/exceptionsLib.wlk deleted file mode 100644 index 3ae68870f1..0000000000 --- a/wollok-tests/src/wollok/exceptions/exceptionsLib.wlk +++ /dev/null @@ -1,19 +0,0 @@ -class A { - method m0() { throw new MyException("my exception message") } - method m1() { self.m2() } - method m2() { self.m3() } - method m3() { self.m4() } - method m4() { - try - self.m5() - catch e : MyException - throw new Exception("Opps, error on m5()", e) - } - method m5() { - throw new MyException("Error sarasa") - } -} - -class MyException inherits wollok.lang.Exception { - constructor(message) = super(message) -} diff --git a/wollok-tests/src/wollok/imports/importing.wlk b/wollok-tests/src/wollok/imports/importing.wlk deleted file mode 100644 index 89195a020d..0000000000 --- a/wollok-tests/src/wollok/imports/importing.wlk +++ /dev/null @@ -1,5 +0,0 @@ -import packageA.file1.x -import packageB.file2.y - -object z{ -} \ No newline at end of file diff --git a/wollok-tests/src/wollok/imports/packageA/file1.wlk b/wollok-tests/src/wollok/imports/packageA/file1.wlk deleted file mode 100644 index e5a0e4cba4..0000000000 --- a/wollok-tests/src/wollok/imports/packageA/file1.wlk +++ /dev/null @@ -1,3 +0,0 @@ -object x { - -} \ No newline at end of file diff --git a/wollok-tests/src/wollok/imports/packageB/file2.wlk b/wollok-tests/src/wollok/imports/packageB/file2.wlk deleted file mode 100644 index afa89212c8..0000000000 --- a/wollok-tests/src/wollok/imports/packageB/file2.wlk +++ /dev/null @@ -1,5 +0,0 @@ -import packageA.file1.x - -object y{ - -} \ No newline at end of file diff --git a/wollok-tests/src/wollok/imports/wollok.root b/wollok-tests/src/wollok/imports/wollok.root deleted file mode 100644 index e69de29bb2..0000000000 diff --git a/wollok-tests/src/wollok/lang/exceptions.wlk b/wollok-tests/src/wollok/lang/exceptions.wlk deleted file mode 100644 index 8fad6d3a2d..0000000000 --- a/wollok-tests/src/wollok/lang/exceptions.wlk +++ /dev/null @@ -1,7 +0,0 @@ -package wollok.lang { - - class Exception { - method printStackTrace() native - } - -} \ No newline at end of file diff --git a/wollok-tests/src/wollok/tests/test.wtest b/wollok-tests/src/wollok/tests/test.wtest deleted file mode 100644 index 28aada55b2..0000000000 --- a/wollok-tests/src/wollok/tests/test.wtest +++ /dev/null @@ -1,17 +0,0 @@ - -object alpiste { - method energia() = 100 -} -object maiz { - method energia() { - return 200 - } -} - -test "Energia del Alpiste es 100" { - assert.equals(100, alpiste.energia()) -} - -test "Energia del Maiz es 200" { - assert.equals(200, maiz.energia()) -} \ No newline at end of file From 685e9e794faf60d266f5736f756aecb6b94b3b03 Mon Sep 17 00:00:00 2001 From: Fernando Dodino Date: Wed, 13 Nov 2019 21:53:43 -0300 Subject: [PATCH 122/133] Fix test after lang.wlk change --- .../tests/natives/ExceptionPropagationInNativeTestCase.xtend | 2 +- wollok-language | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/natives/ExceptionPropagationInNativeTestCase.xtend b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/natives/ExceptionPropagationInNativeTestCase.xtend index 6845e5c01f..51a3210ee9 100644 --- a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/natives/ExceptionPropagationInNativeTestCase.xtend +++ b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/natives/ExceptionPropagationInNativeTestCase.xtend @@ -45,7 +45,7 @@ program natives { } catch e { assert.equals(e.getStackTraceAsString(), "wollok.lib.AssertionException: Expected [1] but found [true] - at wollok.lib.assert.equals(expected,actual) [/lib.wlk:78] + at wollok.lib.assert.equals(expected,actual) [/lib.wlk:72] at [/assertTest.wpgm:3] " ) diff --git a/wollok-language b/wollok-language index e02bee3e10..0c329a999f 160000 --- a/wollok-language +++ b/wollok-language @@ -1 +1 @@ -Subproject commit e02bee3e10d222f41b25acd0a7d6a3c79ab09ed4 +Subproject commit 0c329a999fb499415fe9fd171084dfa044c525c9 From f5577b8b9244e81528a7fea5d74c12d8aaa49a81 Mon Sep 17 00:00:00 2001 From: Fernando Dodino Date: Fri, 15 Nov 2019 00:13:31 -0300 Subject: [PATCH 123/133] Removing warning for core library files --- .../uqbar/project/wollok/libraries/WollokLibExtensions.xtend | 1 + .../uqbar/project/wollok/validation/WollokDslValidator.xtend | 5 ++++- wollok-language | 2 +- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/org.uqbar.project.wollok/src/org/uqbar/project/wollok/libraries/WollokLibExtensions.xtend b/org.uqbar.project.wollok/src/org/uqbar/project/wollok/libraries/WollokLibExtensions.xtend index 54b7f0407e..87cd7b822c 100644 --- a/org.uqbar.project.wollok/src/org/uqbar/project/wollok/libraries/WollokLibExtensions.xtend +++ b/org.uqbar.project.wollok/src/org/uqbar/project/wollok/libraries/WollokLibExtensions.xtend @@ -18,6 +18,7 @@ class WollokLibExtensions { public static val GAME_LIB = "wollok.game" public static val MIRROR_LIB = "wollok.mirror" + public static val ALL_LIBS_FILE = #["lang.wlk", "lib.wlk", "game.wlk", "mirror.wlk", "vm.wlk"] public static val ALL_LIBS = #[LANG_LIB, LIB_LIB, VM_LIB, GAME_LIB, MIRROR_LIB] public static val IMPLICIT_IMPORTS = #[LIB_LIB, LANG_LIB] public static val NON_IMPLICIT_IMPORTS = #[GAME_LIB, VM_LIB, MIRROR_LIB] diff --git a/org.uqbar.project.wollok/src/org/uqbar/project/wollok/validation/WollokDslValidator.xtend b/org.uqbar.project.wollok/src/org/uqbar/project/wollok/validation/WollokDslValidator.xtend index 64a9944c31..0012fc362c 100644 --- a/org.uqbar.project.wollok/src/org/uqbar/project/wollok/validation/WollokDslValidator.xtend +++ b/org.uqbar.project.wollok/src/org/uqbar/project/wollok/validation/WollokDslValidator.xtend @@ -1069,7 +1069,10 @@ class WollokDslValidator extends AbstractConfigurableDslValidator { @Check @DefaultSeverity(WARN) def classNameCannotBeCoreReservedWord(WClass c) { - if(WollokResourceCache.allCoreClasses.map[name].toList.contains(c.name) || isCoreLib(c.fqn)){ + if (ALL_LIBS_FILE.contains(c.eResource.URI.lastSegment)) { + return + } + if ((WollokResourceCache.allCoreClasses.map[name].toList.contains(c.name) || isCoreLib(c.fqn))) { report(NLS.bind(WollokDslValidator_CANNOT_USE_CORE_NAME,c.name),c,WNAMED__NAME) } } diff --git a/wollok-language b/wollok-language index 0c329a999f..308667c783 160000 --- a/wollok-language +++ b/wollok-language @@ -1 +1 @@ -Subproject commit 0c329a999fb499415fe9fd171084dfa044c525c9 +Subproject commit 308667c783dbede318fbdc94dcf9b55b55786481 From 7500f6c3feff326ea8c629204761c961a08b9aee Mon Sep 17 00:00:00 2001 From: Fernando Dodino Date: Wed, 27 Nov 2019 09:03:43 -0300 Subject: [PATCH 124/133] Migrating some game tests to wollok-language repo --- .../project/wollok/tests/sdk/GameTest.xtend | 63 +------------------ wollok-language | 2 +- 2 files changed, 2 insertions(+), 63 deletions(-) diff --git a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/sdk/GameTest.xtend b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/sdk/GameTest.xtend index ec8a9b24a4..49c3b72c43 100644 --- a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/sdk/GameTest.xtend +++ b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/sdk/GameTest.xtend @@ -31,6 +31,7 @@ class GameTest extends AbstractWollokInterpreterTestCase { '''.test } + // Deberíamos publicar una propiedad cellsize en Game para poder ejecutarlo en wollok-language @Test def void cellSize_works_correctly() { ''' @@ -39,72 +40,10 @@ class GameTest extends AbstractWollokInterpreterTestCase { assertEquals(10, gameboard.cellsize) } - @Test - def void cellSize_throws_exception_limit(){ - ''' - assert.throwsExceptionWithMessage("Cell size can't be 0 or lower", {=>game.cellSize(0)}) - '''.gameTest - } - - @Test - def void cellSize_throws_exception(){ - ''' - assert.throwsExceptionWithMessage("Cell size can't be 0 or lower", {=>game.cellSize(-10)}) - '''.gameTest - } - - def void volumeCantBeHigherThan1() { - ''' - assert.throwsExceptionWithMessage("Volume value must be between 0 and 1.", { => sound.volume(2.5) }) - '''.soundTest - } - - @Test - def void volumeCantBeLowerThan0() { - ''' - assert.throwsExceptionWithMessage("Volume value must be between 0 and 1.", { => sound.volume(-3) }) - '''.soundTest - } - - @Test - def void soundCantBePlayedIfGameHasntBeenStarted() { - ''' - assert.throwsExceptionWithMessage("You cannot play sounds until the game has started. Try using it inside an onTick / onPressDo block.", { => sound.play() }) - '''.soundTest - } - - @Test - def void soundCantBePausedIfItHasntBePlayed() { - ''' - assert.throwsExceptionWithMessage("You cannot pause or resume a sound that hasn't been played.", { => sound.pause() }) - '''.soundTest - } - - @Test - def void soundCantBeStoppedIfItHasntBeenPlayed() { - ''' - assert.throwsExceptionWithMessage("You cannot stop a sound that hasn't been played.", { => sound.stop() }) - '''.soundTest - } - - def soundTest(CharSequence test) { - ''' - import wollok.game.* - - program a { - const sound = game.sound("testSound.mp3") - «test» - } - '''.interpretPropagatingErrors - } - def gameTest(CharSequence test) { ''' import wollok.game.* - object myVisual { } - class Visual { } - object pepita { var property position = game.origin() } diff --git a/wollok-language b/wollok-language index 231907fa91..671d798451 160000 --- a/wollok-language +++ b/wollok-language @@ -1 +1 @@ -Subproject commit 231907fa91d0b017813d0f304bf7e08da938413f +Subproject commit 671d798451a95b8c43d22f2764866df6828c86cc From dc43409b44aae7e8734ed353877153171a80bef6 Mon Sep 17 00:00:00 2001 From: Fernando Dodino Date: Wed, 27 Nov 2019 11:15:01 -0300 Subject: [PATCH 125/133] Forcing travis to use hard links to see if surefire reports do not fail --- .travis.yml | 2 +- .../src/org/uqbar/project/wollok/tests/sdk/GameTest.xtend | 2 +- wollokInstallTravis.sh | 4 ++++ 3 files changed, 6 insertions(+), 2 deletions(-) create mode 100755 wollokInstallTravis.sh diff --git a/.travis.yml b/.travis.yml index 378efc22eb..16b3bc2e40 100644 --- a/.travis.yml +++ b/.travis.yml @@ -17,7 +17,7 @@ after_success: cd .. fi script: -- "./wollokInstall.sh" +- "./wollokInstallTravis.sh" - cd org.uqbar.project.wollok.releng/ - export PROFILES=normalProfile - export UPDATE_SITE=none diff --git a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/sdk/GameTest.xtend b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/sdk/GameTest.xtend index 49c3b72c43..ad81ccaa11 100644 --- a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/sdk/GameTest.xtend +++ b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/sdk/GameTest.xtend @@ -31,7 +31,7 @@ class GameTest extends AbstractWollokInterpreterTestCase { '''.test } - // Deberíamos publicar una propiedad cellsize en Game para poder ejecutarlo en wollok-language + // We should publish a cellSize property in game wko to migrate this test to wollok-language @Test def void cellSize_works_correctly() { ''' diff --git a/wollokInstallTravis.sh b/wollokInstallTravis.sh new file mode 100755 index 0000000000..94368e0b88 --- /dev/null +++ b/wollokInstallTravis.sh @@ -0,0 +1,4 @@ +#!/bin/bash +git submodule update --init --recursive +cd org.uqbar.project.wollok.lib/src/wollok +ln ../../../wollok-language/src/wollok/*.wlk ./ From 00ca61fd2e5699b903c12369e74135977dd9f85f Mon Sep 17 00:00:00 2001 From: Fernando Dodino Date: Wed, 27 Nov 2019 13:04:59 -0300 Subject: [PATCH 126/133] Trying to fix surefire for Build travis --- org.uqbar.project.wollok.tests/.classpath | 18 +++--------------- wollokInstallTravis.sh | 2 +- 2 files changed, 4 insertions(+), 16 deletions(-) diff --git a/org.uqbar.project.wollok.tests/.classpath b/org.uqbar.project.wollok.tests/.classpath index 84b7f74b41..1671c20fb7 100644 --- a/org.uqbar.project.wollok.tests/.classpath +++ b/org.uqbar.project.wollok.tests/.classpath @@ -4,20 +4,8 @@ - - - - - - - - - - - - - - - + + + diff --git a/wollokInstallTravis.sh b/wollokInstallTravis.sh index 94368e0b88..4cd61611b7 100755 --- a/wollokInstallTravis.sh +++ b/wollokInstallTravis.sh @@ -1,4 +1,4 @@ #!/bin/bash git submodule update --init --recursive cd org.uqbar.project.wollok.lib/src/wollok -ln ../../../wollok-language/src/wollok/*.wlk ./ +cp ../../../wollok-language/src/wollok/*.wlk ./ From 69fd5fc989ab656c0d2b7dffcbbdb95e57f5b9e7 Mon Sep 17 00:00:00 2001 From: Fernando Dodino Date: Wed, 27 Nov 2019 13:24:38 -0300 Subject: [PATCH 127/133] Back to wollokInstall shell script for Travis --- .travis.yml | 2 +- wollokInstallTravis.sh | 4 ---- 2 files changed, 1 insertion(+), 5 deletions(-) delete mode 100755 wollokInstallTravis.sh diff --git a/.travis.yml b/.travis.yml index 16b3bc2e40..378efc22eb 100644 --- a/.travis.yml +++ b/.travis.yml @@ -17,7 +17,7 @@ after_success: cd .. fi script: -- "./wollokInstallTravis.sh" +- "./wollokInstall.sh" - cd org.uqbar.project.wollok.releng/ - export PROFILES=normalProfile - export UPDATE_SITE=none diff --git a/wollokInstallTravis.sh b/wollokInstallTravis.sh deleted file mode 100755 index 4cd61611b7..0000000000 --- a/wollokInstallTravis.sh +++ /dev/null @@ -1,4 +0,0 @@ -#!/bin/bash -git submodule update --init --recursive -cd org.uqbar.project.wollok.lib/src/wollok -cp ../../../wollok-language/src/wollok/*.wlk ./ From a1b395b306cafe03b59f530759f4e64a074c4894 Mon Sep 17 00:00:00 2001 From: Fernando Dodino Date: Wed, 27 Nov 2019 13:30:09 -0300 Subject: [PATCH 128/133] Removing game.wlk causing travis to fail! --- .gitignore | 2 +- org.uqbar.project.wollok.lib/src/wollok/game.wlk | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) delete mode 120000 org.uqbar.project.wollok.lib/src/wollok/game.wlk diff --git a/.gitignore b/.gitignore index a6b1774a9a..457b6ba85f 100644 --- a/.gitignore +++ b/.gitignore @@ -31,4 +31,4 @@ scripts/wollok-site scripts/wollok-cli # Ignoring wollok-language files -org.uqbar.project.wollok.lib/src/wollok/*.wlk +# org.uqbar.project.wollok.lib/src/wollok/*.wlk diff --git a/org.uqbar.project.wollok.lib/src/wollok/game.wlk b/org.uqbar.project.wollok.lib/src/wollok/game.wlk deleted file mode 120000 index 78a671621a..0000000000 --- a/org.uqbar.project.wollok.lib/src/wollok/game.wlk +++ /dev/null @@ -1 +0,0 @@ -../../../wollok-language/src/wollok/game.wlk \ No newline at end of file From de5722dd2ec6431e7de7b93ebd5e7f40ce91222f Mon Sep 17 00:00:00 2001 From: Fernando Dodino Date: Wed, 27 Nov 2019 13:55:32 -0300 Subject: [PATCH 129/133] Ignoring back all .wlk files --- .gitignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 457b6ba85f..a6b1774a9a 100644 --- a/.gitignore +++ b/.gitignore @@ -31,4 +31,4 @@ scripts/wollok-site scripts/wollok-cli # Ignoring wollok-language files -# org.uqbar.project.wollok.lib/src/wollok/*.wlk +org.uqbar.project.wollok.lib/src/wollok/*.wlk From 73d1a16e2822c6421f0b05f1248806a02e058eba Mon Sep 17 00:00:00 2001 From: Fernando Dodino Date: Sat, 30 Nov 2019 19:29:12 -0300 Subject: [PATCH 130/133] Fixes according to Nahue review --- .../interpreter/TestDescribeTestCase.xtend | 22 +------------------ .../tests/libraries/LoadLibraryTest.xtend | 5 ++--- .../wollok/tests/xpect/DescribeTest.wtest.xt | 15 +++++++++++++ .../WollokExceptionExtensions.xtend | 5 +---- 4 files changed, 19 insertions(+), 28 deletions(-) diff --git a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/TestDescribeTestCase.xtend b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/TestDescribeTestCase.xtend index 25771fb028..ee81ce6f16 100644 --- a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/TestDescribeTestCase.xtend +++ b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/interpreter/TestDescribeTestCase.xtend @@ -11,26 +11,6 @@ import org.uqbar.project.wollok.interpreter.core.WollokProgramExceptionWrapper */ class TestDescribeTestCase extends AbstractWollokInterpreterTestCase { - @Test(expected=AssertionError) - def void testShouldNotUseSameVariableDefinedInDescribe() { - ''' - describe "pruebas generales" { - const a = 8 - const b = 5 - - test "Max between 5 and 8" { - const a = 3 - const result = 5.max(8) - assert.equals(8, result) - } - test "Min between 5 and 8" { - const result = 5.min(8) - assert.equals(5, result) - } - } - '''.interpretPropagatingErrors - } - @Test(expected=WollokProgramExceptionWrapper) def void testFixtureErrorBreaksTestsInDescribe() { ''' @@ -50,7 +30,7 @@ class TestDescribeTestCase extends AbstractWollokInterpreterTestCase { } test "dos es dos" { - var dos = self.dos() + const dos = self.dos() self.uno() assert.equals(2, dos) } diff --git a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/libraries/LoadLibraryTest.xtend b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/libraries/LoadLibraryTest.xtend index f4c8359239..c6f66a1179 100644 --- a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/libraries/LoadLibraryTest.xtend +++ b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/libraries/LoadLibraryTest.xtend @@ -1,6 +1,7 @@ package org.uqbar.project.wollok.tests.libraries import org.eclipse.xtext.testing.InjectWith +import org.junit.Ignore import org.junit.Test import org.uqbar.project.wollok.tests.interpreter.AbstractWollokInterpreterTestCase @@ -20,7 +21,7 @@ class LoadLibraryTest extends AbstractWollokInterpreterTestCase { } - /* probar cuando esté listo el problema de los directorios + @Ignore @Test def void testInnerLocationObjectExist() { ''' @@ -29,9 +30,7 @@ class LoadLibraryTest extends AbstractWollokInterpreterTestCase { assert.equals('hola Don Pepito', jose.hola()) } '''.interpretPropagatingErrors - } - */ @Test def void nativeObjectInLibrary() { diff --git a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/xpect/DescribeTest.wtest.xt b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/xpect/DescribeTest.wtest.xt index 7e83ef214f..7a306c8e30 100644 --- a/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/xpect/DescribeTest.wtest.xt +++ b/org.uqbar.project.wollok.tests/src/org/uqbar/project/wollok/tests/xpect/DescribeTest.wtest.xt @@ -17,3 +17,18 @@ describe "" { assert.equals(2, 1 + 1) } } + +describe "pruebas generales" { + const a = 8 + + test "Max between 5 and 8" { + // XPECT errors --> "Duplicated Name" at "a" + const a = 3 + const result = 5.max(a) + assert.equals(3, result) + } + test "Min between 5 and 8" { + const result = 5.min(a) + assert.equals(5, result) + } +} diff --git a/org.uqbar.project.wollok/src/org/uqbar/project/wollok/errorHandling/WollokExceptionExtensions.xtend b/org.uqbar.project.wollok/src/org/uqbar/project/wollok/errorHandling/WollokExceptionExtensions.xtend index 0753c71e54..514fa44bcb 100644 --- a/org.uqbar.project.wollok/src/org/uqbar/project/wollok/errorHandling/WollokExceptionExtensions.xtend +++ b/org.uqbar.project.wollok/src/org/uqbar/project/wollok/errorHandling/WollokExceptionExtensions.xtend @@ -222,9 +222,6 @@ class WollokExceptionExtensions { def static dispatch shouldShowStackTraceInJava(WollokProgramExceptionWrapper e) { false } def static dispatch shouldShowStackTraceInJava(WollokInterpreterException e) { false } - def static dispatch shouldShowStackTraceInJava(Throwable t) { - // !t.class.name.equals(ASSERTION_EXCEPTION_FQN) - true - } + def static dispatch shouldShowStackTraceInJava(Throwable t) { true } } From c5c88bb28d83341669095b3a02005a73e8432e0d Mon Sep 17 00:00:00 2001 From: Fernando Dodino Date: Sun, 1 Dec 2019 11:30:38 -0300 Subject: [PATCH 131/133] #1863 - adding attachments to Wollok releases --- .travis.yml | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/.travis.yml b/.travis.yml index 378efc22eb..e6fac97de4 100644 --- a/.travis.yml +++ b/.travis.yml @@ -127,6 +127,16 @@ deploy: on: all_branches: true condition: "$UPDATE_SITE =~ ^dev|stable$" +- provider: releases + skip_cleanup: true + api_key: + secure: ZGDMxFYXbp/LgNqtGourJXgQS2itBxHWzLqDKnSd1YV6sDHnYzvrq8aCoLHujMCI0yLkRAI12raylJkXHzQHcN3JDF0SyJostz59x1KEJ4cpv8K5bb2bs8BsV/BuZlQssu6yqqgaIXOALF52wUGgVg8nBjWA0LdRL5DDFs8ExR0= + file_glob: true + file: results-products/*.zip + on: + tags: true + all_branches: true + repo: uqbar-project/wollok env: global: secure: IJCZW9xrLlUjs/HRkrpagk06zo2+FvKaMygUk6K9Fdim3uSsLmn4UyBazNli0a62oq3XuNpscsCmdVtofUCfZphEHnyIUUTToQ+u6j1KxbICjfIGFMmUEoY/7tZVscQ5SBgiqtEVfUvolN6v4YUtx2FwaS27FW5SV3/x8j6toPw= From 7dd5ea87018b3309fd0be332ba98e5756765a15d Mon Sep 17 00:00:00 2001 From: Fernando Dodino Date: Sun, 1 Dec 2019 11:34:32 -0300 Subject: [PATCH 132/133] Updating README --- README.md | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/README.md b/README.md index 7e88eb0236..90355dee55 100644 --- a/README.md +++ b/README.md @@ -26,8 +26,6 @@ You have two options to download an use Wollok. * http://update.uqbar.org/wollok/stable : for the latest stable release * http://update.uqbar.org/wollok/dev : for the current dev (work in progress) version -Or drag and drop Drag to your running Eclipse workspace to install Wollok - ## Wollok SDK standalone ## Finally if you just want the headless Development Kit (WDK), for example to use a different IDE than Eclipse, you can download it from @@ -84,10 +82,8 @@ You can either use its IDE: * With: many **static code analysis**, **Quick-Fixes**, **Refactors** * An **interactive Console** (**REPL**) * **Visual representations**: Outline, Static diagram, Objects Diagrams -* A **debugger**. -Or use the WDK which has command line tools for running and checkin a program. -This is also integrated with [Sublime Editor](https://github.com/uqbar-project/wollok-sublime-linter/blob/master/README.md). +Or use the wollok-cli which has command line tools for running and checkin a program. ## How to Contribute ## From 27cf8ddb153085c7f0f136ce2a2d6f7a8327a107 Mon Sep 17 00:00:00 2001 From: Fernando Dodino Date: Sun, 1 Dec 2019 11:53:54 -0300 Subject: [PATCH 133/133] Upgrading to version 1.9.2 for next release --- org.uqbar.project.wollok.game/META-INF/MANIFEST.MF | 2 +- org.uqbar.project.wollok.launch/META-INF/MANIFEST.MF | 2 +- .../src/org/uqbar/project/wollok/launch/Wollok.xtend | 2 +- org.uqbar.project.wollok.lib/META-INF/MANIFEST.MF | 2 +- org.uqbar.project.wollok.product.ui/META-INF/MANIFEST.MF | 2 +- org.uqbar.project.wollok.product/META-INF/MANIFEST.MF | 2 +- org.uqbar.project.wollok.product/plugin.xml | 2 +- org.uqbar.project.wollok.sdk/feature.xml | 2 +- org.uqbar.project.wollok.tests/META-INF/MANIFEST.MF | 2 +- org.uqbar.project.wollok.typeSystem.ui/META-INF/MANIFEST.MF | 2 +- org.uqbar.project.wollok.typeSystem/META-INF/MANIFEST.MF | 2 +- org.uqbar.project.wollok.ui.diagrams/META-INF/MANIFEST.MF | 2 +- org.uqbar.project.wollok.ui.launch/META-INF/MANIFEST.MF | 2 +- org.uqbar.project.wollok.ui/META-INF/MANIFEST.MF | 2 +- org.uqbar.project.wollok.updatesite/category.xml | 2 +- org.uqbar.project.wollok.updatesite/wollok-product.product | 4 ++-- org.uqbar.project.wollok/META-INF/MANIFEST.MF | 2 +- org.uqbar.project.xinterpreter/META-INF/MANIFEST.MF | 2 +- 18 files changed, 19 insertions(+), 19 deletions(-) diff --git a/org.uqbar.project.wollok.game/META-INF/MANIFEST.MF b/org.uqbar.project.wollok.game/META-INF/MANIFEST.MF index 0b8e3de92a..35d65da5f1 100644 --- a/org.uqbar.project.wollok.game/META-INF/MANIFEST.MF +++ b/org.uqbar.project.wollok.game/META-INF/MANIFEST.MF @@ -1,7 +1,7 @@ Bundle-ManifestVersion: 2 Bundle-Name: Wollok Game Bundle-SymbolicName: org.uqbar.project.wollok.game -Bundle-Version: 1.9.0 +Bundle-Version: 1.9.2 Bundle-RequiredExecutionEnvironment: JavaSE-1.8 Import-Package: org.junit;version="4.11.0", org.osgi.framework;version="1.3.0", diff --git a/org.uqbar.project.wollok.launch/META-INF/MANIFEST.MF b/org.uqbar.project.wollok.launch/META-INF/MANIFEST.MF index efcc46f4c4..7b3454ad14 100644 --- a/org.uqbar.project.wollok.launch/META-INF/MANIFEST.MF +++ b/org.uqbar.project.wollok.launch/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: org.uqbar.project.wollok.launch Bundle-Vendor: Uqbar Project -Bundle-Version: 1.9.0 +Bundle-Version: 1.9.2 Bundle-SymbolicName: org.uqbar.project.wollok.launch;singleton:=true Bundle-ActivationPolicy: lazy Require-Bundle: org.eclipse.ui, diff --git a/org.uqbar.project.wollok.launch/src/org/uqbar/project/wollok/launch/Wollok.xtend b/org.uqbar.project.wollok.launch/src/org/uqbar/project/wollok/launch/Wollok.xtend index 430ecf0888..4b0bfdedb0 100644 --- a/org.uqbar.project.wollok.launch/src/org/uqbar/project/wollok/launch/Wollok.xtend +++ b/org.uqbar.project.wollok.launch/src/org/uqbar/project/wollok/launch/Wollok.xtend @@ -6,6 +6,6 @@ package org.uqbar.project.wollok.launch // THIS GETS UPDATED BY OUT BASH SCRIPT class Wollok { - public static val VERSION = "1.8.5" + public static val VERSION = "1.9.2" } diff --git a/org.uqbar.project.wollok.lib/META-INF/MANIFEST.MF b/org.uqbar.project.wollok.lib/META-INF/MANIFEST.MF index 5eafc9848a..182e98f75a 100644 --- a/org.uqbar.project.wollok.lib/META-INF/MANIFEST.MF +++ b/org.uqbar.project.wollok.lib/META-INF/MANIFEST.MF @@ -1,7 +1,7 @@ Bundle-ManifestVersion: 2 Bundle-Name: Wollok Lib Bundle-SymbolicName: org.uqbar.project.wollok.lib;singleton:=true -Bundle-Version: 1.9.0 +Bundle-Version: 1.9.2 Bundle-Activator: org.uqbar.project.wollok.lib.WollokLibActivator Require-Bundle: org.eclipse.ui, org.eclipse.core.runtime, diff --git a/org.uqbar.project.wollok.product.ui/META-INF/MANIFEST.MF b/org.uqbar.project.wollok.product.ui/META-INF/MANIFEST.MF index 205a780e22..3a4d0a10e6 100644 --- a/org.uqbar.project.wollok.product.ui/META-INF/MANIFEST.MF +++ b/org.uqbar.project.wollok.product.ui/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: Wollok Product UI Customizations Bundle-SymbolicName: org.uqbar.project.wollok.product.ui;singleton:=true -Bundle-Version: 1.9.0 +Bundle-Version: 1.9.2 Bundle-Activator: org.uqbar.project.wollok.product.ui.WollokProductActivator Require-Bundle: org.eclipse.ui, org.eclipse.core.runtime, diff --git a/org.uqbar.project.wollok.product/META-INF/MANIFEST.MF b/org.uqbar.project.wollok.product/META-INF/MANIFEST.MF index f1f4d63385..8e8783f5e7 100644 --- a/org.uqbar.project.wollok.product/META-INF/MANIFEST.MF +++ b/org.uqbar.project.wollok.product/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: Wollok Product Bundle-SymbolicName: org.uqbar.project.wollok.product;singleton:=true -Bundle-Version: 1.9.0 +Bundle-Version: 1.9.2 Bundle-Vendor: Uqbar Project Bundle-Localization: plugin Require-Bundle: org.uqbar.project.wollok, diff --git a/org.uqbar.project.wollok.product/plugin.xml b/org.uqbar.project.wollok.product/plugin.xml index 1a77844f76..01d87d4121 100644 --- a/org.uqbar.project.wollok.product/plugin.xml +++ b/org.uqbar.project.wollok.product/plugin.xml @@ -19,7 +19,7 @@ + value="Wollok Programming Language and IDE Version 1.9.2 http://uqbar-project.org http://wollok.org © Copyright 2014-2019, Uqbar Project Foundation, All rights reserved"> diff --git a/org.uqbar.project.wollok.tests/META-INF/MANIFEST.MF b/org.uqbar.project.wollok.tests/META-INF/MANIFEST.MF index 4a497b376d..ee4b817e3a 100644 --- a/org.uqbar.project.wollok.tests/META-INF/MANIFEST.MF +++ b/org.uqbar.project.wollok.tests/META-INF/MANIFEST.MF @@ -3,7 +3,7 @@ Bundle-ManifestVersion: 2 Bundle-Name: %pluginName Bundle-Vendor: %providerName Bundle-Localization: plugin -Bundle-Version: 1.9.0 +Bundle-Version: 1.9.2 Bundle-ClassPath: lib/mockito-all-1.9.5.jar, lib/lipermi-0-4-2.jar, . diff --git a/org.uqbar.project.wollok.typeSystem.ui/META-INF/MANIFEST.MF b/org.uqbar.project.wollok.typeSystem.ui/META-INF/MANIFEST.MF index 50c6ba8fab..dd80c79107 100644 --- a/org.uqbar.project.wollok.typeSystem.ui/META-INF/MANIFEST.MF +++ b/org.uqbar.project.wollok.typeSystem.ui/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: Wollok Type System UI Bundle-SymbolicName: org.uqbar.project.wollok.typeSystem.ui;singleton:=true -Bundle-Version: 1.9.0 +Bundle-Version: 1.9.2 Bundle-Localization: plugin Bundle-RequiredExecutionEnvironment: JavaSE-1.8 Require-Bundle: org.uqbar.project.wollok.ui, diff --git a/org.uqbar.project.wollok.typeSystem/META-INF/MANIFEST.MF b/org.uqbar.project.wollok.typeSystem/META-INF/MANIFEST.MF index cfd4e70ae2..560d53d139 100644 --- a/org.uqbar.project.wollok.typeSystem/META-INF/MANIFEST.MF +++ b/org.uqbar.project.wollok.typeSystem/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: Wollok's TypeSystem API Bundle-SymbolicName: org.uqbar.project.wollok.typeSystem;singleton:=true -Bundle-Version: 1.9.0 +Bundle-Version: 1.9.2 Bundle-RequiredExecutionEnvironment: JavaSE-1.8 Require-Bundle: org.uqbar.project.wollok, org.eclipse.xtend.lib;bundle-version="2.11.0", diff --git a/org.uqbar.project.wollok.ui.diagrams/META-INF/MANIFEST.MF b/org.uqbar.project.wollok.ui.diagrams/META-INF/MANIFEST.MF index a18fcdf053..da01928a5b 100644 --- a/org.uqbar.project.wollok.ui.diagrams/META-INF/MANIFEST.MF +++ b/org.uqbar.project.wollok.ui.diagrams/META-INF/MANIFEST.MF @@ -21,7 +21,7 @@ Require-Bundle: org.eclipse.ui;bundle-version="[3.2.0,4.0.0)", org.uqbar.project.wollok.ui.launch;bundle-version="1.8.5", org.uqbar.project.wollok.ui;bundle-version="1.8.5" Bundle-Activator: org.uqbar.project.wollok.ui.diagrams.classes.WollokDiagramsPlugin -Bundle-Version: 1.9.0 +Bundle-Version: 1.9.2 Build-Jdk: 1.6.0_21 Bundle-Vendor: %Plugin.providerName Bundle-ActivationPolicy: lazy diff --git a/org.uqbar.project.wollok.ui.launch/META-INF/MANIFEST.MF b/org.uqbar.project.wollok.ui.launch/META-INF/MANIFEST.MF index 53488a3853..e2baa3fbd2 100644 --- a/org.uqbar.project.wollok.ui.launch/META-INF/MANIFEST.MF +++ b/org.uqbar.project.wollok.ui.launch/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: org.uqbar.project.wollok.ui.launch Bundle-Vendor: Uqbar Project -Bundle-Version: 1.9.0 +Bundle-Version: 1.9.2 Bundle-SymbolicName: org.uqbar.project.wollok.ui.launch;singleton:=true Bundle-ActivationPolicy: lazy Bundle-Localization: plugin diff --git a/org.uqbar.project.wollok.ui/META-INF/MANIFEST.MF b/org.uqbar.project.wollok.ui/META-INF/MANIFEST.MF index 4e6fe3b707..6a8ffed2a6 100644 --- a/org.uqbar.project.wollok.ui/META-INF/MANIFEST.MF +++ b/org.uqbar.project.wollok.ui/META-INF/MANIFEST.MF @@ -2,7 +2,7 @@ Manifest-Version: 1.0 Bundle-ManifestVersion: 2 Bundle-Name: org.uqbar.project.wollok.ui Bundle-Vendor: Uqbar Project -Bundle-Version: 1.9.0 +Bundle-Version: 1.9.2 Bundle-SymbolicName: org.uqbar.project.wollok.ui; singleton:=true Bundle-ActivationPolicy: lazy Bundle-Localization: plugin diff --git a/org.uqbar.project.wollok.updatesite/category.xml b/org.uqbar.project.wollok.updatesite/category.xml index 87e55582b1..371ec6061b 100644 --- a/org.uqbar.project.wollok.updatesite/category.xml +++ b/org.uqbar.project.wollok.updatesite/category.xml @@ -1,6 +1,6 @@ - + diff --git a/org.uqbar.project.wollok.updatesite/wollok-product.product b/org.uqbar.project.wollok.updatesite/wollok-product.product index 0a084d3718..879b6db179 100644 --- a/org.uqbar.project.wollok.updatesite/wollok-product.product +++ b/org.uqbar.project.wollok.updatesite/wollok-product.product @@ -1,13 +1,13 @@ - + Wollok Programming Language and IDE -Version 1.8.5 +Version 1.9.2 http://uqbar-project.org http://wollok.org diff --git a/org.uqbar.project.wollok/META-INF/MANIFEST.MF b/org.uqbar.project.wollok/META-INF/MANIFEST.MF index 39fccaf082..2b63510f38 100644 --- a/org.uqbar.project.wollok/META-INF/MANIFEST.MF +++ b/org.uqbar.project.wollok/META-INF/MANIFEST.MF @@ -3,7 +3,7 @@ Bundle-ManifestVersion: 2 Bundle-Name: %pluginName Bundle-Vendor: %providerName Bundle-Localization: plugin -Bundle-Version: 1.9.0 +Bundle-Version: 1.9.2 Bundle-ClassPath: . Bundle-SymbolicName: org.uqbar.project.wollok;singleton:=true Bundle-ActivationPolicy: lazy diff --git a/org.uqbar.project.xinterpreter/META-INF/MANIFEST.MF b/org.uqbar.project.xinterpreter/META-INF/MANIFEST.MF index 35fdc811dd..57d9bf6f05 100644 --- a/org.uqbar.project.xinterpreter/META-INF/MANIFEST.MF +++ b/org.uqbar.project.xinterpreter/META-INF/MANIFEST.MF @@ -3,7 +3,7 @@ Bundle-ManifestVersion: 2 Bundle-Name: Uqbar XInterpreter Bundle-Vendor: Uqbar Project Bundle-Localization: plugin -Bundle-Version: 1.9.0 +Bundle-Version: 1.9.2 Bundle-ClassPath: . Bundle-SymbolicName: org.uqbar.project.xinterpreter;singleton:=true Bundle-ActivationPolicy: lazy