LCOV - code coverage report
Current view: top level - modules/esm - _timers.js (source / functions) Coverage Total Hit
Test: gjs- Code Coverage Lines: 97.1 % 70 68
Test Date: 2024-04-20 17:42:51 Functions: 100.0 % 13 13
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 73.1 % 26 19

             Branch data     Line data    Source code
       1                 :          47 : // SPDX-License-Identifier: MIT OR LGPL-2.0-or-later
       2                 :             : // SPDX-FileCopyrightText: 2021 Evan Welsh <contact@evanwelsh.com>
       3                 :             : 
       4                 :             : /* exported setTimeout, setInterval, clearTimeout, clearInterval */
       5                 :             : /* eslint no-implicit-coercion: ["error", {"allow": ["+"]}] */
       6                 :             : // Note: implicit coercion with + is used to perform the ToNumber algorithm from
       7                 :             : // the timers specification
       8                 :             : 
       9                 :             : /**
      10                 :             :  * @param {number} delay a number value (in milliseconds)
      11                 :             :  */
      12                 :       10067 : function validateDelay(delay) {
      13                 :             :     // |0 always returns a signed 32-bit integer.
      14                 :       10067 :     return Math.max(0, +delay | 0);
      15                 :             : }
      16                 :             : 
      17                 :             : /** @type {Map<GLib.Source, number>} */
      18                 :          47 : const timeouts = new Map();
      19                 :             : 
      20                 :             : /**
      21                 :             :  * @param {GLib.Source} source the source to add to our map
      22                 :             :  */
      23                 :       10807 : function addSource(source) {
      24                 :       10807 :     const id = source.attach(null);
      25                 :       10807 :     timeouts.set(source, id);
      26                 :             : }
      27                 :             : 
      28                 :             : /**
      29                 :             :  * @param {GLib.Source} source the source object to remove from our map
      30                 :             :  */
      31                 :       10156 : function releaseSource(source) {
      32                 :       10156 :     timeouts.delete(source);
      33                 :             : }
      34                 :             : 
      35                 :             : /**
      36                 :             :  * @param {unknown} thisArg 'this' argument
      37                 :             :  * @returns {asserts thisArg is (null | undefined | typeof globalThis)}
      38                 :             :  */
      39                 :       10065 : function checkThis(thisArg) {
      40 [ +  + ][ +  + ]:       10065 :     if (thisArg !== null && thisArg !== undefined && thisArg !== globalThis)
                 [ +  + ]
      41                 :           9 :         throw new TypeError('Illegal invocation');
      42                 :             : }
      43                 :             : 
      44                 :             : /**
      45                 :             :  * @param {number} timeout a timeout in milliseconds
      46                 :             :  * @param {(...args) => any} handler a callback
      47                 :             :  * @returns {GLib.Source}
      48                 :             :  */
      49                 :       10801 : function createTimeoutSource(timeout, handler) {
      50                 :       10801 :     const source = imports.gi.GLib.timeout_source_new(timeout);
      51                 :       10801 :     source.set_priority(imports.gi.GLib.PRIORITY_DEFAULT);
      52                 :       10801 :     imports.gi.GObject.source_set_closure(source, handler);
      53                 :             : 
      54                 :       10801 :     return source;
      55                 :       10801 : }
      56                 :             : 
      57                 :             : /**
      58                 :             :  * @this {typeof globalThis}
      59                 :             :  * @param {(...args) => any} callback a callback function
      60                 :             :  * @param {number} delay the duration in milliseconds to wait before running callback
      61                 :             :  * @param {...any} args arguments to pass to callback
      62                 :             :  */
      63         [ +  + ]:       10768 : function setTimeout(callback, delay = 0, ...args) {
      64                 :       10768 :     checkThis(this);
      65                 :             : 
      66                 :       10759 :     delay = validateDelay(delay);
      67         [ +  + ]:       10759 :     const boundCallback = callback.bind(globalThis, ...args);
      68                 :       10769 :     const source = createTimeoutSource(delay, () => {
      69         [ +  - ]:        7813 :         if (!timeouts.has(source))
      70                 :           0 :             return imports.gi.GLib.SOURCE_REMOVE;
      71                 :             : 
      72                 :        7813 :         boundCallback();
      73                 :        7813 :         releaseSource(source);
      74                 :        7813 :         import.meta.importSync('_promiseNative').drainMicrotaskQueue();
      75                 :             : 
      76                 :        7813 :         return imports.gi.GLib.SOURCE_REMOVE;
      77                 :             :     });
      78                 :             : 
      79                 :       10769 :     addSource(source);
      80                 :       10769 :     return source;
      81                 :       10769 : }
      82                 :             : 
      83                 :             : /**
      84                 :             :  * @this {typeof globalThis}
      85                 :             :  * @param {(...args) => any} callback a callback function
      86                 :             :  * @param {number} delay the duration in milliseconds to wait between calling callback
      87                 :             :  * @param {...any} args arguments to pass to callback
      88                 :             :  */
      89         [ +  - ]:           2 : function setInterval(callback, delay = 0, ...args) {
      90                 :           2 :     checkThis(this);
      91                 :             : 
      92                 :           2 :     delay = validateDelay(delay);
      93         [ +  - ]:           2 :     const boundCallback = callback.bind(globalThis, ...args);
      94                 :           2 :     const source = createTimeoutSource(delay, () => {
      95         [ +  - ]:           1 :         if (!timeouts.has(source))
      96                 :           0 :             return imports.gi.GLib.SOURCE_REMOVE;
      97                 :             : 
      98                 :           1 :         boundCallback();
      99                 :           1 :         import.meta.importSync('_promiseNative').drainMicrotaskQueue();
     100                 :             : 
     101                 :           1 :         return imports.gi.GLib.SOURCE_CONTINUE;
     102                 :             :     });
     103                 :             : 
     104                 :           2 :     addSource(source);
     105                 :           2 :     return source;
     106                 :           2 : }
     107                 :             : 
     108                 :             : /**
     109                 :             :  * @param {GLib.Source} source the timeout to clear
     110                 :             :  */
     111                 :        3531 : function _clearTimer(source) {
     112         [ +  + ]:        3531 :     if (!timeouts.has(source))
     113                 :           3 :         return;
     114                 :             : 
     115         [ -  + ]:        3528 :     if (source) {
     116                 :        3528 :         source.destroy();
     117                 :        3528 :         releaseSource(source);
     118                 :             :     }
     119                 :             : }
     120                 :             : 
     121                 :             : /**
     122                 :             :  * @param {GLib.Source} timeout the timeout to clear
     123                 :             :  */
     124         [ +  - ]:        3527 : function clearTimeout(timeout = null) {
     125                 :        3527 :     _clearTimer(timeout);
     126                 :             : }
     127                 :             : 
     128                 :             : /**
     129                 :             :  * @param {Glib.Source} timeout the timeout to clear
     130                 :             :  */
     131         [ +  - ]:           4 : function clearInterval(timeout = null) {
     132                 :           4 :     _clearTimer(timeout);
     133                 :             : }
     134                 :             : 
     135                 :          94 : Object.defineProperty(globalThis, 'setTimeout', {
     136                 :          47 :     configurable: false,
     137                 :          47 :     enumerable: true,
     138                 :          47 :     writable: true,
     139                 :          47 :     value: setTimeout,
     140                 :             : });
     141                 :             : 
     142                 :          94 : Object.defineProperty(globalThis, 'setInterval', {
     143                 :          47 :     configurable: false,
     144                 :          47 :     enumerable: true,
     145                 :          47 :     writable: true,
     146                 :          47 :     value: setInterval,
     147                 :             : });
     148                 :             : 
     149                 :          94 : Object.defineProperty(globalThis, 'clearTimeout', {
     150                 :          47 :     configurable: false,
     151                 :          47 :     enumerable: true,
     152                 :          47 :     writable: true,
     153                 :          47 :     value: clearTimeout,
     154                 :             : });
     155                 :             : 
     156                 :          94 : Object.defineProperty(globalThis, 'clearInterval', {
     157                 :          47 :     configurable: false,
     158                 :          47 :     enumerable: true,
     159                 :          47 :     writable: true,
     160                 :          47 :     value: clearInterval,
     161                 :             : });
        

Generated by: LCOV version 2.0-1