aboutsummaryrefslogtreecommitdiffstats
path: root/src/plugins/webassembly/webassemblyrunconfigurationaspects.cpp
blob: f68d23ed221c895a9ebabab1d17548e384371147 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
// Copyright (C) 2019 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0

#include "webassemblyrunconfigurationaspects.h"

#include <projectexplorer/buildconfiguration.h>
#include <projectexplorer/runcontrol.h>
#include <projectexplorer/target.h>

#include <utils/layoutbuilder.h>
#include <utils/qtcprocess.h>

#include <QComboBox>
#include <QTextStream>

#ifdef WITH_TESTS
#   include <QTest>
#   include "webassemblyplugin.h"
#endif // WITH_TESTS

using namespace Utils;

namespace WebAssembly {
namespace Internal {

static const char BROWSER_KEY[] = "WASM.WebBrowserSelectionAspect.Browser";

static WebBrowserEntries parseEmrunOutput(const QByteArray &output)
{
    WebBrowserEntries result;
    QTextStream ts(output);
    QString line;
    const QRegularExpression regExp("  - (.*):(.*)");
    while (ts.readLineInto(&line)) {
        const QRegularExpressionMatch match = regExp.match(line);
        if (match.hasMatch())
            result << qMakePair(match.captured(1), match.captured(2).trimmed());
    }
    return result;
}

static WebBrowserEntries emrunBrowsers(ProjectExplorer::Target *target)
{
    WebBrowserEntries result;
    result.append(qMakePair(QString(), WebBrowserSelectionAspect::tr("Default Browser")));
    if (auto bc = target->activeBuildConfiguration()) {
        const Utils::Environment environment = bc->environment();
        const Utils::FilePath emrunPath = environment.searchInPath("emrun");

        QtcProcess browserLister;
        browserLister.setEnvironment(environment);
        browserLister.setCommand({emrunPath, {"--list_browsers"}});
        browserLister.start();

        if (browserLister.waitForFinished())
            result.append(parseEmrunOutput(browserLister.readAllStandardOutput()));
    }
    return result;
}

WebBrowserSelectionAspect::WebBrowserSelectionAspect(ProjectExplorer::Target *target)
    : m_availableBrowsers(emrunBrowsers(target))
{
    if (!m_availableBrowsers.isEmpty()) {
        const int defaultIndex = qBound(0, m_availableBrowsers.count() - 1, 1);
        m_currentBrowser = m_availableBrowsers.at(defaultIndex).first;
    }
    setDisplayName(tr("Web Browser"));
    setId("WebBrowserAspect");
    setSettingsKey("RunConfiguration.WebBrowser");

    addDataExtractor(this, &WebBrowserSelectionAspect::currentBrowser, &Data::currentBrowser);
}

void WebBrowserSelectionAspect::addToLayout(LayoutBuilder &builder)
{
    QTC_CHECK(!m_webBrowserComboBox);
    m_webBrowserComboBox = new QComboBox;
    for (const WebBrowserEntry &be : m_availableBrowsers)
        m_webBrowserComboBox->addItem(be.second, be.first);
    m_webBrowserComboBox->setCurrentIndex(m_webBrowserComboBox->findData(m_currentBrowser));
    connect(m_webBrowserComboBox, &QComboBox::currentIndexChanged, this, [this] {
        m_currentBrowser = m_webBrowserComboBox->currentData().toString();
        emit changed();
    });
    builder.addItems({tr("Web browser:"), m_webBrowserComboBox});
}

void WebBrowserSelectionAspect::fromMap(const QVariantMap &map)
{
    if (!m_availableBrowsers.isEmpty())
        m_currentBrowser = map.value(BROWSER_KEY, m_availableBrowsers.first().first).toString();
}

void WebBrowserSelectionAspect::toMap(QVariantMap &map) const
{
    map.insert(BROWSER_KEY, m_currentBrowser);
}

QString WebBrowserSelectionAspect::currentBrowser() const
{
    return m_currentBrowser;
}

// Unit tests:
#ifdef WITH_TESTS

void testEmrunBrowserListParsing();
void testEmrunBrowserListParsing_data();

void WebAssemblyPlugin::testEmrunBrowserListParsing()
{
    QFETCH(QByteArray, emrunOutput);
    QFETCH(WebBrowserEntries, expectedBrowsers);

    QCOMPARE(parseEmrunOutput(emrunOutput), expectedBrowsers);
}

void WebAssemblyPlugin::testEmrunBrowserListParsing_data()
{
    QTest::addColumn<QByteArray>("emrunOutput");
    QTest::addColumn<WebBrowserEntries>("expectedBrowsers");

    QTest::newRow("emsdk 1.39.8")
// Output of "emrun --list_browsers"
            << QByteArray(
R"(emrun has automatically found the following browsers in the default install locations on the system:

  - firefox: Mozilla Firefox
  - chrome: Google Chrome

You can pass the --browser <id> option to launch with the given browser above.
Even if your browser was not detected, you can use --browser /path/to/browser/executable to launch with that browser.

)")
            << WebBrowserEntries({
                qMakePair(QLatin1String("firefox"), QLatin1String("Mozilla Firefox")),
                qMakePair(QLatin1String("chrome"), QLatin1String("Google Chrome"))});

    QTest::newRow("emsdk 2.0.14")
            << QByteArray(
R"(emrun has automatically found the following browsers in the default install locations on the system:

  - firefox: Mozilla Firefox 96.0.0.8041
  - chrome: Google Chrome 97.0.4692.71

You can pass the --browser <id> option to launch with the given browser above.
Even if your browser was not detected, you can use --browser /path/to/browser/executable to launch with that browser.

)")
            << WebBrowserEntries({
                qMakePair(QLatin1String("firefox"), QLatin1String("Mozilla Firefox 96.0.0.8041")),
                qMakePair(QLatin1String("chrome"), QLatin1String("Google Chrome 97.0.4692.71"))});
}

#endif // WITH_TESTS

} // namespace Internal
} // namespace Webassembly