[contextualprocess] Split API
In order to test some of the internals, split them into Binding.h. This makes the interface visible for tests. The implementation still lives in the same place. While here, adjust the test to the changed **example** which now lists an additional variable.
This commit is contained in:
parent
4a5b3e7bc8
commit
bdb208c079
95
src/modules/contextualprocess/Binding.h
Normal file
95
src/modules/contextualprocess/Binding.h
Normal file
@ -0,0 +1,95 @@
|
||||
/* === This file is part of Calamares - <https://github.com/calamares> ===
|
||||
*
|
||||
* Copyright 2017-2020, Adriaan de Groot <groot@kde.org>
|
||||
*
|
||||
* Calamares is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Calamares is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Calamares. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/* This file isn't public API, but is used to express the API that
|
||||
* the tests for ContextualProcess can work with.
|
||||
*/
|
||||
#ifndef CONTEXTUALPROCESSJOB_BINDING_H
|
||||
#define CONTEXTUALPROCESSJOB_BINDING_H
|
||||
|
||||
#include <QList>
|
||||
#include <QPair>
|
||||
#include <QString>
|
||||
|
||||
namespace CalamaresUtils
|
||||
{
|
||||
class CommandList;
|
||||
}
|
||||
namespace Calamares
|
||||
{
|
||||
class GlobalStorage;
|
||||
}
|
||||
|
||||
struct ValueCheck : public QPair< QString, CalamaresUtils::CommandList* >
|
||||
{
|
||||
ValueCheck( const QString& value, CalamaresUtils::CommandList* commands )
|
||||
: QPair< QString, CalamaresUtils::CommandList* >( value, commands )
|
||||
{
|
||||
}
|
||||
|
||||
// ~ValueCheck()
|
||||
//
|
||||
// There is no destructor.
|
||||
//
|
||||
// We don't own the commandlist, the binding holding this valuecheck
|
||||
// does, so don't delete. This is closely tied to (temporaries created
|
||||
// by) pass-by-value in QList::append().
|
||||
|
||||
QString value() const { return first; }
|
||||
CalamaresUtils::CommandList* commands() const { return second; }
|
||||
};
|
||||
|
||||
class ContextualProcessBinding
|
||||
{
|
||||
public:
|
||||
ContextualProcessBinding( const QString& varname )
|
||||
: m_variable( varname )
|
||||
{
|
||||
}
|
||||
|
||||
~ContextualProcessBinding();
|
||||
|
||||
QString variable() const { return m_variable; }
|
||||
int count() const { return m_checks.count(); }
|
||||
|
||||
/**
|
||||
* @brief add commands to be executed when @p value is matched.
|
||||
*
|
||||
* Ownership of the CommandList passes to this binding.
|
||||
*/
|
||||
void append( const QString& value, CalamaresUtils::CommandList* commands );
|
||||
|
||||
///@brief The bound variable has @p value , run the associated commands.
|
||||
Calamares::JobResult run( const QString& value ) const;
|
||||
|
||||
/** @brief Tries to obtain this binding's value from GS
|
||||
*
|
||||
* Stores the value in @p value and returns true if a value
|
||||
* was found (e.g. @p storage contains the variable this binding
|
||||
* is for) and false otherwise.
|
||||
*/
|
||||
bool fetch( Calamares::GlobalStorage* storage, QString& value ) const;
|
||||
|
||||
private:
|
||||
QString m_variable;
|
||||
QList< ValueCheck > m_checks;
|
||||
CalamaresUtils::CommandList* m_wildcard = nullptr;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
@ -18,9 +18,7 @@
|
||||
|
||||
#include "ContextualProcessJob.h"
|
||||
|
||||
#include <QDateTime>
|
||||
#include <QProcess>
|
||||
#include <QThread>
|
||||
#include "Binding.h"
|
||||
|
||||
#include "CalamaresVersion.h"
|
||||
#include "GlobalStorage.h"
|
||||
@ -30,120 +28,6 @@
|
||||
#include "utils/Logger.h"
|
||||
#include "utils/Variant.h"
|
||||
|
||||
struct ValueCheck : public QPair< QString, CalamaresUtils::CommandList* >
|
||||
{
|
||||
ValueCheck( const QString& value, CalamaresUtils::CommandList* commands )
|
||||
: QPair< QString, CalamaresUtils::CommandList* >( value, commands )
|
||||
{
|
||||
}
|
||||
|
||||
// ~ValueCheck()
|
||||
//
|
||||
// There is no destructor.
|
||||
//
|
||||
// We don't own the commandlist, the binding holding this valuecheck
|
||||
// does, so don't delete. This is closely tied to (temporaries created
|
||||
// by) pass-by-value in QList::append().
|
||||
|
||||
QString value() const { return first; }
|
||||
CalamaresUtils::CommandList* commands() const { return second; }
|
||||
};
|
||||
|
||||
class ContextualProcessBinding
|
||||
{
|
||||
public:
|
||||
ContextualProcessBinding( const QString& varname )
|
||||
: m_variable( varname )
|
||||
{
|
||||
}
|
||||
|
||||
~ContextualProcessBinding();
|
||||
|
||||
QString variable() const { return m_variable; }
|
||||
int count() const { return m_checks.count(); }
|
||||
|
||||
/**
|
||||
* @brief add commands to be executed when @p value is matched.
|
||||
*
|
||||
* Ownership of the CommandList passes to this binding.
|
||||
*/
|
||||
void append( const QString& value, CalamaresUtils::CommandList* commands )
|
||||
{
|
||||
m_checks.append( ValueCheck( value, commands ) );
|
||||
if ( value == QString( "*" ) )
|
||||
{
|
||||
m_wildcard = commands;
|
||||
}
|
||||
}
|
||||
|
||||
Calamares::JobResult run( const QString& value ) const
|
||||
{
|
||||
for ( const auto& c : m_checks )
|
||||
{
|
||||
if ( value == c.value() )
|
||||
{
|
||||
return c.commands()->run();
|
||||
}
|
||||
}
|
||||
|
||||
if ( m_wildcard )
|
||||
{
|
||||
return m_wildcard->run();
|
||||
}
|
||||
|
||||
return Calamares::JobResult::ok();
|
||||
}
|
||||
|
||||
/** @brief Tries to obtain this binding's value from GS
|
||||
*
|
||||
* Stores the value in @p value and returns true if a value
|
||||
* was found (e.g. @p storage contains the variable this binding
|
||||
* is for) and false otherwise.
|
||||
*/
|
||||
bool fetch( Calamares::GlobalStorage* storage, QString& value ) const
|
||||
{
|
||||
value.clear();
|
||||
if ( !storage )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if ( m_variable.contains( '.' ) )
|
||||
{
|
||||
QStringList steps = m_variable.split( '.' );
|
||||
return fetch( value, steps, 1, storage->value( steps.first() ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
value = storage->value( m_variable ).toString();
|
||||
return storage->contains( m_variable );
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
static bool fetch( QString& value, QStringList& selector, int index, const QVariant& v )
|
||||
{
|
||||
if ( !v.canConvert( QMetaType::QVariantMap ) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
const QVariantMap map = v.toMap();
|
||||
const QString& key = selector.at( index );
|
||||
if ( index == selector.length() )
|
||||
{
|
||||
value = map.value( key ).toString();
|
||||
return map.contains( key );
|
||||
}
|
||||
else
|
||||
{
|
||||
return fetch( value, selector, index + 1, map.value( key ) );
|
||||
}
|
||||
}
|
||||
|
||||
QString m_variable;
|
||||
QList< ValueCheck > m_checks;
|
||||
CalamaresUtils::CommandList* m_wildcard = nullptr;
|
||||
};
|
||||
|
||||
|
||||
ContextualProcessBinding::~ContextualProcessBinding()
|
||||
{
|
||||
@ -154,6 +38,78 @@ ContextualProcessBinding::~ContextualProcessBinding()
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ContextualProcessBinding::append( const QString& value, CalamaresUtils::CommandList* commands )
|
||||
{
|
||||
m_checks.append( ValueCheck( value, commands ) );
|
||||
if ( value == QString( "*" ) )
|
||||
{
|
||||
m_wildcard = commands;
|
||||
}
|
||||
}
|
||||
|
||||
Calamares::JobResult
|
||||
ContextualProcessBinding::run( const QString& value ) const
|
||||
{
|
||||
for ( const auto& c : m_checks )
|
||||
{
|
||||
if ( value == c.value() )
|
||||
{
|
||||
return c.commands()->run();
|
||||
}
|
||||
}
|
||||
|
||||
if ( m_wildcard )
|
||||
{
|
||||
return m_wildcard->run();
|
||||
}
|
||||
|
||||
return Calamares::JobResult::ok();
|
||||
}
|
||||
|
||||
///@brief Implementation of fetch() for recursively looking up dotted selector parts.
|
||||
static bool
|
||||
fetch( QString& value, QStringList& selector, int index, const QVariant& v )
|
||||
{
|
||||
if ( !v.canConvert( QMetaType::QVariantMap ) )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
const QVariantMap map = v.toMap();
|
||||
const QString& key = selector.at( index );
|
||||
if ( index == selector.length() )
|
||||
{
|
||||
value = map.value( key ).toString();
|
||||
return map.contains( key );
|
||||
}
|
||||
else
|
||||
{
|
||||
return fetch( value, selector, index + 1, map.value( key ) );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool
|
||||
ContextualProcessBinding::fetch( Calamares::GlobalStorage* storage, QString& value ) const
|
||||
{
|
||||
value.clear();
|
||||
if ( !storage )
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if ( m_variable.contains( '.' ) )
|
||||
{
|
||||
QStringList steps = m_variable.split( '.' );
|
||||
return ::fetch( value, steps, 1, storage->value( steps.first() ) );
|
||||
}
|
||||
else
|
||||
{
|
||||
value = storage->value( m_variable ).toString();
|
||||
return storage->contains( m_variable );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
ContextualProcessJob::ContextualProcessJob( QObject* parent )
|
||||
: Calamares::CppJob( parent )
|
||||
{
|
||||
|
@ -27,7 +27,7 @@
|
||||
|
||||
#include "utils/PluginFactory.h"
|
||||
|
||||
struct ContextualProcessBinding;
|
||||
class ContextualProcessBinding;
|
||||
|
||||
class PLUGINDLLEXPORT ContextualProcessJob : public Calamares::CppJob
|
||||
{
|
||||
|
@ -59,6 +59,6 @@ ContextualProcessTests::testProcessListSampleConfig()
|
||||
ContextualProcessJob job;
|
||||
job.setConfigurationMap( CalamaresUtils::yamlMapToVariant( doc ).toMap() );
|
||||
|
||||
QCOMPARE( job.count(), 1 ); // Only "firmwareType"
|
||||
QCOMPARE( job.count(), 2 ); // Only "firmwareType" and "branding.shortVersion"
|
||||
QCOMPARE( job.count( "firmwareType" ), 4 );
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user