-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Expand file tree
/
Copy pathgreeting.service.unit.ts
More file actions
128 lines (99 loc) · 3.75 KB
/
greeting.service.unit.ts
File metadata and controls
128 lines (99 loc) · 3.75 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
// Copyright IBM Corp. and LoopBack contributors 2026. All Rights Reserved.
// Node module: @loopback/example-metrics-prometheus
// This file is licensed under the MIT License.
// License text available at https://opensource.org/licenses/MIT
import {expect} from '@loopback/testlab';
import {GreetingService} from '../../../services';
describe('GreetingService (unit)', () => {
let service: GreetingService;
beforeEach(() => {
service = new GreetingService();
});
describe('greet', () => {
it('returns a greeting message', async () => {
const result = await service.greet('World');
expect(result).to.be.a.String();
expect(result).to.match(/Hello, World/);
});
it('includes timestamp in greeting', async () => {
const result = await service.greet('Alice');
expect(result).to.match(
/\[\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d{3}Z: \d+\]/,
);
});
it('includes delay information', async () => {
const result = await service.greet('Bob');
// Extract delay from message format: [timestamp: delay] Hello, name
const delayMatch = result.match(/: (\d+)\]/);
expect(delayMatch).to.not.be.null();
const delay = parseInt(delayMatch![1], 10);
expect(delay).to.be.greaterThanOrEqual(0);
expect(delay).to.be.lessThan(100);
});
it('greets different names', async () => {
const result1 = await service.greet('Alice');
const result2 = await service.greet('Bob');
const result3 = await service.greet('Charlie');
expect(result1).to.match(/Hello, Alice/);
expect(result2).to.match(/Hello, Bob/);
expect(result3).to.match(/Hello, Charlie/);
});
it('handles empty name', async () => {
const result = await service.greet('');
expect(result).to.match(/Hello, $/);
});
it('handles special characters in name', async () => {
const result = await service.greet('Alice & Bob');
expect(result).to.match(/Hello, Alice & Bob/);
});
it('handles unicode characters in name', async () => {
const result = await service.greet('世界');
expect(result).to.match(/Hello, 世界/);
});
it('introduces random delay', async () => {
const delays: number[] = [];
// Call greet multiple times to collect delays
for (let i = 0; i < 10; i++) {
const result = await service.greet('Test');
const delayMatch = result.match(/: (\d+)\]/);
if (delayMatch) {
delays.push(parseInt(delayMatch[1], 10));
}
}
// Check that we got different delays (not all the same)
const uniqueDelays = new Set(delays);
expect(uniqueDelays.size).to.be.greaterThan(1);
});
it('completes within reasonable time', async () => {
const startTime = Date.now();
await service.greet('Performance Test');
const endTime = Date.now();
const duration = endTime - startTime;
// Should complete within 150ms (max delay is 100ms + overhead)
expect(duration).to.be.lessThan(150);
});
});
describe('service injection', () => {
it('is injectable', () => {
expect(service).to.be.instanceOf(GreetingService);
});
it('has greet method', () => {
expect(service.greet).to.be.a.Function();
});
});
describe('concurrent greetings', () => {
it('handles multiple concurrent greetings', async () => {
const promises = [
service.greet('User1'),
service.greet('User2'),
service.greet('User3'),
];
const results = await Promise.all(promises);
expect(results).to.have.length(3);
expect(results[0]).to.match(/Hello, User1/);
expect(results[1]).to.match(/Hello, User2/);
expect(results[2]).to.match(/Hello, User3/);
});
});
});
// Made with Bob