Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(stdlib): Add lookupCI for assocarray and Node #639

Merged
merged 14 commits into from
Apr 30, 2021
19 changes: 17 additions & 2 deletions src/brsTypes/components/RoAssociativeArray.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ export class RoAssociativeArray extends BrsComponent implements BrsValue, BrsIte
this.keys,
this.items,
this.lookup,
this.lookupCI,
this.setmodecasesensitive,
],
ifEnum: [this.isEmpty],
Expand Down Expand Up @@ -77,7 +78,7 @@ export class RoAssociativeArray extends BrsComponent implements BrsValue, BrsIte
.map((value: BrsType) => value);
}

get(index: BrsType) {
get(index: BrsType, forceCaseInsensitive = false) {
if (index.kind !== ValueKind.String) {
throw new Error("Associative array indexes must be strings");
}
Expand All @@ -93,7 +94,10 @@ export class RoAssociativeArray extends BrsComponent implements BrsValue, BrsIte
// method with the desired name separately? That last bit would work but it's pretty gross.
// That'd allow roArrays to have methods with the methods not accessible via `arr["count"]`.
// Same with RoAssociativeArrays I guess.
let indexValue = this.modeCaseSensitive ? index.value : index.value.toLowerCase();
let indexValue =
this.modeCaseSensitive && !forceCaseInsensitive
? index.value
: index.value.toLowerCase();
return this.elements.get(indexValue) || this.getMethod(index.value) || BrsInvalid.Instance;
}

Expand Down Expand Up @@ -235,6 +239,17 @@ export class RoAssociativeArray extends BrsComponent implements BrsValue, BrsIte
},
});

private lookupCI = new Callable("lookupCI", {
signature: {
args: [new StdlibArgument("key", ValueKind.String)],
returns: ValueKind.Dynamic,
},
impl: (interpreter: Interpreter, key: BrsString) => {
let lKey = key.value;
return this.get(new BrsString(lKey), true);
},
});

/** Changes the sensitive case method for lookups */
private setmodecasesensitive = new Callable("setModeCaseSensitive", {
signature: {
Expand Down
3 changes: 3 additions & 0 deletions src/brsTypes/components/RoSGNode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -327,6 +327,7 @@ export class RoSGNode extends BrsComponent implements BrsValue, BrsIterable {
this.keys,
this.items,
this.lookup,
this.lookupCI,
],
ifSGNodeField: [
this.addfield,
Expand Down Expand Up @@ -801,6 +802,8 @@ export class RoSGNode extends BrsComponent implements BrsValue, BrsIterable {
},
});

private lookupCI = new Callable("lookupCI", this.lookup.signatures[0]);

/** Adds a new field to the node, if the field already exists it doesn't change the current value. */
private addfield = new Callable("addfield", {
signature: {
Expand Down
14 changes: 14 additions & 0 deletions test/brsTypes/components/RoAssociativeArray.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -372,6 +372,20 @@ describe("RoAssociativeArray", () => {

result2 = aa.get(new BrsString("KeY2"));
expect(result2).toBe(v2);

// check lookupCI method
let lookupCI = aa.getMethod("lookupCI");
expect(lookupCI).toBeTruthy();

addreplace.call(interpreter, new BrsString("key2"), v1);
let result = lookup.call(interpreter, new BrsString("key2"));
expect(result).toBe(v1);

result = lookupCI.call(interpreter, new BrsString("KEY2"));
expect(result).toBe(v1);

result = lookupCI.call(interpreter, new BrsString("Key2"));
expect(result).toBe(v1);
});
});
});
Expand Down
2 changes: 2 additions & 0 deletions test/e2e/BrsComponents.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@ describe("end to end brightscript functions", () => {
"true",
"can look up elements (brackets): ",
"true",
"can case insensitive look up elements: ",
"true",
"can check for existence: ",
"true",
"items() example key: ",
Expand Down
2 changes: 2 additions & 0 deletions test/e2e/RoSGNode.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,8 @@ describe("components/roSGNode", () => {
"true",
"can look up elements (brackets): ",
"true",
"can case insensitive look up elements: ",
"true",
"can check for existence: ",
"true",
"can empty itself: ",
Expand Down
1 change: 1 addition & 0 deletions test/e2e/resources/components/roAssociativeArray.brs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ sub main()
print "can delete elements: " aa.delete("baz") ' => true
print "can look up elements: " aa.lookup("foo") = "foo" ' => true
print "can look up elements (brackets): " aa["foo"] = "foo" ' => true
print "can case insensitive look up elements: " aa.lookupCI("foO") = "foo" ' => true
print "can check for existence: " aa.doesExist("bar") ' => true
print "items() example key: " aa.items()[0].key ' => bar
print "items() example value: " aa.items()[0].value ' => 5
Expand Down
1 change: 1 addition & 0 deletions test/e2e/resources/components/roSGNode/roSGNode.brs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ sub init()
print "can delete elements: " node1.delete("baz") ' => true
print "can look up elements: " node1.lookup("foo") = "foo" ' => true
print "can look up elements (brackets): " node1["foo"] = "foo" ' => true
print "can case insensitive look up elements: " node1.lookupCI("foO") = "foo" ' => true
print "can check for existence: " node1.doesExist("bar") ' => true

node1.clear()
Expand Down