Index: components/link_header_util/link_header_util_unittest.cc |
diff --git a/components/link_header_util/link_header_util_unittest.cc b/components/link_header_util/link_header_util_unittest.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..21ce2d424b741be98cfcf5000b93d38d2a04d00a |
--- /dev/null |
+++ b/components/link_header_util/link_header_util_unittest.cc |
@@ -0,0 +1,224 @@ |
+// Copyright 2016 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#include "components/link_header_util/link_header_util.h" |
+ |
+#include "base/logging.h" |
+#include "base/run_loop.h" |
+#include "testing/gtest/include/gtest/gtest.h" |
+ |
+namespace link_header_util { |
+ |
+namespace { |
+ |
+void SplitLinkHeaderForTesting(const std::string& header, |
+ std::vector<std::string>* values) { |
+ std::vector<StringIteratorPair> values_iterators = SplitLinkHeader(header); |
+ values->clear(); |
+ for (const auto& pair : values_iterators) |
+ values->push_back(std::string(pair.first, pair.second)); |
+} |
+ |
+bool ParseLinkHeaderValueForTesting( |
+ std::string value, |
+ std::string* url, |
+ std::unordered_map<std::string, base::Optional<std::string>>* params) { |
+ return ParseLinkHeaderValue(value.begin(), value.end(), url, params); |
+} |
+ |
+TEST(LinkHeaderTest, SplitEmpty) { |
+ std::vector<std::string> values; |
+ SplitLinkHeaderForTesting("", &values); |
+ ASSERT_EQ(0u, values.size()); |
+} |
+ |
+TEST(LinkHeaderTest, SplitSimple) { |
+ std::vector<std::string> values; |
+ SplitLinkHeaderForTesting("hello", &values); |
+ ASSERT_EQ(1u, values.size()); |
+ EXPECT_EQ("hello", values[0]); |
+ |
+ SplitLinkHeaderForTesting("foo, bar", &values); |
+ ASSERT_EQ(2u, values.size()); |
+ EXPECT_EQ("foo", values[0]); |
+ EXPECT_EQ("bar", values[1]); |
+ |
+ SplitLinkHeaderForTesting(" 1\t,\t2,3", &values); |
+ ASSERT_EQ(3u, values.size()); |
+ EXPECT_EQ("1", values[0]); |
+ EXPECT_EQ("2", values[1]); |
+ EXPECT_EQ("3", values[2]); |
+} |
+ |
+TEST(LinkHeaderTest, SplitSkipsEmpty) { |
+ std::vector<std::string> values; |
+ SplitLinkHeaderForTesting(", foo, , \t, bar", &values); |
+ ASSERT_EQ(2u, values.size()); |
+ EXPECT_EQ("foo", values[0]); |
+ EXPECT_EQ("bar", values[1]); |
+} |
+ |
+TEST(LinkHeaderTest, SplitQuotes) { |
+ std::vector<std::string> values; |
+ SplitLinkHeaderForTesting("\"foo,bar\", 'bar,foo', <hel,lo>", &values); |
+ ASSERT_EQ(4u, values.size()); |
+ EXPECT_EQ("\"foo,bar\"", values[0]); |
+ EXPECT_EQ("'bar", values[1]); |
+ EXPECT_EQ("foo'", values[2]); |
+ EXPECT_EQ("<hel,lo>", values[3]); |
+} |
+ |
+TEST(LinkHeaderTest, SplitEscapedQuotes) { |
+ std::vector<std::string> values; |
+ SplitLinkHeaderForTesting("\"f\\\"oo,bar\", 'b\\'ar,foo', <hel\\>,lo>", |
+ &values); |
+ ASSERT_EQ(5u, values.size()); |
+ EXPECT_EQ("\"f\\\"oo,bar\"", values[0]); |
+ EXPECT_EQ("'b\\'ar", values[1]); |
+ EXPECT_EQ("foo'", values[2]); |
+ EXPECT_EQ("<hel\\>", values[3]); |
+ EXPECT_EQ("lo>", values[4]); |
+} |
+ |
+struct SimpleParseTestData { |
+ const char* link; |
+ bool valid; |
+ const char* url; |
+ const char* rel; |
+ const char* as; |
+}; |
+ |
+void PrintTo(const SimpleParseTestData& test, std::ostream* os) { |
+ *os << ::testing::PrintToString(test.link); |
+} |
+ |
+class SimpleParseTest : public ::testing::TestWithParam<SimpleParseTestData> {}; |
+ |
+TEST_P(SimpleParseTest, Simple) { |
+ const SimpleParseTestData test = GetParam(); |
+ |
+ std::string url; |
+ std::unordered_map<std::string, base::Optional<std::string>> params; |
+ EXPECT_EQ(test.valid, |
+ ParseLinkHeaderValueForTesting(test.link, &url, ¶ms)); |
+ if (test.valid) { |
+ EXPECT_EQ(test.url, url); |
+ EXPECT_EQ(test.rel, params["rel"].value_or("")); |
+ EXPECT_EQ(test.as, params["as"].value_or("")); |
+ } |
+} |
+ |
+// Test data mostly copied from blink::LinkHeaderTest. Expectations for a small |
+// subset of test cases are different though. Mostly because blink::LinkHeader |
+// factors in knowledge about semantics of Link headers (parameters that are |
+// required to have a value if they occur, some parameters are auto-lower-cased, |
+// headers with an "anchor" parameter are rejected by base::LinkHeader). |
+// The code this tests purely parses without actually interpreting the data, as |
+// it is expected that another layer on top will do more specific validations. |
+const SimpleParseTestData simple_parse_tests[] = { |
+ {"</images/cat.jpg>; rel=prefetch", true, "/images/cat.jpg", "prefetch", |
+ ""}, |
+ {"</images/cat.jpg>;rel=prefetch", true, "/images/cat.jpg", "prefetch", ""}, |
+ {"</images/cat.jpg> ;rel=prefetch", true, "/images/cat.jpg", "prefetch", |
+ ""}, |
+ {"</images/cat.jpg> ; rel=prefetch", true, "/images/cat.jpg", |
+ "prefetch", ""}, |
+ {"< /images/cat.jpg> ; rel=prefetch", true, "/images/cat.jpg", |
+ "prefetch", ""}, |
+ {"</images/cat.jpg > ; rel=prefetch", true, "/images/cat.jpg", |
+ "prefetch", ""}, |
+ {"</images/cat.jpg wutwut> ; rel=prefetch", true, |
+ "/images/cat.jpg wutwut", "prefetch", ""}, |
+ {"</images/cat.jpg wutwut \t > ; rel=prefetch", true, |
+ "/images/cat.jpg wutwut", "prefetch", ""}, |
+ {"</images/cat.jpg>; rel=prefetch ", true, "/images/cat.jpg", "prefetch", |
+ ""}, |
+ {"</images/cat.jpg>; Rel=prefetch ", true, "/images/cat.jpg", "prefetch", |
+ ""}, |
+ {"</images/cat.jpg>; Rel=PReFetCh ", true, "/images/cat.jpg", "PReFetCh", |
+ ""}, |
+ {"</images/cat.jpg>; rel=prefetch; rel=somethingelse", true, |
+ "/images/cat.jpg", "prefetch", ""}, |
+ {"</images/cat.jpg>\t\t ; \trel=prefetch \t ", true, "/images/cat.jpg", |
+ "prefetch", ""}, |
+ {"</images/cat.jpg>; rel= prefetch", true, "/images/cat.jpg", "prefetch", |
+ ""}, |
+ {"<../images/cat.jpg?dog>; rel= prefetch", true, "../images/cat.jpg?dog", |
+ "prefetch", ""}, |
+ {"</images/cat.jpg>; rel =prefetch", true, "/images/cat.jpg", "prefetch", |
+ ""}, |
+ {"</images/cat.jpg>; rel pel=prefetch", false}, |
+ {"< /images/cat.jpg>", true, "/images/cat.jpg", "", ""}, |
+ {"</images/cat.jpg>; wut=sup; rel =prefetch", true, "/images/cat.jpg", |
+ "prefetch", ""}, |
+ {"</images/cat.jpg>; wut=sup ; rel =prefetch", true, "/images/cat.jpg", |
+ "prefetch", ""}, |
+ {"</images/cat.jpg>; wut=sup ; rel =prefetch \t ;", true, |
+ "/images/cat.jpg", "prefetch", ""}, |
+ {"</images/cat.jpg> wut=sup ; rel =prefetch \t ;", false}, |
+ {"< /images/cat.jpg", false}, |
+ {"< http://wut.com/ sdfsdf ?sd>; rel=dns-prefetch", true, |
+ "http://wut.com/ sdfsdf ?sd", "dns-prefetch", ""}, |
+ {"< http://wut.com/%20%20%3dsdfsdf?sd>; rel=dns-prefetch", true, |
+ "http://wut.com/%20%20%3dsdfsdf?sd", "dns-prefetch", ""}, |
+ {"< http://wut.com/dfsdf?sdf=ghj&wer=rty>; rel=prefetch", true, |
+ "http://wut.com/dfsdf?sdf=ghj&wer=rty", "prefetch", ""}, |
+ {"< http://wut.com/dfsdf?sdf=ghj&wer=rty>;;;;; rel=prefetch", true, |
+ "http://wut.com/dfsdf?sdf=ghj&wer=rty", "prefetch", ""}, |
+ {"< http://wut.com/%20%20%3dsdfsdf?sd>; rel=preload;as=image", true, |
+ "http://wut.com/%20%20%3dsdfsdf?sd", "preload", "image"}, |
+ {"< http://wut.com/%20%20%3dsdfsdf?sd>; rel=preload;as=whatever", true, |
+ "http://wut.com/%20%20%3dsdfsdf?sd", "preload", "whatever"}, |
+ {"</images/cat.jpg>; rel=prefetch;", true, "/images/cat.jpg", "prefetch", |
+ ""}, |
+ {"</images/cat.jpg>; rel=prefetch ;", true, "/images/cat.jpg", |
+ "prefetch", ""}, |
+ {"</images/ca,t.jpg>; rel=prefetch ;", true, "/images/ca,t.jpg", |
+ "prefetch", ""}, |
+ {"<simple.css>; rel=stylesheet; title=\"title with a DQUOTE and " |
+ "backslash\"", |
+ true, "simple.css", "stylesheet", ""}, |
+ {"<simple.css>; rel=stylesheet; title=\"title with a DQUOTE \\\" and " |
+ "backslash: \\\"", |
+ false}, |
+ {"<simple.css>; title=\"title with a DQUOTE \\\" and backslash: \"; " |
+ "rel=stylesheet; ", |
+ true, "simple.css", "stylesheet", ""}, |
+ {"<simple.css>; title=\'title with a DQUOTE \\\' and backslash: \'; " |
+ "rel=stylesheet; ", |
+ true, "simple.css", "stylesheet", ""}, |
+ {"<simple.css>; title=\"title with a DQUOTE \\\" and ;backslash,: \"; " |
+ "rel=stylesheet; ", |
+ true, "simple.css", "stylesheet", ""}, |
+ {"<simple.css>; title=\"title with a DQUOTE \' and ;backslash,: \"; " |
+ "rel=stylesheet; ", |
+ true, "simple.css", "stylesheet", ""}, |
+ {"<simple.css>; title=\"\"; rel=stylesheet; ", true, "simple.css", |
+ "stylesheet", ""}, |
+ {"<simple.css>; title=\"\"; rel=\"stylesheet\"; ", true, "simple.css", |
+ "stylesheet", ""}, |
+ {"<simple.css>; rel=stylesheet; title=\"", false}, |
+ {"<simple.css>; rel=stylesheet; title=\"\"", true, "simple.css", |
+ "stylesheet", ""}, |
+ {"<simple.css>; rel=\"stylesheet\"; title=\"", false}, |
+ {"<simple.css>; rel=\";style,sheet\"; title=\"", false}, |
+ {"<simple.css>; rel=\"bla'sdf\"; title=\"", false}, |
+ {"<simple.css>; rel=\"\"; title=\"\"", true, "simple.css", "", ""}, |
+ {"<simple.css>; rel=''; title=\"\"", true, "simple.css", "''", ""}, |
+ {"<simple.css>; rel=''; bla", true, "simple.css", "''", ""}, |
+ {"<simple.css>; rel='prefetch", true, "simple.css", "'prefetch", ""}, |
+ {"<simple.css>; rel=\"prefetch", false}, |
+ {"<simple.css>; rel=\"", false}, |
+ {"simple.css; rel=prefetch", false}, |
+ {"<simple.css>; rel=prefetch; rel=foobar", true, "simple.css", "prefetch", |
+ ""}, |
+}; |
+ |
+INSTANTIATE_TEST_CASE_P(LinkHeaderTest, |
+ SimpleParseTest, |
+ testing::ValuesIn(simple_parse_tests)); |
+ |
+} // namespace |
+ |
+} // namespace link_header_util |