@Test
    void testRouteExclusion() {
        Route route = Route.builder().pathPrefix("/foo")
                           .exclude(Route.builder().pathPrefix("/foo/bar").build())
                           .build();
        assertThat(route.apply(withPath("/foo/baz"), false).isPresent()).isTrue();
        // PrefixPathMapping will automatically add '/' to the end of the given path prefix.
        assertThat(route.apply(withPath("/foo/bar"), false).isPresent()).isTrue();
        assertThat(route.apply(withPath("/foo/bar/"), false).isPresent()).isFalse();

        route = Route.builder().pathPrefix("/foo")
                     .exclude(Route.builder().exact("/foo/bar").build())
                     .build();
        assertThat(route.apply(withPath("/foo/baz"), false).isPresent()).isTrue();
        assertThat(route.apply(withPath("/foo/bar"), false).isPresent()).isFalse();
        assertThat(route.apply(withPath("/foo/bar/"), false).isPresent()).isTrue();

        route = Route.builder().pathPrefix("/foo")
                     .exclude("regex:^/foo/(bar|baz)$") // Use shortcut.
                     .build();
        assertThat(route.apply(withPath("/foo/baz"), false).isPresent()).isFalse();
        assertThat(route.apply(withPath("/foo/bar"), false).isPresent()).isFalse();
        assertThat(route.apply(withPath("/foo/bar/"), false).isPresent()).isTrue();

        route = Route.builder().pathPrefix("/foo")
                     .exclude("glob:/foo/bar/**")   // Use shortcut.
                     .build();
        assertThat(route.apply(withPath("/foo/baz"), false).isPresent()).isTrue();
        assertThat(route.apply(withPath("/foo/bar"), false).isPresent()).isTrue();
        assertThat(route.apply(withPath("/foo/bar/"), false).isPresent()).isFalse();
        assertThat(route.apply(withPath("/foo/bar/baz"), false).isPresent()).isFalse();
    }
/bar");

        route = Route.builder().path("/foo", "regex:^/files/(?<filePath>.*)$").build();
        assertThat(route.pathType()).isSameAs(RoutePathType.REGEX_WITH_PREFIX);
        assertThat(route.paths()).containsExactly("^/files/(?<filePath>.*)$", "/foo/");
        assertThat(route.patternString()).isEqualTo("/foo/^/files/(?<filePath>.*)$");
    }

    @Test
    void invalidRoutePath() {
        assertThatThrownBy(() -> Route.builder().path("foo")).isInstanceOf(IllegalArgumentException.class);
        assertThatThrownBy(() -> Route.builder().path("foo:/bar")).isInstanceOf(IllegalArgumentException.class);
        assertThatThrownBy(() -> Route.builder().path("/foo/{bar}:verb1:verb2")).isInstanceOf(
                IllegalArgumentException.class);
    }

    @Test
    void notAllowSemicolon() {
        assertThatThrownBy(() -> Route.builder().path("/foo;")).isInstanceOf(
                IllegalArgumentException.class);
        assertThatThrownBy(() -> Route.builder().path("/foo/{bar};")).isInstanceOf(
                IllegalArgumentException.class);
        assertThatThrownBy(() -> Route.builder().path("/bar/:baz;")).isInstanceOf(
                IllegalArgumentException.class);
        assertThatThrownBy(() -> Route.builder().path("exact:/:foo/bar;")).isInstanceOf(
                IllegalArgumentException.class);
        assertThatThrownBy(() -> Route.builder().path("prefix:/bar/baz;")).isInstanceOf(
                IllegalArgumentException.class);
    }

    @Test
    void testHeader() {
        final Route route = Route.builder()
                                 .path(PATH)
                                 .methods(HttpMethod.GET, HttpMethod.POST)
                                 .build();

        final RoutingResult getResult = route.apply(withMethod(HttpMethod.GET), false);
        final RoutingResult postResult = route.apply(withMethod(HttpMethod.POST), false);
        assertThat(getResult.isPresent()).isTrue();
        assertThat(postResult.isPresent()).isTrue();

        assertThat(route.apply(withMethod(HttpMethod.PUT), false).isPresent()).isFalse();
        assertThat(route.apply(withMethod(HttpMethod.DELETE), false).isPresent()).isFalse();
    }

    @Test
    void testConsumeType() {
        final Route route = Route.builder()
                                 .path(PATH)
                                 .methods(HttpMethod.POST)
                                 .consumes(JSON_UTF_8)
                                 .build();

        assertThat(route.apply(withConsumeType(HttpMethod.POST, JSON_UTF_8), false).isPresent()).isTrue();
        assertThat(route.apply(withConsumeType(HttpMethod.POST, MediaType.create("application", "json")), false)
                        .isPresent()).isFalse();
    }

    @Test
    void testAcceptType() {
        final Route route = Route.builder()
                                 .path(PATH)
                                 .methods(HttpMethod.GET)
                                 .produces(JSON_UTF_8)
                                 .build();

        assertThat(route.apply(withAcceptHeader(HttpMethod.GET, "
core/src/test/java/com/linecorp/armeria/server/RouteTest.java