Skip to content

Commit

Permalink
Ensure support for custom null and undefined (#1407)
Browse files Browse the repository at this point in the history
  • Loading branch information
lahma authored Jan 18, 2023
1 parent 4839fd1 commit 81cfbc0
Show file tree
Hide file tree
Showing 4 changed files with 85 additions and 38 deletions.
117 changes: 84 additions & 33 deletions Jint.Tests.PublicInterface/RavenApiUsageTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using Jint.Constraints;
using Jint.Native;
using Jint.Native.Function;
using Jint.Runtime;
using Jint.Runtime.Descriptors;
using Jint.Runtime.Interop;

Expand Down Expand Up @@ -96,7 +97,7 @@ public void CanInjectConstructedObjects()

TestArrayAccess(engine, array1, "array1");

var array3 = new JsArray(engine, new []
var array3 = new JsArray(engine, new[]
{
new PropertyDescriptor(JsNumber.Create(1), true, true, true),
new PropertyDescriptor(JsNumber.Create(2), true, true, true),
Expand Down Expand Up @@ -206,47 +207,97 @@ public void CanInheritCustomString()
Assert.True(engine.Evaluate("empty.trimEnd() === ''").AsBoolean());
}

private sealed class CustomString : JsString
[Fact]
public void CanDefineCustomNull()
{
private readonly string _value;
var engine = new Engine();
engine.SetValue("value", new CustomNull());
Assert.Equal("foo", engine.Evaluate("value ? value + 'bar' : 'foo'"));
}

public CustomString(string value) : base(null)
{
_value = value;
}
[Fact]
public void CanDefineCustomUndefined()
{
var engine = new Engine();
engine.SetValue("value", new CustomUndefined());
Assert.Equal("foo", engine.Evaluate("value ? value + 'bar' : 'foo'"));
}
}

public override string ToString()
{
// when called we know that we couldn't use fast paths
throw new InvalidOperationException("I don't want to be materialized!");
}
file sealed class CustomString : JsString
{
private readonly string _value;

public override char this[int index] => _value[index];
public CustomString(string value) : base(null)
{
_value = value;
}

public override int Length => _value.Length;
public override string ToString()
{
// when called we know that we couldn't use fast paths
throw new InvalidOperationException("I don't want to be materialized!");
}

public override bool Equals(JsString obj)
{
return obj switch
{
CustomString customString => _value == customString._value,
_ => _value == obj.ToString()
};
}
public override char this[int index] => _value[index];

public override int Length => _value.Length;

public override bool IsLooselyEqual(JsValue value)
public override bool Equals(JsString obj)
{
return obj switch
{
return value switch
{
CustomString customString => _value == customString._value,
JsString jsString => _value == jsString.ToString(),
_ => base.IsLooselyEqual(value)
};
}
CustomString customString => _value == customString._value,
_ => _value == obj.ToString()
};
}

public override int GetHashCode()
public override bool IsLooselyEqual(JsValue value)
{
return value switch
{
return _value.GetHashCode();
}
CustomString customString => _value == customString._value,
JsString jsString => _value == jsString.ToString(),
_ => base.IsLooselyEqual(value)
};
}

public override int GetHashCode()
{
return _value.GetHashCode();
}
}

file sealed class CustomNull : JsValue
{
public CustomNull() : base(Types.Null)
{
}

public override object ToObject()
{
return null;
}

public override string ToString()
{
return "null";
}
}

file sealed class CustomUndefined : JsValue
{
public CustomUndefined() : base(Types.Null)
{
}

public override object ToObject()
{
return null;
}

public override string ToString()
{
return "null";
}
}
2 changes: 0 additions & 2 deletions Jint/Native/JsNull.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,6 @@ internal JsNull() : base(Types.Null)

public override object ToObject() => null!;

internal override bool ToBoolean() => false;

public override string ToString() => "null";

public override bool IsLooselyEqual(JsValue value)
Expand Down
2 changes: 0 additions & 2 deletions Jint/Native/JsUndefined.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,6 @@ internal JsUndefined() : base(Types.Undefined)

public override object ToObject() => null!;

internal override bool ToBoolean() => false;

public override string ToString() => "undefined";

public override bool IsLooselyEqual(JsValue value)
Expand Down
2 changes: 1 addition & 1 deletion Jint/Native/JsValue.cs
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ public static JsValue FromObject(Engine engine, object? value)
/// <summary>
/// Coerces boolean value from <see cref="JsValue"/> instance.
/// </summary>
internal virtual bool ToBoolean() => true;
internal virtual bool ToBoolean() => _type > InternalTypes.Null;

/// <summary>
/// Invoke the current value as function.
Expand Down

0 comments on commit 81cfbc0

Please sign in to comment.