##// END OF EJS Templates
added TraceSource tests
cin -
r11:b9900835d201 propose cancellat...
parent child
Show More
@@ -0,0 +1,29
1 define(["tape"], function(tape) {
2 "use strict";
3 var sourceId = '73a633f3-eab8-49b0-8601-07cae710f234';
4 var sourceId2 = '3ba9c7cd-ed77-437b-9a2f-1cbeb1226b5b';
5 tape('Load TraceSource for the module', function(t) {
6 require(["core/log/trace!" + sourceId, "core/log/TraceSource"], function(trace, TraceSource) {
7 t.equal(trace && trace.id, sourceId, "trace should be taken from the loader plugin parameter");
8
9 var count = 0;
10
11 var h = TraceSource.on(function(x) {
12 if(x.id == sourceId || x.id == sourceId2)
13 count++;
14 });
15
16 t.equal(count, 1, "should see created channel immediatelly");
17 t.equal(trace, TraceSource.get(sourceId), "should get same TraceSource from registry");
18 t.equal(count, 1);
19
20 TraceSource.get(sourceId2);
21
22 t.equal(count, 2);
23
24 h.destroy();
25
26 t.end();
27 });
28 });
29 }); No newline at end of file
@@ -0,0 +1,14
1 import * as TraceSource from '@implab/core/log/TraceSource'
2 import * as tape from 'tape';
3
4 const sourceId = 'test/TraceSourceTests';
5
6 tape('', t => {
7 let trace = TraceSource.get(sourceId);
8
9 let h = trace.on((sender,level,msg) => {
10
11 });
12
13 h.destroy();
14 }); No newline at end of file
@@ -1,94 +1,96
1 1 import { IActivationController } from './IActivationController';
2 2 import { IActivatable } from './IActivatable';
3 3 import { AsyncComponent } from './AsyncComponent';
4 4 import { ICancellation } from '../ICancellation';
5 5 import { EmptyCancellation } from '../EmptyCancellation';
6 import * as log from '@implab/core/log/trace!';
6 import * as TraceSource from '../log/TraceSource';
7 7
8 8 type Constructor<T = {}> = new (...args: any[]) => T;
9 9
10 const log = TraceSource.get('@implab/core/components/ActivatableMixin');
11
10 12 function ActivatableMixin<TBase extends Constructor<AsyncComponent>>(Base: TBase) {
11 13 return class extends Base implements IActivatable {
12 14 _controller: IActivationController;
13 15
14 16 _active: boolean;
15 17
16 18 isActive() {
17 19 return this._active;
18 20 }
19 21
20 22 getActivationController() {
21 23 return this._controller;
22 24 }
23 25
24 26 setActivationController(controller: IActivationController) {
25 27 this._controller = controller;
26 28 }
27 29
28 30 async onActivating(ct: ICancellation) {
29 31 if (this._controller)
30 32 await this._controller.activating(this, ct);
31 33 }
32 34
33 35 async onActivated(ct: ICancellation) {
34 36 if (this._controller)
35 37 await this._controller.activated(this, ct);
36 38 }
37 39
38 40 async activate(ct: ICancellation = EmptyCancellation.default) {
39 41 if (this.isActive())
40 42 return;
41 43 ct = this.startOperation(ct);
42 44 try {
43 45 await this.onActivating(ct);
44 46 this._active = true;
45 47 try {
46 48 await this.onActivated(ct);
47 49 } catch(e) {
48 50 log.error(e);
49 51 // TODO log error
50 52 }
51 53 this.completeSuccess();
52 54 } catch (e) {
53 55 this.completeFail(e);
54 56 }
55 57 return this.getCompletion();
56 58 }
57 59
58 60 async onDeactivating(ct: ICancellation) {
59 61 if (this._controller)
60 62 await this._controller.deactivating(this, ct);
61 63 }
62 64
63 65 async onDeactivated(ct: ICancellation) {
64 66 if (this._controller)
65 67 await this._controller.deactivated(this, ct);
66 68 }
67 69
68 70 async deactivate(ct: ICancellation = EmptyCancellation.default) {
69 71 if (!this.isActive())
70 72 return;
71 73 ct = this.startOperation(ct);
72 74 try {
73 75 await this.onDeactivating(ct);
74 76 this._active = false;
75 77 try {
76 78 await this.onDeactivated(ct);
77 79 } catch {
78 80 // TODO log error
79 81 }
80 82 this.completeSuccess();
81 83 } catch (e) {
82 84 this.completeFail(e);
83 85 }
84 86 return this.getCompletion();
85 87 }
86 88
87 89 }
88 90 }
89 91
90 92 namespace ActivatableMixin {
91 93
92 94 }
93 95
94 96 export = ActivatableMixin; No newline at end of file
@@ -1,175 +1,175
1 1 import * as format from '../text/format'
2 2 import { argumentNotNull } from '../safe';
3 3
4 4 interface TraceEventHandler {
5 5 (sender: TraceSource, level: number, arg: any): void;
6 6 }
7 7
8 8 interface TraceSourceHandler {
9 9 (source: TraceSource): void;
10 10 }
11 11
12 12 interface Destroyable {
13 13 destroy();
14 14 }
15 15
16 16 class Registry {
17 17 static readonly instance = new Registry();
18 18
19 19 private _registry: object = new Object();
20 20 private _listeners: object = new Object();
21 21 private _nextCookie: number = 1;
22 22
23 23 get(id: any): TraceSource {
24 24 argumentNotNull(id, "id");
25 25
26 26 if (this._registry[id])
27 27 return this._registry[id];
28 28
29 29 var source = new TraceSource(id);
30 30 this._registry[id] = source;
31 31 this._onNewSource(source);
32 32
33 33 return source;
34 34 }
35 35
36 36 add(id: any, source: TraceSource) {
37 37 argumentNotNull(id, "id");
38 38 argumentNotNull(source, "source");
39 39
40 40 this._registry[id] = source;
41 41 this._onNewSource(source);
42 42 }
43 43
44 44 _onNewSource(source: TraceSource) {
45 45 for (let i in this._listeners)
46 46 this._listeners[i].call(null, source);
47 47 }
48 48
49 49 on(handler: TraceSourceHandler): Destroyable {
50 50 argumentNotNull(handler, "handler");
51 51 var me = this;
52 52
53 53 var cookie = this._nextCookie++;
54 54
55 55 this._listeners[cookie] = handler;
56 56
57 57 for (let i in this._registry)
58 58 handler(this._registry[i]);
59 59
60 60 return {
61 61 destroy() {
62 62 delete me._listeners[cookie];
63 63 }
64 64 };
65 65 }
66 66 }
67 67
68 68 class TraceSource {
69 69
70 70 readonly id: any
71 71
72 72 // using array will provide faster iteration the with object
73 73 private _handlers: Array<TraceEventHandler> = new Array<TraceEventHandler>();
74 74
75 75 level: number
76 76
77 77 constructor(id: any) {
78 78 this.id = id || new Object();
79 79 }
80 80
81 81 on(handler: TraceEventHandler): Destroyable {
82 82 argumentNotNull(handler, "handler");
83 83 var me = this;
84 84 me._handlers.push(handler);
85 85
86 86 return {
87 87 destroy() {
88 88 me.remove(handler);
89 89 }
90 90 }
91 91 }
92 92
93 93 remove(handler: TraceEventHandler): void {
94 94 let i = this._handlers.indexOf(handler);
95 95 if (i >= 0)
96 96 this._handlers.splice(i, 1);
97 97 }
98 98
99 99 protected emit(level: number, arg: any) {
100 100 this._handlers.forEach(h => {
101 101 try {
102 102 h(this, level, arg);
103 103 } catch (e) {
104 104 // suppress error in log handlers
105 105 }
106 106 });
107 107 }
108 108
109 109 isDebugEnabled() {
110 110 return this.level >= TraceSource.DebugLevel;
111 111 }
112 112
113 113 debug(msg: string, ...args: any[]) {
114 114 if (this.isEnabled(TraceSource.DebugLevel))
115 115 this.emit(TraceSource.DebugLevel, format(msg, args));
116 116 }
117 117
118 118 isLogEnabled() {
119 119 return this.level >= TraceSource.LogLevel;
120 120 }
121 121
122 122 log(msg: string, ...args: any[]) {
123 123 if (this.isEnabled(TraceSource.LogLevel))
124 124 this.emit(TraceSource.LogLevel, format(msg, args));
125 125 }
126 126
127 127 isWarnEnabled() {
128 128 return this.level >= TraceSource.WarnLevel;
129 129 }
130 130
131 131 warn(msg: string, ...args: any[]) {
132 132 if (this.isEnabled(TraceSource.WarnLevel))
133 133 this.emit(TraceSource.WarnLevel, format(msg, args));
134 134 }
135 135
136 136 isErrorEnabled() {
137 137 return this.level >= TraceSource.ErrorLevel;
138 138 }
139 139
140 140 error(msg: string, ...args: any[]) {
141 141 if (this.isEnabled(TraceSource.ErrorLevel))
142 142 this.emit(TraceSource.ErrorLevel, format(msg, args));
143 143 }
144 144
145 145 isEnabled(level: number) {
146 146 return (this.level >= level);
147 147 }
148 148
149 149 traceEvent(level: number, arg: any) {
150 150 if (this.isEnabled(level))
151 151 this.emit(level, arg);
152 152 }
153 153
154 154 static on(handler: TraceSourceHandler) {
155 Registry.instance.on(handler);
155 return Registry.instance.on(handler);
156 156 }
157 157
158 158 static get(id: any) {
159 159 return Registry.instance.get(id);
160 160 }
161 161 }
162 162
163 163 namespace TraceSource {
164 164 export const DebugLevel = 400;
165 165
166 166 export const LogLevel = 300;
167 167
168 168 export const WarnLevel = 200;
169 169
170 170 export const ErrorLevel = 100;
171 171
172 172 export const SilentLevel = 0;
173 173 }
174 174
175 175 export = TraceSource; No newline at end of file
@@ -1,1 +1,1
1 define(["./dummy", "./example", "./ActivatableTests"]); No newline at end of file
1 define(["./ActivatableTests", "./trace-test"]); No newline at end of file
1 NO CONTENT: file was removed
General Comments 0
You need to be logged in to leave comments. Login now