-
Notifications
You must be signed in to change notification settings - Fork 23
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
test: add testing of rename provider
- Loading branch information
1 parent
c82f446
commit 3134ee3
Showing
7 changed files
with
302 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,162 @@ | ||
/* | ||
* Copyright 2024 Holger Dal Mogensen | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
import * as assert from 'assert' | ||
import * as vscode from 'vscode' | ||
import { getTestDocUri, activate, open } from './util' | ||
|
||
suite('Rename', () => { | ||
const mainDocUri = getTestDocUri('src/Main.flix') | ||
const areaDocUri = getTestDocUri('src/Area.flix') | ||
const equatableDocUri = getTestDocUri('src/Equatable.flix') | ||
const dateDocUri = getTestDocUri('src/Date.flix') | ||
const recordsDocUri = getTestDocUri('src/Records.flix') | ||
|
||
suiteSetup(async () => { | ||
await activate('rename') | ||
}) | ||
|
||
test('Renaming empty line should fail', async () => { | ||
await open(mainDocUri) | ||
const position = new vscode.Position(0, 0) | ||
const newName = 'NewName' | ||
assert.rejects(async () => { | ||
await vscode.commands.executeCommand<vscode.WorkspaceEdit>( | ||
'vscode.executeDocumentRenameProvider', | ||
mainDocUri, | ||
position, | ||
newName, | ||
) | ||
}) | ||
}) | ||
|
||
async function testRename( | ||
uri: vscode.Uri, | ||
position: vscode.Position, | ||
expectedRanges: [vscode.Uri, vscode.Range[]][], | ||
) { | ||
await open(uri) | ||
const newName = 'NewName' | ||
const r = await vscode.commands.executeCommand<vscode.WorkspaceEdit>( | ||
'vscode.executeDocumentRenameProvider', | ||
uri, | ||
position, | ||
newName, | ||
) | ||
|
||
const entries = r.entries() | ||
for (const [_uri, edits] of entries) { | ||
for (const edit of edits) { | ||
assert.strictEqual(edit.newText, newName) | ||
} | ||
} | ||
|
||
const actualRangesString: [string, vscode.Range[]][] = entries.map(([uri, edit]) => [ | ||
uri.toString(), | ||
edit.map(r => r.range), | ||
]) | ||
const expectedRangesString = expectedRanges.map(([uri, edit]) => [uri.toString(), edit]) | ||
|
||
assert.deepStrictEqual(actualRangesString.sort(), expectedRangesString.sort()) | ||
} | ||
|
||
test('Rename Shape.Circle case', async () => { | ||
await testRename(mainDocUri, new vscode.Position(3, 9), [ | ||
[mainDocUri, [new vscode.Range(3, 9, 3, 15), new vscode.Range(12, 52, 12, 58), new vscode.Range(17, 17, 17, 29)]], | ||
[areaDocUri, [new vscode.Range(5, 13, 5, 25)]], | ||
]) | ||
}) | ||
test('Rename Shape.Circle case-use', async () => { | ||
await testRename(mainDocUri, new vscode.Position(12, 52), [ | ||
[mainDocUri, [new vscode.Range(3, 9, 3, 15), new vscode.Range(12, 52, 12, 58), new vscode.Range(17, 17, 17, 29)]], | ||
[areaDocUri, [new vscode.Range(5, 13, 5, 25)]], | ||
]) | ||
}) | ||
test('Rename Shape.Circle case-use from pattern match', async () => { | ||
await testRename(mainDocUri, new vscode.Position(17, 23), [ | ||
[mainDocUri, [new vscode.Range(3, 9, 3, 15), new vscode.Range(12, 52, 12, 58), new vscode.Range(17, 17, 17, 29)]], | ||
[areaDocUri, [new vscode.Range(5, 13, 5, 25)]], | ||
]) | ||
}) | ||
|
||
test('Rename area function', async () => { | ||
await testRename(areaDocUri, new vscode.Position(3, 4), [ | ||
[areaDocUri, [new vscode.Range(3, 4, 3, 8), new vscode.Range(12, 39, 12, 43)]], | ||
[mainDocUri, [new vscode.Range(10, 12, 10, 16)]], | ||
]) | ||
}) | ||
test('Rename area function-use', async () => { | ||
await testRename(areaDocUri, new vscode.Position(12, 39), [ | ||
[areaDocUri, [new vscode.Range(3, 4, 3, 8), new vscode.Range(12, 39, 12, 43)]], | ||
[mainDocUri, [new vscode.Range(10, 12, 10, 16)]], | ||
]) | ||
}) | ||
|
||
test('Rename Day type alias', async () => { | ||
await testRename(dateDocUri, new vscode.Position(18, 11), [ | ||
[dateDocUri, [new vscode.Range(18, 11, 18, 14), new vscode.Range(21, 23, 21, 26)]], | ||
]) | ||
}) | ||
|
||
test('Rename function parameter', async () => { | ||
await testRename(equatableDocUri, new vscode.Position(6, 19), [ | ||
[equatableDocUri, [new vscode.Range(6, 19, 6, 20), new vscode.Range(7, 15, 7, 16)]], | ||
]) | ||
}) | ||
test('Rename function parameter-use', async () => { | ||
await testRename(equatableDocUri, new vscode.Position(7, 15), [ | ||
[equatableDocUri, [new vscode.Range(6, 19, 6, 20), new vscode.Range(7, 15, 7, 16)]], | ||
]) | ||
}) | ||
|
||
test('Rename match-extracted variable', async () => { | ||
await testRename(equatableDocUri, new vscode.Position(9, 23), [ | ||
[equatableDocUri, [new vscode.Range(9, 23, 9, 25), new vscode.Range(9, 58, 9, 60)]], | ||
]) | ||
}) | ||
test('Rename match-extracted variable-use', async () => { | ||
await testRename(equatableDocUri, new vscode.Position(9, 58), [ | ||
[equatableDocUri, [new vscode.Range(9, 23, 9, 25), new vscode.Range(9, 58, 9, 60)]], | ||
]) | ||
}) | ||
|
||
test('Rename let-bound variable', async () => { | ||
await testRename(equatableDocUri, new vscode.Position(20, 8), [ | ||
[equatableDocUri, [new vscode.Range(20, 8, 20, 13), new vscode.Range(22, 21, 22, 26)]], | ||
]) | ||
}) | ||
test('Rename let-bound variable-use', async () => { | ||
await testRename(equatableDocUri, new vscode.Position(22, 21), [ | ||
[equatableDocUri, [new vscode.Range(20, 8, 20, 13), new vscode.Range(22, 21, 22, 26)]], | ||
]) | ||
}) | ||
|
||
test('Rename record label', async () => { | ||
await testRename(recordsDocUri, new vscode.Position(3, 6), [ | ||
[ | ||
recordsDocUri, | ||
[ | ||
new vscode.Range(2, 13, 2, 14), | ||
new vscode.Range(2, 48, 2, 49), | ||
new vscode.Range(3, 6, 3, 7), | ||
new vscode.Range(13, 14, 13, 15), | ||
new vscode.Range(15, 7, 15, 8), | ||
new vscode.Range(15, 14, 15, 15), | ||
], | ||
], | ||
]) | ||
}) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
[package] | ||
name = "vscode-flix-test" | ||
description = "test" | ||
version = "0.1.0" | ||
flix = "0.44.0" | ||
authors = ["John Doe <john@example.com>"] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
// Blank line | ||
/// Computes the area of the given shape using | ||
/// pattern matching and basic arithmetic. | ||
def area(s: Shape): Int32 = { | ||
match s { | ||
case Shape.Circle(r) => 3 * r * r | ||
case Shape.Square(w) => w * w | ||
case Shape.Rectangle(h, w) => h * w | ||
} | ||
} | ||
|
||
@Test | ||
def testSquareArea(): Bool = Assert.eq(area(Shape.Square(5)), 25) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
// Blank line | ||
/// We derive the traits Eq, Order, and ToString for the enum Month | ||
enum Month with Eq, Order, ToString { | ||
case January | ||
case February | ||
case March | ||
case April | ||
case May | ||
case June | ||
case July | ||
case August | ||
case September | ||
case October | ||
case November | ||
case December | ||
} | ||
|
||
type alias Year = Int32 | ||
type alias Day = Int32 | ||
|
||
/// The Date type derives the traits Eq and Order | ||
enum Date(Year, Month, Day) with Eq, Order | ||
|
||
/// We implement our own instance of ToString for Date | ||
/// since we don't want the default "Date(1948, December, 10)" | ||
instance ToString[Date] { | ||
pub def toString(x: Date): String = | ||
let Date.Date(y, m, d) = x; | ||
"${d} ${m}, ${y}" | ||
} | ||
|
||
/// Thanks to the Eq and Order traits, we can easily compare dates. | ||
def earlierDate(d1: Date, d2: Date): Date = Order.min(d1, d2) | ||
|
||
/// Thanks to the ToString trait, we can easily convert dates to strings. | ||
def printDate(d: Date): Unit \ IO = | ||
let message = "The date is ${d}!"; | ||
println(message) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
// Blank line | ||
trait Equatable[t] { | ||
pub def equals(x: t, y: t): Bool | ||
} | ||
|
||
instance Equatable[Option[t]] with Equatable[t] { | ||
pub def equals(x: Option[t], y: Option[t]): Bool = | ||
match (x, y) { | ||
case (None, None) => true | ||
case (Some(v1), Some(v2)) => Equatable.equals(v1, v2) | ||
case _ => false | ||
} | ||
} | ||
|
||
instance Equatable[Int32] { | ||
pub def equals(x: Int32, y: Int32): Bool = x == y | ||
} | ||
|
||
@Test | ||
def testOptionEquatable01(): Bool = { | ||
let first = Some(1); | ||
let second = Some(1); | ||
Equatable.equals(first, second) | ||
} | ||
|
||
@Test | ||
def testOptionEquatable02(): Bool = { | ||
let first: Option[Int32] = None; | ||
let second: Option[Int32] = None; | ||
Equatable.equals(first, second) | ||
} | ||
|
||
@Test | ||
def testOptionEquatable03(): Bool = { | ||
let first = Some(1); | ||
let second: Option[Int32] = None; | ||
not Equatable.equals(first, second) | ||
} | ||
|
||
@Test | ||
def testOptionEquatable04(): Bool = { | ||
let first = Some(1); | ||
let second = Some(2); | ||
not Equatable.equals(first, second) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
// Blank line | ||
/// An algebraic data type for shapes. | ||
enum Shape { | ||
case Circle(Int32), // circle radius | ||
case Square(Int32), // side length | ||
case Rectangle(Int32, Int32) // height and width | ||
} | ||
|
||
/// Computes the area of a 2 by 4. | ||
def main(): Unit \ IO = | ||
println(area(Shape.Rectangle(2, 4))) | ||
|
||
def f(): Shape \ IO = println("Hello World"); Shape.Circle(5) | ||
|
||
instance ToString[Shape] { | ||
pub def toString(s: Shape): String = | ||
match s { | ||
case Shape.Circle(r) => "Circle(${r})" | ||
case Shape.Square(w) => "Square(${w})" | ||
case Shape.Rectangle(h, w) => "Rectangle(${h}, ${w})" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
// Blank line | ||
/// Returns the record `r` with a new value of its `x` label. | ||
def setX(r: {x = Int32, y = Int32}, v: Int32): {x = Int32, y = Int32} = | ||
{ x = v | r } | ||
|
||
/// Returns the record `r` with a new value of its `y` label. | ||
/// Preserves (retains) all other labels polymorphically. | ||
def setY(r: {y = Int32 | a}, v: Int32): {y = Int32 | a} = | ||
{ y = v | r } | ||
|
||
|
||
@Test | ||
def testRecords(): Bool = | ||
let r1 = {x = 1, y = 2}; | ||
let r2 = setX(r1, 3); | ||
r1.x + r2.x == 4 |