ConstructorTests.cs 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. using Jint.Native;
  2. using Jint.Native.Object;
  3. using Jint.Runtime;
  4. using Jint.Runtime.Interop;
  5. namespace Jint.Tests.PublicInterface;
  6. public class ConstructorTests
  7. {
  8. private readonly Engine _engine;
  9. public ConstructorTests()
  10. {
  11. _engine = new Engine();
  12. _engine.SetValue("DateOnly", new DateOnlyConstructor(_engine));
  13. }
  14. [Fact]
  15. public void CanConstructWithParameters()
  16. {
  17. var wrapper = (IObjectWrapper) _engine.Evaluate("new DateOnly(1982, 6, 28);");
  18. var date = (DateOnly) wrapper.Target;
  19. Assert.Equal(1982, date.Year);
  20. Assert.Equal(6, date.Month);
  21. Assert.Equal(28, date.Day);
  22. Assert.Equal(1982, _engine.Evaluate("new DateOnly(1982, 6, 28).year").AsNumber());
  23. Assert.Equal(6, _engine.Evaluate("new DateOnly(1982, 6, 28).month").AsNumber());
  24. Assert.Equal(28, _engine.Evaluate("new DateOnly(1982, 6, 28).day").AsNumber());
  25. }
  26. [Fact]
  27. public void CanConstructWithoutParameters()
  28. {
  29. Assert.Equal(DateTime.Today.Year, _engine.Evaluate("new DateOnly().year").AsNumber());
  30. Assert.Equal(DateTime.Today.Month, _engine.Evaluate("new DateOnly().month").AsNumber());
  31. Assert.Equal(DateTime.Today.Day, _engine.Evaluate("new DateOnly().day").AsNumber());
  32. }
  33. [Fact]
  34. public void CallThrows()
  35. {
  36. var ex = Assert.Throws<JavaScriptException>(() => _engine.Evaluate("DateOnly(1982, 6, 28);"));
  37. Assert.Equal("Constructor DateOnly requires 'new'", ex.Message);
  38. }
  39. [Fact]
  40. public void CanThrowTypeError()
  41. {
  42. var ex = Assert.Throws<JavaScriptException>(() => _engine.Evaluate("new DateOnly(undefined, 1, 1);"));
  43. Assert.Equal("Invalid year NaN", ex.Message);
  44. }
  45. }
  46. file sealed class DateOnlyConstructor : Constructor
  47. {
  48. public DateOnlyConstructor(Engine engine) : base(engine, engine.Realm, (JsString) "DateOnly")
  49. {
  50. }
  51. public override ObjectInstance Construct(JsValue[] arguments, JsValue newTarget)
  52. {
  53. DateOnly result;
  54. if (arguments.Length == 0)
  55. {
  56. result = new DateOnly(DateTime.Today);
  57. }
  58. else if (arguments.Length == 1)
  59. {
  60. var days = TypeConverter.ToNumber(arguments[0]);
  61. var ticks = (long) (days * TimeSpan.TicksPerDay);
  62. result = new DateOnly(new DateTime(ticks));
  63. }
  64. else
  65. {
  66. var year = TypeConverter.ToNumber(arguments.At(0));
  67. var month = TypeConverter.ToNumber(arguments.At(1)) - 1;
  68. var day = arguments.Length == 2 ? 0 : TypeConverter.ToNumber(arguments[2]) - 1;
  69. if (double.IsNaN(year))
  70. {
  71. throw new JavaScriptException(_engine.Realm.Intrinsics.TypeError, "Invalid year " + year);
  72. }
  73. if (double.IsNaN(month))
  74. {
  75. throw new JavaScriptException(_engine.Realm.Intrinsics.TypeError, "Invalid month " + month);
  76. }
  77. if (double.IsNaN(day))
  78. {
  79. throw new JavaScriptException(_engine.Realm.Intrinsics.TypeError, "Invalid day " + day);
  80. }
  81. var dt = new DateTime((int) year, 1, 1);
  82. dt = dt.AddMonths((int) month);
  83. dt = dt.AddDays((int) day);
  84. result = new DateOnly(dt);
  85. }
  86. return (ObjectInstance) FromObject(_engine, result);
  87. }
  88. }
  89. file sealed class DateOnly
  90. {
  91. internal DateOnly(DateTime value)
  92. {
  93. Year = value.Year;
  94. Month = value.Month;
  95. Day = value.Day;
  96. }
  97. public JsValue Year { get; set; }
  98. public JsValue Month { get; set; }
  99. public JsValue Day { get; set; }
  100. }