Skip to content

Commit

Permalink
chore(sdk): add out of bounds exception to string.at (#3312)
Browse files Browse the repository at this point in the history
Adds exception to `string.at` if index is out of bounds.

closes #3240 

## Checklist

- [x] Title matches [Winglang's style guide](https://www.winglang.io/contributing/start-here/pull_requests#how-are-pull-request-titles-formatted)
- [x] Description explains motivation and solution
- [x] Tests added (always)
- [ ] Docs updated (only required for features)
- [ ] Added `pr/e2e-full` label if this feature requires end-to-end testing

*By submitting this pull request, I confirm that my contribution is made under the terms of the [Monada Contribution License](https://www.winglang.io/terms-and-policies/contribution-license.html)*.
  • Loading branch information
fynnfluegge authored Jul 10, 2023
1 parent 210e492 commit 36f5a20
Show file tree
Hide file tree
Showing 4 changed files with 50 additions and 11 deletions.
15 changes: 12 additions & 3 deletions examples/tests/sdk_tests/std/string.w
Original file line number Diff line number Diff line change
Expand Up @@ -39,19 +39,28 @@ test "length" {
//-----------------------------------------------------------------------------
// at()

let INDEX_OUT_OF_BOUNDS_ERROR = "index out of bounds";

assert("boom".at(2) == "o");
// Negative integers count back from the last string character.
assert("boom".at(-4) == "b");
assert("boom".at(-1) == "m");
// Should throw an exception
assertThrows(INDEX_OUT_OF_BOUNDS_ERROR, () => {
"boom".at(4);
});
assertThrows(INDEX_OUT_OF_BOUNDS_ERROR, () => {
"boom".at(-5);
});

test "at()" {
assert("boom".at(0) == "b");
// Negative integers count back from the last string character.
assert("boom".at(-4) == "b");
assert("boom".at(-1) == "m");

// Should throw an exception instead of returns undefined see issue #3240
// assert("boom".at(-10) == "m");
// Should throw an exception
try { "boom".at(4); } catch s { assert(s == INDEX_OUT_OF_BOUNDS_ERROR ); } // <-- Passes if no exception is thrown, see issue #3341
try { "boom".at(-5); } catch s { assert(s == INDEX_OUT_OF_BOUNDS_ERROR ); }
}

//-----------------------------------------------------------------------------
Expand Down
2 changes: 2 additions & 0 deletions libs/wingsdk/src/std/string.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@ export class String {
/**
* Returns the character at the specified index.
*
* @macro ((args) => { if ($args$ >= $self$.length || $args$ + $self$.length < 0) {throw new Error("index out of bounds")}; return $self$.at($args$) })($args$)
*
* @param index position of the character.
* @returns string at the specified index.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -126,17 +126,31 @@ module.exports = function({ }) {

## inflight.$Closure3.js
```js
module.exports = function({ }) {
module.exports = function({ $INDEX_OUT_OF_BOUNDS_ERROR }) {
class $Closure3 {
constructor({ }) {
const $obj = (...args) => this.handle(...args);
Object.setPrototypeOf($obj, this);
return $obj;
}
async handle() {
{((cond) => {if (!cond) throw new Error("assertion failed: \"boom\".at(0) == \"b\"")})(((await "boom".at(0)) === "b"))};
{((cond) => {if (!cond) throw new Error("assertion failed: \"boom\".at(-4) == \"b\"")})(((await "boom".at((-4))) === "b"))};
{((cond) => {if (!cond) throw new Error("assertion failed: \"boom\".at(-1) == \"m\"")})(((await "boom".at((-1))) === "m"))};
{((cond) => {if (!cond) throw new Error("assertion failed: \"boom\".at(0) == \"b\"")})((((args) => { if (0 >= "boom".length || 0 + "boom".length < 0) {throw new Error("index out of bounds")}; return "boom".at(0) })(0) === "b"))};
{((cond) => {if (!cond) throw new Error("assertion failed: \"boom\".at(-4) == \"b\"")})((((args) => { if ((-4) >= "boom".length || (-4) + "boom".length < 0) {throw new Error("index out of bounds")}; return "boom".at((-4)) })((-4)) === "b"))};
{((cond) => {if (!cond) throw new Error("assertion failed: \"boom\".at(-1) == \"m\"")})((((args) => { if ((-1) >= "boom".length || (-1) + "boom".length < 0) {throw new Error("index out of bounds")}; return "boom".at((-1)) })((-1)) === "m"))};
try {
((args) => { if (4 >= "boom".length || 4 + "boom".length < 0) {throw new Error("index out of bounds")}; return "boom".at(4) })(4);
}
catch ($error_s) {
const s = $error_s.message;
{((cond) => {if (!cond) throw new Error("assertion failed: s == INDEX_OUT_OF_BOUNDS_ERROR ")})((s === $INDEX_OUT_OF_BOUNDS_ERROR))};
}
try {
((args) => { if ((-5) >= "boom".length || (-5) + "boom".length < 0) {throw new Error("index out of bounds")}; return "boom".at((-5)) })((-5));
}
catch ($error_s) {
const s = $error_s.message;
{((cond) => {if (!cond) throw new Error("assertion failed: s == INDEX_OUT_OF_BOUNDS_ERROR ")})((s === $INDEX_OUT_OF_BOUNDS_ERROR))};
}
}
}
return $Closure3;
Expand Down Expand Up @@ -1254,6 +1268,7 @@ class $Root extends $stdlib.std.Resource {
static _toInflightType(context) {
return $stdlib.core.NodeJsCode.fromInline(`
require("./inflight.$Closure3.js")({
$INDEX_OUT_OF_BOUNDS_ERROR: ${context._lift(INDEX_OUT_OF_BOUNDS_ERROR)},
})
`);
}
Expand All @@ -1268,6 +1283,12 @@ class $Root extends $stdlib.std.Resource {
})())
`);
}
_registerBind(host, ops) {
if (ops.includes("handle")) {
$Closure3._registerBindObject(INDEX_OUT_OF_BOUNDS_ERROR, host, []);
}
super._registerBind(host, ops);
}
}
class $Closure4 extends $stdlib.std.Resource {
constructor(scope, id, ) {
Expand Down Expand Up @@ -1530,9 +1551,16 @@ class $Root extends $stdlib.std.Resource {
{((cond) => {if (!cond) throw new Error("assertion failed: \"hello\".length == 5")})(("hello".length === 5))};
{((cond) => {if (!cond) throw new Error("assertion failed: \"\".length == 0")})(("".length === 0))};
this.node.root.new("@winglang/sdk.std.Test",std.Test,this,"test:length",new $Closure2(this,"$Closure2"));
{((cond) => {if (!cond) throw new Error("assertion failed: \"boom\".at(2) == \"o\"")})((("boom".at(2)) === "o"))};
{((cond) => {if (!cond) throw new Error("assertion failed: \"boom\".at(-4) == \"b\"")})((("boom".at((-4))) === "b"))};
{((cond) => {if (!cond) throw new Error("assertion failed: \"boom\".at(-1) == \"m\"")})((("boom".at((-1))) === "m"))};
const INDEX_OUT_OF_BOUNDS_ERROR = "index out of bounds";
{((cond) => {if (!cond) throw new Error("assertion failed: \"boom\".at(2) == \"o\"")})((((args) => { if (2 >= "boom".length || 2 + "boom".length < 0) {throw new Error("index out of bounds")}; return "boom".at(2) })(2) === "o"))};
{((cond) => {if (!cond) throw new Error("assertion failed: \"boom\".at(-4) == \"b\"")})((((args) => { if ((-4) >= "boom".length || (-4) + "boom".length < 0) {throw new Error("index out of bounds")}; return "boom".at((-4)) })((-4)) === "b"))};
{((cond) => {if (!cond) throw new Error("assertion failed: \"boom\".at(-1) == \"m\"")})((((args) => { if ((-1) >= "boom".length || (-1) + "boom".length < 0) {throw new Error("index out of bounds")}; return "boom".at((-1)) })((-1)) === "m"))};
(assertThrows(INDEX_OUT_OF_BOUNDS_ERROR,(() => {
((args) => { if (4 >= "boom".length || 4 + "boom".length < 0) {throw new Error("index out of bounds")}; return "boom".at(4) })(4);
})));
(assertThrows(INDEX_OUT_OF_BOUNDS_ERROR,(() => {
((args) => { if ((-5) >= "boom".length || (-5) + "boom".length < 0) {throw new Error("index out of bounds")}; return "boom".at((-5)) })((-5));
})));
this.node.root.new("@winglang/sdk.std.Test",std.Test,this,"test:at()",new $Closure3(this,"$Closure3"));
{((cond) => {if (!cond) throw new Error("assertion failed: \"boom\".concat(\"boom\") == \"boomboom\"")})((("boom".concat("boom")) === "boomboom"))};
this.node.root.new("@winglang/sdk.std.Test",std.Test,this,"test:concat()",new $Closure4(this,"$Closure4"));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,7 @@ class $Root extends $stdlib.std.Resource {
const s1 = "some string";
const s2 = "s are immutable";
{((cond) => {if (!cond) throw new Error("assertion failed: s1.length == 11")})((s1.length === 11))};
{((cond) => {if (!cond) throw new Error("assertion failed: s1.at(7) == \"r\"")})(((s1.at(7)) === "r"))};
{((cond) => {if (!cond) throw new Error("assertion failed: s1.at(7) == \"r\"")})((((args) => { if (7 >= s1.length || 7 + s1.length < 0) {throw new Error("index out of bounds")}; return s1.at(7) })(7) === "r"))};
{((cond) => {if (!cond) throw new Error("assertion failed: s1.concat(s2) == \"some strings are immutable\"")})(((s1.concat(s2)) === "some strings are immutable"))};
{((cond) => {if (!cond) throw new Error("assertion failed: s1.contains(\"some\")")})(s1.includes("some"))};
{((cond) => {if (!cond) throw new Error("assertion failed: !\"some\".contains(s1)")})((!"some".includes(s1)))};
Expand Down

0 comments on commit 36f5a20

Please sign in to comment.