From d919b9b241fa786f7afda85f22b6bcd2f95e81be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wagner=20Daimling=20Font=C3=A3o?= Date: Sat, 8 Feb 2025 18:14:47 -0300 Subject: [PATCH 1/5] Support custom hostname and TLS options --- webdev/CHANGELOG.md | 1 + webdev/lib/src/serve/webdev_server.dart | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/webdev/CHANGELOG.md b/webdev/CHANGELOG.md index 491bdb385..d23461ab4 100644 --- a/webdev/CHANGELOG.md +++ b/webdev/CHANGELOG.md @@ -1,4 +1,5 @@ ## 3.7.1-wip +- Support the `--hostname` flag when the `--tls-cert-key` and `--tls-cert-chain` flags are present. ## 3.7.0 diff --git a/webdev/lib/src/serve/webdev_server.dart b/webdev/lib/src/serve/webdev_server.dart index bdf632091..eea3800ca 100644 --- a/webdev/lib/src/serve/webdev_server.dart +++ b/webdev/lib/src/serve/webdev_server.dart @@ -205,7 +205,7 @@ class WebDevServer { ..useCertificateChain(tlsCertChain) ..usePrivateKey(tlsCertKey); server = - await HttpMultiServer.loopbackSecure(options.port, serverContext); + await HttpMultiServer.bindSecure(hostname, options.port, serverContext); } else { server = await HttpMultiServer.bind(hostname, options.port); } From ce514f5aff69d1dfb9a2e4430c1bfe5a03d78a65 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wagner=20Daimling=20Font=C3=A3o?= Date: Mon, 10 Feb 2025 14:24:55 -0300 Subject: [PATCH 2/5] Format webdev_server.dart file --- webdev/lib/src/serve/webdev_server.dart | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/webdev/lib/src/serve/webdev_server.dart b/webdev/lib/src/serve/webdev_server.dart index eea3800ca..78ec6dd77 100644 --- a/webdev/lib/src/serve/webdev_server.dart +++ b/webdev/lib/src/serve/webdev_server.dart @@ -204,8 +204,8 @@ class WebDevServer { final serverContext = SecurityContext() ..useCertificateChain(tlsCertChain) ..usePrivateKey(tlsCertKey); - server = - await HttpMultiServer.bindSecure(hostname, options.port, serverContext); + server = await HttpMultiServer.bindSecure( + hostname, options.port, serverContext); } else { server = await HttpMultiServer.bind(hostname, options.port); } From 3c6a95fd75c6198112af9df3af3726e0473c1992 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wagner=20Daimling=20Font=C3=A3o?= Date: Fri, 14 Feb 2025 12:14:44 -0300 Subject: [PATCH 3/5] TLS options E2E tests --- .../_testTlsHostnameSound/localhost+2-key.pem | 28 +++++ .../_testTlsHostnameSound/localhost+2.pem | 27 +++++ fixtures/_testTlsHostnameSound/pubspec.yaml | 16 +++ fixtures/_testTlsHostnameSound/web/index.html | 7 ++ fixtures/_testTlsHostnameSound/web/main.dart | 108 +++++++++++++++++ webdev/test/tls_test.dart | 113 ++++++++++++++++++ 6 files changed, 299 insertions(+) create mode 100644 fixtures/_testTlsHostnameSound/localhost+2-key.pem create mode 100644 fixtures/_testTlsHostnameSound/localhost+2.pem create mode 100644 fixtures/_testTlsHostnameSound/pubspec.yaml create mode 100644 fixtures/_testTlsHostnameSound/web/index.html create mode 100644 fixtures/_testTlsHostnameSound/web/main.dart create mode 100644 webdev/test/tls_test.dart diff --git a/fixtures/_testTlsHostnameSound/localhost+2-key.pem b/fixtures/_testTlsHostnameSound/localhost+2-key.pem new file mode 100644 index 000000000..7bc7c1e26 --- /dev/null +++ b/fixtures/_testTlsHostnameSound/localhost+2-key.pem @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDR8FlEhQ8XZctL +mGdx78Z5EInK2mcfU9Nq4oUKkPeiql7Sd3cd3prd+m5MYylL255wAZf8Fdupkko2 +cjQEsU24jUBWVG5q3YqZ+OidFYdxYnPbDhFtzL3Lr2zHGAi+MgqVENUF6ED2O5tU +9U1crceXmXHb3E8Sg+zXX6TMVCS11OH9VQ1ZutM0fFMPZxmfU5aOfd5kuTmTiaOt +OMyymroUPgzRW6UcbLfSdD7KuNFQgHDHiWkr2MtoZffgGM/cOfmCdgE85MdL6kyb +7TUTbAlTSpJNWwygObce7DN7qwM8HocRWSAfH+y3ewbs2NtzG1Az+a/kUBjhvmjT +WFiwDT+1AgMBAAECggEBALkJMXTeHh4OP2+ipVJb9r/P3tMnSornFEl5268jdNAv +f6HbX+a4xCDwUHUNVWGh8XRhQzcRgOllofl5EPYt3AXUoac1hZi1KStqooOJbTZ3 +gwvIy33OXl5/gM2+Fj6k1oTqMAej3FXq1Y69InGUTX4F5b/V3u+/zWlKyHK7mxuT +LIP3/iAxbpST5FB1G7ZPyz5mvzvEQFRiv9ubuMxYg3fzORULtbnnHNAM5jLG3IzZ +9EM/1umaeZu1bg9rGVVgr0l/rWMJSg5u+Z6jcrt9+Oj7hYrMPGHKHXAPhC1gaq+k +tlKHj/mhmJyN0jUXt71UgrsWF3MhrK2W2AlIfxXhIIECgYEA8oaIEOaeNmtDqlH5 +MmU0jd2EcMRnLrlfKs4fKObFoSMqELRB3yJ1u5Yt/wQCCSpN9bhkinR0l4Q7YsAy +4sg5Q3VaA/rUWkVKkv2sD04LbBmpHr5vksPnIPKcfAY3csQ1F5pu9gY6zgzdxBvN +nWEu8tqbUSdC5+0F+tB8IDW+/lUCgYEA3ZpVXmBLvgeZJ8rNjCCeKR5hXMYdFKqC +Yd5KfasTKH7h8a4GWo/mtUsS5UPRRjhrP5mPjdUKBFhSaJtX+k9Hhot58RN20fWR +4Ake4yV/cNFRykD1jsv9JJiPkggnVLVXN91+/EnKJozWv46q6nG44iX+q2w2i9FQ +6lohgwQp2+ECgYEAwKJY+0uiiUkD0woPbJb0emZj5wophvRYgfB80YkTmt0KcYAr +/icp6pjr6e3uDAedKrqOqWa8oQi3/sT45ibxTQKuQBEAkL8O79grzXBJJFDxgujy +SFnwgLwTzXNGoZL1NM1Gq4XhOX8Aut72n7Xsi5tV2MzdmMgsgr8MiK0ICo0CgYBA +h4yMauYjc/r5R2kLgQQNXTdk2JvnRK+q6Bww8/wkMq6AvfhDrtuztyTNdi4ekJdK +ceEHoB3GniGBLJs13JgrabocpVpYUXYlEwLXijfOFmYGy1u2NViFq5dDIvSxCg1X +yzwLI0GmcCSoq1bB5lO8Juw95skLdexmEdDoYfH+gQKBgDgaFlF9lYuKd0HhAxxm +oJ8WBv26FWxR8/UsvUPqI8Mzmb8J1Q22tZEMEVr8bN/HkcL+8DVQ4uh2zx9+rqC0 +aPqJZNgePGpRDhZ/cwA8xsg+Xkou8rrFjpGRuVuG9FvMEexufkHoDc94ppONuwsR +QzjTUxgXdLjtxT95ISwX83Nr +-----END PRIVATE KEY----- diff --git a/fixtures/_testTlsHostnameSound/localhost+2.pem b/fixtures/_testTlsHostnameSound/localhost+2.pem new file mode 100644 index 000000000..a62046b5e --- /dev/null +++ b/fixtures/_testTlsHostnameSound/localhost+2.pem @@ -0,0 +1,27 @@ +-----BEGIN CERTIFICATE----- +MIIEgjCCAuqgAwIBAgIQBeTmjjlnyrCQUy06Xx/ybzANBgkqhkiG9w0BAQsFADCB +pTEeMBwGA1UEChMVbWtjZXJ0IGRldmVsb3BtZW50IENBMT0wOwYDVQQLDDRMQVBU +T1AtQUFSSFFPMkxcV2Rlc3RATEFQVE9QLUFBUkhRTzJMIChXYWduZXIgRC4gRi4p +MUQwQgYDVQQDDDtta2NlcnQgTEFQVE9QLUFBUkhRTzJMXFdkZXN0QExBUFRPUC1B +QVJIUU8yTCAoV2FnbmVyIEQuIEYuKTAeFw0yNTAyMTQxNDI2MjFaFw0yNzA1MTQx +NDI2MjFaMGgxJzAlBgNVBAoTHm1rY2VydCBkZXZlbG9wbWVudCBjZXJ0aWZpY2F0 +ZTE9MDsGA1UECww0TEFQVE9QLUFBUkhRTzJMXFdkZXN0QExBUFRPUC1BQVJIUU8y +TCAoV2FnbmVyIEQuIEYuKTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEB +ANHwWUSFDxdly0uYZ3HvxnkQicraZx9T02rihQqQ96KqXtJ3dx3emt36bkxjKUvb +nnABl/wV26mSSjZyNASxTbiNQFZUbmrdipn46J0Vh3Fic9sOEW3MvcuvbMcYCL4y +CpUQ1QXoQPY7m1T1TVytx5eZcdvcTxKD7NdfpMxUJLXU4f1VDVm60zR8Uw9nGZ9T +lo593mS5OZOJo604zLKauhQ+DNFbpRxst9J0Psq40VCAcMeJaSvYy2hl9+AYz9w5 ++YJ2ATzkx0vqTJvtNRNsCVNKkk1bDKA5tx7sM3urAzwehxFZIB8f7Ld7BuzY23Mb +UDP5r+RQGOG+aNNYWLANP7UCAwEAAaNqMGgwDgYDVR0PAQH/BAQDAgWgMBMGA1Ud +JQQMMAoGCCsGAQUFBwMBMB8GA1UdIwQYMBaAFLmYo+uZjtNZbL0jyR7XVnK/FICG +MCAGA1UdEQQZMBeCCWxvY2FsaG9zdIcEfwAAAYcEAAAAADANBgkqhkiG9w0BAQsF +AAOCAYEAbUhcggR4p8n/Us+ov8zvI+hBIrDi7GevWQQKrU1Rp2gzHV6glhqGMQ1A +BkGlj56L9O4P02awFZzB/55d2CsufzMD+d4aMKpdIJivwXByg6fJCtPOIprAiGeR +GuE9Q9ceUUJVrTYiy5CZeKTIQp4ZqWu5/wBQ+yvbsvxnzq2ESDpGmCkY6/ToMWmu +5cZPbZcyF7XBybSBdvaMGFsthRpawvQMsGHDZBaVhLn099Hjx2p35jNiM+HqCQXn +NweLYMJx9FZtOYyNJoTj0w97ViaSubz7V9n7LVIxW1QXmDXAk+75Fwq3x+n/tfhe +1BTLEOKvARvRVB6M1EE0z+zeNusHIu/TUMSmGv59OhsQdW5Lp1D0o3JK2mHu6tgP ++v1XRMaTQq73oHqU0oXCtsEdPuoFBNREBDhBOGB5wtFjfniu1zD0cKSDbVslSD5B +LKu9Yi1PzZTWVkaOWQolA6sYwWFLhQbHoyQoNjAJz58VNNtYIMjR6fZ0xTYiPQpJ +4Jh3TJKU +-----END CERTIFICATE----- diff --git a/fixtures/_testTlsHostnameSound/pubspec.yaml b/fixtures/_testTlsHostnameSound/pubspec.yaml new file mode 100644 index 000000000..12760da0f --- /dev/null +++ b/fixtures/_testTlsHostnameSound/pubspec.yaml @@ -0,0 +1,16 @@ +name: _experiment_sound +version: 1.0.0 +description: >- + A fake package used for testing experimental language features. +publish_to: none + +environment: + sdk: ^3.2.0 + +dependencies: + intl: ^0.17.0 + path: ^1.8.2 + +dev_dependencies: + build_runner: ^2.4.0 + build_web_compilers: ^4.0.4 diff --git a/fixtures/_testTlsHostnameSound/web/index.html b/fixtures/_testTlsHostnameSound/web/index.html new file mode 100644 index 000000000..d93440a94 --- /dev/null +++ b/fixtures/_testTlsHostnameSound/web/index.html @@ -0,0 +1,7 @@ + + + + + + + diff --git a/fixtures/_testTlsHostnameSound/web/main.dart b/fixtures/_testTlsHostnameSound/web/main.dart new file mode 100644 index 000000000..09827fd9b --- /dev/null +++ b/fixtures/_testTlsHostnameSound/web/main.dart @@ -0,0 +1,108 @@ +// Copyright (c) 2023, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + +import 'dart:async'; +import 'dart:core'; +// TODO: https://github.com/dart-lang/webdev/issues/2508 +// ignore: deprecated_member_use +import 'dart:html'; + +void main() { + // for evaluation + Timer.periodic(const Duration(seconds: 1), (_) { + printSimpleLocalRecord(); + printComplexLocalRecord(); + printNestedLocalRecord(); + printSimpleNamedLocalRecord(); + printComplexNamedLocalRecord(); + printNestedNamedLocalRecord(); + print('Patterns'); // Breakpoint: callTestPattern1 + testPattern(['a', 1]); + testPattern([3.14, 'b']); + testPattern([0, 1]); + testPattern2(); + print('Classes'); + testClass(); + }); + + document.body!.appendText('Program is running!'); +} + +void printSimpleLocalRecord() { + final record = (true, 3); + print(record); // Breakpoint: printSimpleLocalRecord +} + +void printSimpleNamedLocalRecord() { + final record = (true, cat: 'Vasya'); + print(record); // Breakpoint: printSimpleNamedLocalRecord +} + +void printComplexLocalRecord() { + final record = (true, 3, {'a': 1, 'b': 5}); + print(record); // Breakpoint: printComplexLocalRecord +} + +void printComplexNamedLocalRecord() { + final record = (true, 3, array: {'a': 1, 'b': 5}); + print(record); // Breakpoint: printComplexNamedLocalRecord +} + +void printNestedLocalRecord() { + final record = (true, (false, 5)); + print(record); // Breakpoint: printNestedLocalRecord +} + +void printNestedNamedLocalRecord() { + final record = (true, inner: (false, 5)); + print(record); // Breakpoint: printNestedNamedLocalRecord +} + +void testClass() { + final greeter = GreeterClass(greeteeName: 'Charlie Brown'); + greeter.sayHello(); +} + +String testPattern(Object obj) { + switch (obj) { + case [final a, final int n] || [final int n, final a] + when n == 1 && a is String: + return a.toString(); // Breakpoint: testPatternCase1 + case [final double n, final a] || [final a, final double n] + when (n - 3.14).abs() < 0.001: + return a.toString(); // Breakpoint: testPatternCase2 + default: + return 'default'; // Breakpoint: testPatternDefault + } +} + +String testPattern2() { + final dog = 'Prismo'; + final cats = ['Garfield', 'Tom']; // Breakpoint: testPattern2Case1 + final [firstCat, secondCat] = cats; + print(firstCat); // Breakpoint: testPattern2Case2 + return '$dog, $firstCat, $secondCat'; +} + +class GreeterClass { + final String greeteeName; + final bool useFrench; + + GreeterClass({ + this.greeteeName = 'Snoopy', + this.useFrench = false, + }); + + void sayHello() { + useFrench ? greetInFrench() : greetInEnglish(); + } + + void greetInEnglish() { + print('Hello $greeteeName'); // Breakpoint: testClass1Case1 + } + + void greetInFrench() { + print('Bonjour $greeteeName'); + } +} diff --git a/webdev/test/tls_test.dart b/webdev/test/tls_test.dart new file mode 100644 index 000000000..943c94891 --- /dev/null +++ b/webdev/test/tls_test.dart @@ -0,0 +1,113 @@ +import 'dart:io'; + +import 'package:collection/collection.dart'; +import 'package:logging/logging.dart'; +import 'package:path/path.dart' as p; +import 'package:test/test.dart'; +import 'package:test_descriptor/test_descriptor.dart' as d; +import 'package:test_process/test_process.dart'; + +import 'package:webdev/src/logging.dart'; +import 'package:webdev/src/serve/utils.dart'; + +import 'test_utils.dart'; + +void main() { + group('serve app with TLS options', () { + // Change to true for debugging. + final debug = false; + + final testRunner = TestRunner(); + late String soundExampleDirectory; + + setUpAll(() async { + configureLogWriter(debug); + await testRunner.setUpAll(); + soundExampleDirectory = p.absolute( + p.join(p.current, '..', 'fixtures', '_testTlsHostnameSound')); + + final process = await TestProcess.start( + 'dart', + ['pub', 'upgrade'], + workingDirectory: soundExampleDirectory, + environment: getPubEnvironment(), + ); + + await process.shouldExit(0); + + await d + .file('.dart_tool/package_config.json', isNotEmpty) + .validate(soundExampleDirectory); + await d.file('pubspec.lock', isNotEmpty).validate(soundExampleDirectory); + }); + + test('listens on a loopback interface', () async { + final port = await findUnusedPort(); + final args = [ + 'serve', + 'web:$port', + '--hostname=0.0.0.0', + '--tls-cert-chain=localhost+2.pem', + '--tls-cert-key=localhost+2-key.pem', + ]; + + final process = await testRunner.runWebDev(args, + workingDirectory: soundExampleDirectory); + await expectLater(process.stdout, emitsThrough(contains('Succeeded'))); + + final client = HttpClient() + ..badCertificateCallback = (_, __, ___) => true; + try { + final request = + await client.getUrl(Uri.parse('https://localhost:$port')); + final response = await request.close(); + expect(response.statusCode, equals(200)); + } finally { + client.close(force: true); + } + + await process.kill(); + await process.shouldExit(); + }); + + test('listens on a non-loopback interface', () async { + final port = await findUnusedPort(); + final args = [ + 'serve', + 'web:$port', + '--hostname=0.0.0.0', + '--tls-cert-chain=localhost+2.pem', + '--tls-cert-key=localhost+2-key.pem', + ]; + + final process = await testRunner.runWebDev(args, + workingDirectory: soundExampleDirectory); + await expectLater(process.stdout, emitsThrough(contains('Succeeded'))); + + final interfaces = await NetworkInterface.list( + type: InternetAddressType.IPv4, + includeLoopback: false, + ); + final nonLoopback = interfaces.expand((i) => i.addresses).firstOrNull; + + if (nonLoopback == null) { + Logger.root.info( + 'No non-loopback IPv4 address available, skipping hostname test.'); + } else { + final client = HttpClient() + ..badCertificateCallback = (_, __, ___) => true; + try { + final request = await client + .getUrl(Uri.parse('https://${nonLoopback.address}:$port')); + final response = await request.close(); + expect(response.statusCode, equals(200)); + } finally { + client.close(force: true); + } + } + + await process.kill(); + await process.shouldExit(); + }); + }); +} From 1f2a782f5f61760a41c836c9b224cc63168dc3cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wagner=20Daimling=20Font=C3=A3o?= Date: Fri, 21 Feb 2025 03:28:41 -0300 Subject: [PATCH 4/5] Add copyright header and remove duplicated files --- .../localhost+2-key.pem | 0 .../localhost+2.pem | 0 fixtures/_testTlsHostnameSound/pubspec.yaml | 16 --- fixtures/_testTlsHostnameSound/web/index.html | 7 -- fixtures/_testTlsHostnameSound/web/main.dart | 108 ------------------ webdev/test/tls_test.dart | 20 ++-- 6 files changed, 12 insertions(+), 139 deletions(-) rename fixtures/{_testTlsHostnameSound => _experimentSound}/localhost+2-key.pem (100%) rename fixtures/{_testTlsHostnameSound => _experimentSound}/localhost+2.pem (100%) delete mode 100644 fixtures/_testTlsHostnameSound/pubspec.yaml delete mode 100644 fixtures/_testTlsHostnameSound/web/index.html delete mode 100644 fixtures/_testTlsHostnameSound/web/main.dart diff --git a/fixtures/_testTlsHostnameSound/localhost+2-key.pem b/fixtures/_experimentSound/localhost+2-key.pem similarity index 100% rename from fixtures/_testTlsHostnameSound/localhost+2-key.pem rename to fixtures/_experimentSound/localhost+2-key.pem diff --git a/fixtures/_testTlsHostnameSound/localhost+2.pem b/fixtures/_experimentSound/localhost+2.pem similarity index 100% rename from fixtures/_testTlsHostnameSound/localhost+2.pem rename to fixtures/_experimentSound/localhost+2.pem diff --git a/fixtures/_testTlsHostnameSound/pubspec.yaml b/fixtures/_testTlsHostnameSound/pubspec.yaml deleted file mode 100644 index 12760da0f..000000000 --- a/fixtures/_testTlsHostnameSound/pubspec.yaml +++ /dev/null @@ -1,16 +0,0 @@ -name: _experiment_sound -version: 1.0.0 -description: >- - A fake package used for testing experimental language features. -publish_to: none - -environment: - sdk: ^3.2.0 - -dependencies: - intl: ^0.17.0 - path: ^1.8.2 - -dev_dependencies: - build_runner: ^2.4.0 - build_web_compilers: ^4.0.4 diff --git a/fixtures/_testTlsHostnameSound/web/index.html b/fixtures/_testTlsHostnameSound/web/index.html deleted file mode 100644 index d93440a94..000000000 --- a/fixtures/_testTlsHostnameSound/web/index.html +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/fixtures/_testTlsHostnameSound/web/main.dart b/fixtures/_testTlsHostnameSound/web/main.dart deleted file mode 100644 index 09827fd9b..000000000 --- a/fixtures/_testTlsHostnameSound/web/main.dart +++ /dev/null @@ -1,108 +0,0 @@ -// Copyright (c) 2023, the Dart project authors. Please see the AUTHORS file -// for details. All rights reserved. Use of this source code is governed by a -// BSD-style license that can be found in the LICENSE file. - -import 'dart:async'; -import 'dart:core'; -// TODO: https://github.com/dart-lang/webdev/issues/2508 -// ignore: deprecated_member_use -import 'dart:html'; - -void main() { - // for evaluation - Timer.periodic(const Duration(seconds: 1), (_) { - printSimpleLocalRecord(); - printComplexLocalRecord(); - printNestedLocalRecord(); - printSimpleNamedLocalRecord(); - printComplexNamedLocalRecord(); - printNestedNamedLocalRecord(); - print('Patterns'); // Breakpoint: callTestPattern1 - testPattern(['a', 1]); - testPattern([3.14, 'b']); - testPattern([0, 1]); - testPattern2(); - print('Classes'); - testClass(); - }); - - document.body!.appendText('Program is running!'); -} - -void printSimpleLocalRecord() { - final record = (true, 3); - print(record); // Breakpoint: printSimpleLocalRecord -} - -void printSimpleNamedLocalRecord() { - final record = (true, cat: 'Vasya'); - print(record); // Breakpoint: printSimpleNamedLocalRecord -} - -void printComplexLocalRecord() { - final record = (true, 3, {'a': 1, 'b': 5}); - print(record); // Breakpoint: printComplexLocalRecord -} - -void printComplexNamedLocalRecord() { - final record = (true, 3, array: {'a': 1, 'b': 5}); - print(record); // Breakpoint: printComplexNamedLocalRecord -} - -void printNestedLocalRecord() { - final record = (true, (false, 5)); - print(record); // Breakpoint: printNestedLocalRecord -} - -void printNestedNamedLocalRecord() { - final record = (true, inner: (false, 5)); - print(record); // Breakpoint: printNestedNamedLocalRecord -} - -void testClass() { - final greeter = GreeterClass(greeteeName: 'Charlie Brown'); - greeter.sayHello(); -} - -String testPattern(Object obj) { - switch (obj) { - case [final a, final int n] || [final int n, final a] - when n == 1 && a is String: - return a.toString(); // Breakpoint: testPatternCase1 - case [final double n, final a] || [final a, final double n] - when (n - 3.14).abs() < 0.001: - return a.toString(); // Breakpoint: testPatternCase2 - default: - return 'default'; // Breakpoint: testPatternDefault - } -} - -String testPattern2() { - final dog = 'Prismo'; - final cats = ['Garfield', 'Tom']; // Breakpoint: testPattern2Case1 - final [firstCat, secondCat] = cats; - print(firstCat); // Breakpoint: testPattern2Case2 - return '$dog, $firstCat, $secondCat'; -} - -class GreeterClass { - final String greeteeName; - final bool useFrench; - - GreeterClass({ - this.greeteeName = 'Snoopy', - this.useFrench = false, - }); - - void sayHello() { - useFrench ? greetInFrench() : greetInEnglish(); - } - - void greetInEnglish() { - print('Hello $greeteeName'); // Breakpoint: testClass1Case1 - } - - void greetInFrench() { - print('Bonjour $greeteeName'); - } -} diff --git a/webdev/test/tls_test.dart b/webdev/test/tls_test.dart index 943c94891..2b88f9c98 100644 --- a/webdev/test/tls_test.dart +++ b/webdev/test/tls_test.dart @@ -1,3 +1,7 @@ +// Copyright (c) 2025, the Dart project authors. Please see the AUTHORS file +// for details. All rights reserved. Use of this source code is governed by a +// BSD-style license that can be found in the LICENSE file. + import 'dart:io'; import 'package:collection/collection.dart'; @@ -18,18 +22,18 @@ void main() { final debug = false; final testRunner = TestRunner(); - late String soundExampleDirectory; + late String exampleDirectory; setUpAll(() async { configureLogWriter(debug); await testRunner.setUpAll(); - soundExampleDirectory = p.absolute( - p.join(p.current, '..', 'fixtures', '_testTlsHostnameSound')); + exampleDirectory = p.absolute( + p.join(p.current, '..', 'fixtures', '_experimentSound')); final process = await TestProcess.start( 'dart', ['pub', 'upgrade'], - workingDirectory: soundExampleDirectory, + workingDirectory: exampleDirectory, environment: getPubEnvironment(), ); @@ -37,8 +41,8 @@ void main() { await d .file('.dart_tool/package_config.json', isNotEmpty) - .validate(soundExampleDirectory); - await d.file('pubspec.lock', isNotEmpty).validate(soundExampleDirectory); + .validate(exampleDirectory); + await d.file('pubspec.lock', isNotEmpty).validate(exampleDirectory); }); test('listens on a loopback interface', () async { @@ -52,7 +56,7 @@ void main() { ]; final process = await testRunner.runWebDev(args, - workingDirectory: soundExampleDirectory); + workingDirectory: exampleDirectory); await expectLater(process.stdout, emitsThrough(contains('Succeeded'))); final client = HttpClient() @@ -81,7 +85,7 @@ void main() { ]; final process = await testRunner.runWebDev(args, - workingDirectory: soundExampleDirectory); + workingDirectory: exampleDirectory); await expectLater(process.stdout, emitsThrough(contains('Succeeded'))); final interfaces = await NetworkInterface.list( From ec047949297ed2026e8af059e3a9382d06b74a0a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Wagner=20Daimling=20Font=C3=A3o?= Date: Thu, 3 Apr 2025 07:18:05 -0300 Subject: [PATCH 5/5] Format test/tls_test.dart --- webdev/test/tls_test.dart | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/webdev/test/tls_test.dart b/webdev/test/tls_test.dart index 2b88f9c98..43a95e8e9 100644 --- a/webdev/test/tls_test.dart +++ b/webdev/test/tls_test.dart @@ -27,8 +27,8 @@ void main() { setUpAll(() async { configureLogWriter(debug); await testRunner.setUpAll(); - exampleDirectory = p.absolute( - p.join(p.current, '..', 'fixtures', '_experimentSound')); + exampleDirectory = + p.absolute(p.join(p.current, '..', 'fixtures', '_experimentSound')); final process = await TestProcess.start( 'dart', @@ -55,8 +55,8 @@ void main() { '--tls-cert-key=localhost+2-key.pem', ]; - final process = await testRunner.runWebDev(args, - workingDirectory: exampleDirectory); + final process = + await testRunner.runWebDev(args, workingDirectory: exampleDirectory); await expectLater(process.stdout, emitsThrough(contains('Succeeded'))); final client = HttpClient() @@ -84,8 +84,8 @@ void main() { '--tls-cert-key=localhost+2-key.pem', ]; - final process = await testRunner.runWebDev(args, - workingDirectory: exampleDirectory); + final process = + await testRunner.runWebDev(args, workingDirectory: exampleDirectory); await expectLater(process.stdout, emitsThrough(contains('Succeeded'))); final interfaces = await NetworkInterface.list(