ConstructorTests.cs 3.7 KB

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