import { assert, assertEqual, assertFalse, assertNull, assertTrue, assertThrows } from '../tk-unit'; import { enable, disable, profile, time, start, stop, timer, isRunning, resetProfiles } from '@nativescript/core/profiling'; enable(); class TestClass { @profile('__func_decorator__') doNothing() { //noop } @profile('__func_decorator_error__') throwError() { throw new Error('This error is expected'); } @profile unnamed1() { // noop } @profile() unnamed2() { // noop } private isInReentrant = false; @profile reentrant() { try { if (!this.isInReentrant) { this.isInReentrant = true; this.reentrant(); } } finally { this.isInReentrant = false; } } } const testFunction1 = profile(function testFunction1() { // noop }); const testFunction2 = profile('testFunction2', () => { // noop }); disable(); function retry(count: number, action: () => void) { for (var i = 1; i <= count; i++) { try { action(); return; } catch (e) { if (i === count) { throw e; } } } } export function test_time_returns_number() { assertEqual(typeof time(), 'number'); } export function test_isRunning() { resetProfiles(); const name = 'test_isRunning'; assertFalse(isRunning(name), 'isRunning should be false before start'); start(name); assertTrue(isRunning(name), 'isRunning should be true after start'); stop(name); assertFalse(isRunning(name), 'isRunning should be false after stop'); start(name); assertTrue(isRunning(name), 'isRunning should be true after second start'); stop(name); assertFalse(isRunning(name), 'isRunning should be false after second stop'); } export function test_isRunning_withReentrancy() { resetProfiles(); const name = 'test_isRunning'; assertFalse(isRunning(name), 'isRunning should be false before start'); start(name); assertTrue(isRunning(name), 'isRunning should be true after start'); start(name); assertTrue(isRunning(name), 'isRunning should be true after second start'); stop(name); assertTrue(isRunning(name), 'isRunning should be true after first stop'); stop(name); assertFalse(isRunning(name), 'isRunning should be false after second stop'); } export function test_reset_profiles() { resetProfiles(); const name = 'test_reset_profiles'; start(name); stop(name); resetProfiles(); const res = timer(name); assertNull(res); } export function test_start_stop() { resetProfiles(); const name = 'test_start_stop'; start(name); stop(name); const res = timer(name); assertEqual(res.count, 1); } export function test_start_stop_count() { resetProfiles(); const name = 'test_start_stop_count'; for (var i = 0; i < 10; i++) { start(name); stop(name); } const res = timer(name); assertEqual(res.count, 10); } export function test_profile_decorator_count() { resetProfiles(); const test = new TestClass(); for (var i = 0; i < 10; i++) { test.doNothing(); test.unnamed1(); test.unnamed2(); testFunction1(); testFunction2(); } ['__func_decorator__', 'TestClass.unnamed1', 'TestClass.unnamed2', 'testFunction1', 'testFunction2'].forEach((key) => { const res = timer(key); assertEqual(res.count, 10, 'Expected profile with name ${key} to have traced 10 calls.'); }); } export function test_profile_decorator_handles_exceptions() { resetProfiles(); const test = new TestClass(); assertThrows(() => test.throwError()); assertFalse(isRunning('__func_decorator_error__'), 'Timer should be stopped on exception.'); assertEqual(timer('__func_decorator_error__').count, 1, 'Timer should be called once'); } export function test_start_stop_performance() { retry(5, () => { resetProfiles(); const count = 10000; const name = 'test_start_stop_performance'; for (var i = 0; i < count; i++) { start(name); stop(name); } const res = timer(name); assertEqual(res.count, count); assert(res.totalTime <= 500, `Total time for ${count} timer operations is too much: ${res.totalTime}`); }); } export function test_profile_decorator_performance() { retry(5, () => { resetProfiles(); var start = Date.now(); const count = 10000; const test = new TestClass(); for (var i = 0; i < count; i++) { test.doNothing(); } const res = timer('__func_decorator__'); assertEqual(res.count, count); assert(res.totalTime <= 500, `Total time for ${count} timer operations is too much: ${res.totalTime}`); var end = Date.now(); assert(end - start <= 1000, `Total time for test execution is too much: ${end - start}ms`); }); } export function test_reentrancy() { // reentrant retry(5, () => { resetProfiles(); const test = new TestClass(); test.reentrant(); }); }