blob: 881fbdbb44947455256461be835ac8799976f926 [file] [log] [blame]
weinig@apple.com1e83db42020-10-12 21:54:50 +00001/*
2 * Copyright (C) 2020 Apple Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23 * THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26#include "config.h"
27#include "TestCommand.h"
28
29namespace WTR {
30
31class CommandTokenizer {
32public:
33 explicit CommandTokenizer(const std::string& input)
34 : m_input(input)
35 , m_posNextSeparator(0)
36 {
37 pump();
38 }
39
40 bool hasNext() const;
41 std::string next();
42
43private:
44 void pump();
45 static const char kSeparator = '\'';
46 const std::string& m_input;
47 std::string m_next;
48 size_t m_posNextSeparator;
49};
50
51void CommandTokenizer::pump()
52{
53 if (m_posNextSeparator == std::string::npos || m_posNextSeparator == m_input.size()) {
54 m_next = std::string();
55 return;
56 }
57 size_t start = m_posNextSeparator ? m_posNextSeparator + 1 : 0;
58 m_posNextSeparator = m_input.find(kSeparator, start);
59 size_t size = m_posNextSeparator == std::string::npos ? std::string::npos : m_posNextSeparator - start;
60 m_next = std::string(m_input, start, size);
61}
62
63std::string CommandTokenizer::next()
64{
65 ASSERT(hasNext());
66
67 std::string oldNext = m_next;
68 pump();
69 return oldNext;
70}
71
72bool CommandTokenizer::hasNext() const
73{
74 return !m_next.empty();
75}
76
77NO_RETURN static void die(const std::string& inputLine)
78{
79 fprintf(stderr, "Unexpected input line: %s\n", inputLine.c_str());
80 exit(1);
81}
82
83TestCommand parseInputLine(const std::string& inputLine)
84{
85 TestCommand result;
86 CommandTokenizer tokenizer(inputLine);
87 if (!tokenizer.hasNext())
88 die(inputLine);
89
90 std::string arg = tokenizer.next();
91 result.pathOrURL = arg;
92 while (tokenizer.hasNext()) {
93 arg = tokenizer.next();
94 if (arg == "--timeout") {
95 auto timeoutToken = tokenizer.next();
96 result.timeout = Seconds::fromMilliseconds(atoi(timeoutToken.c_str()));
97 } else if (arg == "-p" || arg == "--pixel-test") {
98 result.shouldDumpPixels = true;
99 if (tokenizer.hasNext())
100 result.expectedPixelHash = tokenizer.next();
101 } else if (arg == std::string("--dump-jsconsolelog-in-stderr"))
102 result.dumpJSConsoleLogInStdErr = true;
103 else if (arg == std::string("--absolutePath"))
104 result.absolutePath = tokenizer.next();
105 else
106 die(inputLine);
107 }
108
109 if (result.absolutePath.empty())
110 result.absolutePath = testPath(result.pathOrURL);
111
112 return result;
113}
114
115std::filesystem::path testPath(const std::string& pathOrURL)
116{
117 if (pathOrURL.find("http://") == 0 || pathOrURL.find("https://") == 0)
118 return { };
119
120 if (pathOrURL.find("file://") == 0)
121 return pathOrURL.substr(strlen("file:/"));
122
123 return std::filesystem::absolute(pathOrURL);
124}
125
126std::string testURLString(const std::string& pathOrURL)
127{
128 if (pathOrURL.find("http://") == 0 || pathOrURL.find("https://") == 0 || pathOrURL.find("file://") == 0)
129 return pathOrURL;
130
131 return "file://" + std::filesystem::absolute(pathOrURL).generic_string();
132}
133
134}