Skip to content

Commit c1fedbd

Browse files
authored
test: add e2e test for route config domain (#977)
1 parent af5190d commit c1fedbd

File tree

4 files changed

+258
-4
lines changed

4 files changed

+258
-4
lines changed
Lines changed: 254 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,254 @@
1+
import 'dart:io';
2+
3+
import 'package:dart_frog_cli/src/daemon/daemon.dart';
4+
import 'package:path/path.dart' as path;
5+
import 'package:test/test.dart';
6+
7+
import '../helpers/helpers.dart';
8+
9+
/// Objectives:
10+
///
11+
/// * Generate a new Dart Frog project via `dart_frog create`
12+
/// * Start the daemon
13+
/// * Start a route configuration watcher
14+
/// * Create a new route on the project and verify new route configuration
15+
/// * Generate a route configuration
16+
/// * Create a rogue route and verify new route configuration
17+
/// * Stop the route configuration watcher
18+
/// * Stop the daemon
19+
void main() {
20+
const projectName = 'example';
21+
final tempDirectory = Directory.systemTemp.createTempSync();
22+
final projectDirectory = Directory(
23+
path.join(tempDirectory.path, projectName),
24+
);
25+
26+
late Process daemonProcess;
27+
28+
late final DaemonStdioHelper daemonStdio;
29+
30+
var requestCount = 0;
31+
32+
late String projectWatcherId;
33+
34+
setUpAll(() async {
35+
await dartFrogCreate(
36+
projectName: projectName,
37+
directory: tempDirectory,
38+
);
39+
daemonProcess = await dartFrogDaemonStart();
40+
41+
daemonStdio = DaemonStdioHelper(daemonProcess);
42+
addTearDown(() async {
43+
daemonProcess.kill(ProcessSignal.sigkill);
44+
daemonStdio.dispose();
45+
});
46+
47+
await daemonStdio.awaitForDaemonEvent('daemon.ready');
48+
});
49+
50+
group('route configuration domain', () {
51+
test('start route configuration watcher', () async {
52+
final response = await daemonStdio.sendDaemonRequest(
53+
DaemonRequest(
54+
id: '${++requestCount}',
55+
domain: 'route_configuration',
56+
method: 'watcherStart',
57+
params: {
58+
'workingDirectory': projectDirectory.path,
59+
},
60+
),
61+
);
62+
63+
expect(response.isSuccess, isTrue);
64+
projectWatcherId = response.result!['watcherId'] as String;
65+
66+
final event = await daemonStdio.awaitForDaemonEvent(
67+
'route_configuration.changed',
68+
withParamsThat: containsPair('watcherId', projectWatcherId),
69+
timeout: const Duration(seconds: 5),
70+
);
71+
72+
final routeConfiguration =
73+
event.params?['routeConfiguration'] as Map<String, dynamic>;
74+
final routeConfigurationEndpoints =
75+
routeConfiguration['endpoints'] as Map<String, dynamic>;
76+
final routeConfigurationMiddleware =
77+
routeConfiguration['middleware'] as List<dynamic>;
78+
final routeConfigurationRogueRoutes =
79+
routeConfiguration['rogueRoutes'] as List<dynamic>;
80+
81+
expect(routeConfigurationEndpoints.keys.toList(), containsAll(['/']));
82+
expect(routeConfigurationMiddleware, isEmpty);
83+
expect(routeConfigurationRogueRoutes, isEmpty);
84+
});
85+
86+
test('create new route', () async {
87+
await dartFrogNewRoute('new_route', directory: projectDirectory);
88+
89+
final event = await daemonStdio.awaitForDaemonEvent(
90+
'route_configuration.changed',
91+
withParamsThat: containsPair('watcherId', projectWatcherId),
92+
timeout: const Duration(seconds: 5),
93+
);
94+
95+
final routeConfiguration =
96+
event.params?['routeConfiguration'] as Map<String, dynamic>;
97+
final routeConfigurationEndpoints =
98+
routeConfiguration['endpoints'] as Map<String, dynamic>;
99+
final routeConfigurationMiddleware =
100+
routeConfiguration['middleware'] as List<dynamic>;
101+
final routeConfigurationRogueRoutes =
102+
routeConfiguration['rogueRoutes'] as List<dynamic>;
103+
104+
expect(
105+
routeConfigurationEndpoints.keys.toList(),
106+
equals(['/new_route', '/']),
107+
);
108+
expect(routeConfigurationMiddleware, isEmpty);
109+
expect(routeConfigurationRogueRoutes, isEmpty);
110+
});
111+
112+
test('create new middleware', () async {
113+
await dartFrogNewMiddleware('new_route', directory: projectDirectory);
114+
115+
// Creating a middleware ath that route will case some files to move
116+
// around before the middleware file is created. Therefore, we have to
117+
// wait for the logger event that indicates the middleware file was
118+
// created.
119+
await daemonStdio.awaitForDaemonEvent(
120+
'route_configuration.loggerDetail',
121+
withParamsThat: allOf(
122+
containsPair('watcherId', projectWatcherId),
123+
containsPair('requestId', '1'),
124+
containsPair(
125+
'message',
126+
allOf(
127+
startsWith('[watcher] add'),
128+
endsWith('_middleware.dart'),
129+
),
130+
),
131+
),
132+
timeout: const Duration(seconds: 5),
133+
);
134+
135+
final event = await daemonStdio.awaitForDaemonEvent(
136+
'route_configuration.changed',
137+
withParamsThat: containsPair('watcherId', projectWatcherId),
138+
timeout: const Duration(seconds: 5),
139+
);
140+
141+
final routeConfiguration =
142+
event.params?['routeConfiguration'] as Map<String, dynamic>;
143+
final routeConfigurationEndpoints =
144+
routeConfiguration['endpoints'] as Map<String, dynamic>;
145+
final routeConfigurationMiddleware =
146+
routeConfiguration['middleware'] as List<dynamic>;
147+
final routeConfigurationRogueRoutes =
148+
routeConfiguration['rogueRoutes'] as List<dynamic>;
149+
150+
expect(
151+
routeConfigurationEndpoints.keys.toList(),
152+
containsAll(['/new_route', '/']),
153+
);
154+
expect(
155+
(routeConfigurationMiddleware.first as Map<String, dynamic>)['path'],
156+
'../routes/new_route/_middleware.dart',
157+
);
158+
expect(routeConfigurationRogueRoutes, isEmpty);
159+
});
160+
161+
test('ask for route config generation', () async {
162+
final response = await daemonStdio.sendDaemonRequest(
163+
DaemonRequest(
164+
id: '${requestCount++}',
165+
domain: 'route_configuration',
166+
method: 'watcherGenerateRouteConfiguration',
167+
params: {
168+
'watcherId': projectWatcherId,
169+
},
170+
),
171+
);
172+
173+
expect(response.isSuccess, isTrue);
174+
final routeConfiguration =
175+
response.result?['routeConfiguration'] as Map<String, dynamic>;
176+
final routeConfigurationEndpoints =
177+
routeConfiguration['endpoints'] as Map<String, dynamic>;
178+
final routeConfigurationMiddleware =
179+
routeConfiguration['middleware'] as List<dynamic>;
180+
final routeConfigurationRogueRoutes =
181+
routeConfiguration['rogueRoutes'] as List<dynamic>;
182+
183+
expect(
184+
routeConfigurationEndpoints.keys.toList(),
185+
containsAll(['/new_route', '/']),
186+
);
187+
expect(
188+
(routeConfigurationMiddleware.first as Map<String, dynamic>)['path'],
189+
'../routes/new_route/_middleware.dart',
190+
);
191+
expect(routeConfigurationRogueRoutes, isEmpty);
192+
});
193+
194+
test('create a rogue route', () async {
195+
await dartFrogNewRoute(
196+
'rogue_route/sub_route',
197+
directory: projectDirectory,
198+
);
199+
200+
File(
201+
path.join(projectDirectory.path, 'routes', 'rogue_route.dart'),
202+
).createSync();
203+
204+
await daemonStdio.awaitForDaemonEvent(
205+
'route_configuration.loggerDetail',
206+
withParamsThat: allOf(
207+
containsPair('watcherId', projectWatcherId),
208+
containsPair('requestId', '1'),
209+
containsPair(
210+
'message',
211+
allOf(
212+
startsWith('[watcher] add'),
213+
endsWith('rogue_route.dart'),
214+
),
215+
),
216+
),
217+
timeout: const Duration(seconds: 5),
218+
);
219+
220+
final event = await daemonStdio.awaitForDaemonEvent(
221+
'route_configuration.changed',
222+
withParamsThat: containsPair('watcherId', projectWatcherId),
223+
timeout: const Duration(seconds: 5),
224+
);
225+
226+
final routeConfiguration =
227+
event.params?['routeConfiguration'] as Map<String, dynamic>;
228+
final routeConfigurationRogueRoutes =
229+
routeConfiguration['rogueRoutes'] as List<dynamic>;
230+
231+
expect(routeConfigurationRogueRoutes.length, equals(1));
232+
expect(
233+
(routeConfigurationRogueRoutes.first as Map<String, dynamic>)['path'],
234+
equals('../routes/rogue_route.dart'),
235+
);
236+
});
237+
238+
test('stop watcher', () async {
239+
final response = await daemonStdio.sendDaemonRequest(
240+
DaemonRequest(
241+
id: '${requestCount++}',
242+
domain: 'route_configuration',
243+
method: 'watcherStop',
244+
params: {
245+
'watcherId': projectWatcherId,
246+
},
247+
),
248+
);
249+
250+
expect(response.isSuccess, isTrue);
251+
expect(response.result?['exitCode'], equals(0));
252+
});
253+
});
254+
}

packages/dart_frog_cli/e2e/test/helpers/dart_frog_daemon.dart

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -115,11 +115,11 @@ class DaemonStdioHelper {
115115
final existingItem = _pastMessagesCache.indexed.where((pair) {
116116
return messageMatcher.matches(pair.$2, {});
117117
}).firstOrNull;
118-
if (existingItem != null) {
118+
119+
if (existingItem case (final int itemIndex, final String itemValue)) {
119120
// if there is a matching message in the cache,
120121
// remove all the previous messages from the cache and
121122
// return the matching message.
122-
final (itemIndex, itemValue) = existingItem;
123123
_pastMessagesCache = _pastMessagesCache.skip(itemIndex + 1).toList();
124124
_clean();
125125
return itemValue;

packages/dart_frog_cli/lib/src/daemon/domain/route_configuration_domain.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ class RouteConfigurationDomain extends DomainBase {
6161
daemon.sendEvent(
6262
DaemonEvent(
6363
domain: domainName,
64-
event: 'routeConfigurationChanged',
64+
event: 'changed',
6565
params: {
6666
'watcherId': watcherId,
6767
'requestId': request.id,

packages/dart_frog_cli/test/src/daemon/domain/route_configuration_domain_test.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ void main() {
131131
() => daemonServer.sendEvent(
132132
DaemonEvent(
133133
domain: 'route_configuration',
134-
event: 'routeConfigurationChanged',
134+
event: 'changed',
135135
params: {
136136
'watcherId': 'id',
137137
'requestId': '12',

0 commit comments

Comments
 (0)