Skip to content

Commit 6bd5dae

Browse files
committed
fix and adjust tests
1 parent b7c8790 commit 6bd5dae

File tree

3 files changed

+58
-107
lines changed

3 files changed

+58
-107
lines changed

packages/angular/src/tracing.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
import {
33
AfterViewInit,
44
Directive,
5+
Inject,
56
Injectable,
67
Input,
78
NgModule,
@@ -173,15 +174,15 @@ export class TraceDirective implements OnInit, AfterViewInit {
173174

174175
private _tracingSpan?: Span;
175176

176-
public constructor(@Optional() private readonly _vcRef: ViewContainerRef) {}
177+
public constructor(@Optional() @Inject(ViewContainerRef) private readonly _vcRef: ViewContainerRef) {}
177178

178179
/**
179180
* Implementation of OnInit lifecycle method
180181
* @inheritdoc
181182
*/
182183
public ngOnInit(): void {
183184
if (!this.componentName) {
184-
this.componentName = detectComponentName(this._vcRef as EnhancedVieContainerRef);
185+
this.componentName = detectComponentName(this._vcRef as EnhancedViewContainerRef);
185186
}
186187

187188
const activeTransaction = getActiveTransaction();
@@ -204,7 +205,7 @@ export class TraceDirective implements OnInit, AfterViewInit {
204205
}
205206
}
206207

207-
type EnhancedVieContainerRef = ViewContainerRef & {
208+
type EnhancedViewContainerRef = ViewContainerRef & {
208209
_lContainer?: {
209210
localName?: string;
210211
}[][];
@@ -215,10 +216,9 @@ type EnhancedVieContainerRef = ViewContainerRef & {
215216
* Specifically, it looks up the selector of the component (e.g. `app-my-component`) or
216217
* falls back to the default component name if the selector is not available.
217218
*/
218-
function detectComponentName(vcRef: EnhancedVieContainerRef | undefined): string {
219+
function detectComponentName(vcRef: EnhancedViewContainerRef | undefined): string {
219220
if (vcRef && vcRef._lContainer && vcRef._lContainer[0] && vcRef._lContainer[0][0]) {
220-
// TODO: is this preferrable?
221-
// Alternative: We could get the class name like so:
221+
// Alternatively, we could get the class name like so:
222222
// const className = Object.getPrototypeOf(vcRef._lContainer[0][8]).constructor.name;
223223

224224
const selectorName = vcRef._lContainer[0][0].localName;

packages/angular/test/tracing.test.ts

Lines changed: 50 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,15 @@ import { Hub } from '@sentry/types';
44

55
import { instrumentAngularRouting, TraceClassDecorator, TraceDirective, TraceMethodDecorator } from '../src';
66
import { getParameterizedRouteFromSnapshot } from '../src/tracing';
7-
import { AppComponent, TestEnv, TestViewContainerRef } from './utils/index';
7+
import { AppComponent, TestEnv } from './utils/index';
88

99
let transaction: any;
1010

1111
const defaultStartTransaction = (ctx: any) => {
1212
transaction = {
1313
...ctx,
1414
setName: jest.fn(name => (transaction.name = name)),
15+
startChild: jest.fn(),
1516
};
1617

1718
return transaction;
@@ -260,67 +261,76 @@ describe('Angular Tracing', () => {
260261
expect(directive).toBeTruthy();
261262
});
262263

263-
it('should create a child tracingSpan on init (WIP)', async () => {
264-
const customStartTransaction = jest.fn(defaultStartTransaction);
265-
266-
@Component({
267-
selector: 'app-component',
268-
template: '<app-child trace></app-child>',
269-
})
270-
class AppComponent {
271-
public constructor() {}
272-
}
264+
it("should auto detect the component's selector.", async () => {
265+
const directive = new TraceDirective({
266+
_lContainer: [[{ localName: 'app-test' }]],
267+
} as unknown as any);
273268

274-
@Component({
275-
selector: 'app-child',
276-
template: '<p>Hi</p>',
277-
})
278-
class ChildComponent {
279-
public constructor() {}
280-
}
269+
const customStartTransaction = jest.fn(defaultStartTransaction);
281270

282271
const env = await TestEnv.setup({
283-
components: [AppComponent, ChildComponent, TraceDirective],
284-
defaultComponent: AppComponent,
272+
components: [TraceDirective],
285273
customStartTransaction,
286274
useTraceService: false,
287275
});
288276

289277
transaction.startChild = jest.fn();
290278

291-
// directive.ngOnInit();
279+
directive.ngOnInit();
292280

293281
expect(transaction.startChild).toHaveBeenCalledWith({
294282
op: 'ui.angular.init',
295-
description: '<unknown>',
283+
description: '<app-test>',
296284
});
297285

298286
env.destroy();
299287
});
300288

301-
it('should create a child tracingSpan on init', async () => {
302-
// const directive = new TraceDirective({} as unknown as any);
303-
const customStartTransaction = jest.fn(defaultStartTransaction);
289+
it.each([
290+
{},
291+
{
292+
_lContainer: [],
293+
},
294+
{
295+
_lContainer: [[]],
296+
},
297+
{
298+
_lContainer: [[{}]],
299+
},
300+
{
301+
_lContainer: [[{ localName: undefined }]],
302+
},
303+
])(
304+
"should fall back to the default component name if auto-detection doesn't work and no custom name is given",
305+
async (containerViewRef: any) => {
306+
const directive = new TraceDirective(containerViewRef);
307+
const customStartTransaction = jest.fn(defaultStartTransaction);
304308

305-
const env = await TestEnv.setup({
306-
components: [TraceDirective],
307-
customStartTransaction,
308-
useTraceService: false,
309-
});
309+
const env = await TestEnv.setup({
310+
components: [TraceDirective],
311+
customStartTransaction,
312+
useTraceService: false,
313+
});
310314

311-
transaction.startChild = jest.fn();
315+
const finishSpan = jest.fn();
316+
transaction.startChild = jest.fn().mockReturnValue({ finish: finishSpan });
317+
transaction.finish = jest.fn();
312318

313-
// directive.ngOnInit();
319+
directive.ngOnInit();
314320

315-
expect(transaction.startChild).toHaveBeenCalledWith({
316-
op: 'ui.angular.init',
317-
description: '<unknown>',
318-
});
321+
expect(transaction.startChild).toHaveBeenCalledWith({
322+
op: 'ui.angular.init',
323+
description: '<unknown>',
324+
});
319325

320-
env.destroy();
321-
});
326+
directive.ngAfterViewInit();
327+
expect(finishSpan).toHaveBeenCalledTimes(1);
322328

323-
it('should use component name as span description', async () => {
329+
env.destroy();
330+
},
331+
);
332+
333+
it('should use the custom component name as span description if one is passed', async () => {
324334
const directive = new TraceDirective({} as unknown as any);
325335
const finishMock = jest.fn();
326336
const customStartTransaction = jest.fn(defaultStartTransaction);
@@ -347,8 +357,7 @@ describe('Angular Tracing', () => {
347357
});
348358

349359
it('should finish tracingSpan after view init', async () => {
350-
// @ts-ignore - we don't need to pass a param here
351-
const directive = new TraceDirective(new TestViewContainerRef());
360+
const directive = new TraceDirective({} as unknown as any);
352361
const finishMock = jest.fn();
353362
const customStartTransaction = jest.fn(defaultStartTransaction);
354363

packages/angular/test/utils/index.ts

Lines changed: 2 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { Component, NgModule, ViewContainerRef } from '@angular/core';
1+
import { Component, NgModule } from '@angular/core';
22
import { ComponentFixture, TestBed } from '@angular/core/testing';
33
import { Router, Routes } from '@angular/router';
44
import { RouterTestingModule } from '@angular/router/testing';
@@ -65,12 +65,7 @@ export class TestEnv {
6565
deps: [Router],
6666
},
6767
]
68-
: [
69-
{
70-
provide: ViewContainerRef,
71-
useValue: new TestViewContainerRef(),
72-
},
73-
],
68+
: [],
7469
});
7570

7671
const router: Router = TestBed.inject(Router);
@@ -99,56 +94,3 @@ export class TestEnv {
9994
jest.clearAllMocks();
10095
}
10196
}
102-
103-
// create the test class
104-
export class TestViewContainerRef extends ViewContainerRef {
105-
get element(): import('@angular/core').ElementRef<any> {
106-
throw new Error('Method not implemented.');
107-
}
108-
get injector(): import('@angular/core').Injector {
109-
throw new Error('Method not implemented.');
110-
}
111-
get parentInjector(): import('@angular/core').Injector {
112-
throw new Error('Method not implemented.');
113-
}
114-
clear(): void {
115-
throw new Error('Method not implemented.');
116-
}
117-
get(_index: number): import('@angular/core').ViewRef {
118-
throw new Error('Method not implemented.');
119-
}
120-
get length(): number {
121-
throw new Error('Method not implemented.');
122-
}
123-
createEmbeddedView<C>(
124-
_templateRef: import('@angular/core').TemplateRef<C>,
125-
_context?: C,
126-
_index?: number,
127-
): import('@angular/core').EmbeddedViewRef<C> {
128-
throw new Error('Method not implemented.');
129-
}
130-
createComponent<C>(
131-
_componentFactory: import('@angular/core').ComponentFactory<C>,
132-
_index?: number,
133-
_injector?: import('@angular/core').Injector,
134-
_projectableNodes?: any[][],
135-
_ngModule?: import('@angular/core').NgModuleRef<any>,
136-
): import('@angular/core').ComponentRef<C> {
137-
throw new Error('Method not implemented.');
138-
}
139-
insert(_viewRef: import('@angular/core').ViewRef, _index?: number): import('@angular/core').ViewRef {
140-
throw new Error('Method not implemented.');
141-
}
142-
move(_viewRef: import('@angular/core').ViewRef, _currentIndex: number): import('@angular/core').ViewRef {
143-
throw new Error('Method not implemented.');
144-
}
145-
indexOf(_viewRef: import('@angular/core').ViewRef): number {
146-
throw new Error('Method not implemented.');
147-
}
148-
remove(_index?: number): void {
149-
throw new Error('Method not implemented.');
150-
}
151-
detach(_index?: number): import('@angular/core').ViewRef {
152-
throw new Error('Method not implemented.');
153-
}
154-
}

0 commit comments

Comments
 (0)