Skip to content

Commit

Permalink
Add support for wrapped lists to push and pop items (#1822)
Browse files Browse the repository at this point in the history
  • Loading branch information
ejsmith authored Apr 1, 2024
1 parent 198f4f7 commit 3209ab3
Show file tree
Hide file tree
Showing 3 changed files with 79 additions and 2 deletions.
42 changes: 42 additions & 0 deletions Jint.Tests/Runtime/InteropTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2913,6 +2913,48 @@ public void ArrayPrototypeIndexOfWithInteropList()
Assert.Equal(1, engine.Evaluate("Array.prototype.lastIndexOf.call(list, 'B')"));
}

[Fact]
public void ArrayPrototypeFindWithInteropList()
{
var engine = new Jint.Engine();
var list = new List<string> { "A", "B", "C" };

engine.SetValue("list", list);

Assert.Equal(1, engine.Evaluate("list.findIndex((x) => x === 'B')"));
Assert.Equal('B', engine.Evaluate("list.find((x) => x === 'B')"));
}

[Fact]
public void ArrayPrototypePushWithInteropList()
{
var engine = new Jint.Engine();

var list = new List<string> { "A", "B", "C" };

engine.SetValue("list", list);

engine.Evaluate("list.push('D')");
Assert.Equal(4, list.Count);
Assert.Equal("D", list[3]);
Assert.Equal(3, engine.Evaluate("list.lastIndexOf('D')"));
}

[Fact]
public void ArrayPrototypePopWithInteropList()
{
var engine = new Jint.Engine();

var list = new List<string> { "A", "B", "C" };
engine.SetValue("list", list);

Assert.Equal(2, engine.Evaluate("list.lastIndexOf('C')"));
Assert.Equal(3, list.Count);
Assert.Equal("C", engine.Evaluate("list.pop()"));
Assert.Equal(2, list.Count);
Assert.Equal(-1, engine.Evaluate("list.lastIndexOf('C')"));
}

[Fact]
public void ShouldBeJavaScriptException()
{
Expand Down
29 changes: 27 additions & 2 deletions Jint/Native/Array/ArrayOperations.cs
Original file line number Diff line number Diff line change
Expand Up @@ -493,7 +493,25 @@ public IndexWrappedOperations(ObjectWrapper wrapper)

public override ulong GetLongLength() => GetLength();

public override void SetLength(ulong length) => throw new NotSupportedException();
public override void SetLength(ulong length)
{
if (_list == null)
{
throw new NotSupportedException();
}

while (_list.Count > (int) length)
{
// shrink list to fit
_list.RemoveAt(_list.Count - 1);
}

while (_list.Count < (int) length)
{
// expand list to fit
_list.Add(null);
}
}

public override void EnsureCapacity(ulong capacity)
{
Expand Down Expand Up @@ -530,7 +548,14 @@ public override void CreateDataPropertyOrThrow(ulong index, JsValue value)
=> _target.CreateDataPropertyOrThrow(index, value);

public override void Set(ulong index, JsValue value, bool updateLength = false, bool throwOnError = true)
=> _target[(int) index] = value;
{
if (updateLength && _list != null && index >= (ulong) _list.Count)
{
SetLength(index + 1);
}

_target[(int) index] = value;
}

public override void DeletePropertyOrThrow(ulong index)
=> _target.DeletePropertyOrThrow(index);
Expand Down
10 changes: 10 additions & 0 deletions Jint/Runtime/Interop/ObjectWrapper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,16 @@ public override bool HasProperty(JsValue property)
return base.HasProperty(property);
}

public override bool Delete(JsValue property)
{
if (Target is IList && property.IsNumber())
{
return true;
}

return base.Delete(property);
}

public override JsValue Get(JsValue property, JsValue receiver)
{
if (property.IsInteger())
Expand Down

0 comments on commit 3209ab3

Please sign in to comment.