PublicInterfaceTests.cs 2.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. using System.Collections.Concurrent;
  2. using Jint.Native;
  3. using Jint.Native.Function;
  4. namespace Jint.Tests.PublicInterface;
  5. public class PublicInterfaceTests
  6. {
  7. [Fact]
  8. public void BindFunctionInstancesArePublic()
  9. {
  10. var engine = new Engine(options =>
  11. {
  12. options.AllowClr();
  13. });
  14. using var emulator = new SetTimeoutEmulator(engine);
  15. engine.SetValue("emulator", emulator);
  16. engine.Execute(@"
  17. var coolingObject = {
  18. coolDownTime: 1000,
  19. cooledDown: false
  20. }
  21. emulator.SetTimeout(function() {
  22. coolingObject.cooledDown = true;
  23. }.bind(coolingObject), coolingObject.coolDownTime);
  24. ");
  25. }
  26. private sealed class SetTimeoutEmulator : IDisposable
  27. {
  28. private readonly Engine _engine;
  29. private readonly ConcurrentQueue<JsValue> _queue = new();
  30. private readonly Task _queueProcessor;
  31. private readonly CancellationTokenSource _quit = new();
  32. private bool _disposedValue;
  33. public SetTimeoutEmulator(Engine engine)
  34. {
  35. _engine = engine ?? throw new ArgumentNullException(nameof(engine));
  36. _queueProcessor = Task.Run(() =>
  37. {
  38. while (!_quit.IsCancellationRequested)
  39. {
  40. while (_queue.TryDequeue(out var queueEntry))
  41. {
  42. lock (_engine)
  43. {
  44. if (queueEntry is FunctionInstance fi)
  45. {
  46. _engine.Invoke(fi);
  47. }
  48. else if (queueEntry is BindFunctionInstance bfi)
  49. {
  50. _engine.Invoke(bfi);
  51. }
  52. else
  53. {
  54. _engine.Execute(queueEntry.ToString());
  55. }
  56. }
  57. }
  58. }
  59. });
  60. }
  61. public void SetTimeout(JsValue script, object timeout)
  62. {
  63. _queue.Enqueue(script);
  64. }
  65. private void Dispose(bool disposing)
  66. {
  67. if (!_disposedValue)
  68. {
  69. if (disposing)
  70. {
  71. // TODO: dispose managed state (managed objects)
  72. _quit.Cancel();
  73. _queueProcessor.Wait();
  74. }
  75. _disposedValue = true;
  76. }
  77. }
  78. public void Dispose()
  79. {
  80. // Do not change this code. Put cleanup code in 'Dispose(bool disposing)' method
  81. Dispose(disposing: true);
  82. GC.SuppressFinalize(this);
  83. }
  84. }
  85. }