blob: 1c221fc219f915bac72cd1c71ef222751e5574a9 [file] [log] [blame]
// Copyright 2013 The Flutter 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 <comdef.h>
#include <comip.h>
#include <windows.h>
#include <functional>
#include <memory>
#include <variant>
#include <vector>
#include "file_dialog_controller.h"
#include "test/test_utils.h"
namespace file_selector_windows {
namespace test {
class TestFileDialogController;
// A value to use for GetResult(s) in TestFileDialogController. The type depends
// on whether the dialog is an open or save dialog.
using MockShowResult =
std::variant<std::monostate, IShellItemPtr, IShellItemArrayPtr>;
// Called for TestFileDialogController::Show, to do validation and provide a
// mock return value for GetResult(s).
using MockShow =
std::function<MockShowResult(const TestFileDialogController&, HWND)>;
// A C++-friendly version of a COMDLG_FILTERSPEC.
struct DialogFilter {
std::wstring name;
std::wstring spec;
DialogFilter(const wchar_t* name, const wchar_t* spec)
: name(name), spec(spec) {}
// An extension of the normal file dialog controller that:
// - Allows for inspection of set values.
// - Allows faking the 'Show' interaction, providing tests an opportunity to
// validate the dialog settings and provide a return value, via MockShow.
class TestFileDialogController : public FileDialogController {
TestFileDialogController(IFileDialog* dialog, MockShow mock_show);
// FileDialogController:
HRESULT SetFolder(IShellItem* folder) override;
HRESULT SetFileTypes(UINT count, COMDLG_FILTERSPEC* filters) override;
HRESULT SetOkButtonLabel(const wchar_t* text) override;
HRESULT Show(HWND parent) override;
HRESULT GetResult(IShellItem** out_item) const override;
HRESULT GetResults(IShellItemArray** out_items) const override;
// Accessors for validating IFileDialogController setter calls.
// Gets the folder path set by FileDialogController::SetFolder.
// This exists because there are multiple ways that the value returned by
// GetDialogFolderPath can be changed, so this allows specifically validating
// calls to SetFolder.
std::wstring GetSetFolderPath() const;
// Gets dialog folder path by calling IFileDialog::GetFolder.
std::wstring GetDialogFolderPath() const;
std::wstring GetFileName() const;
const std::vector<DialogFilter>& GetFileTypes() const;
std::wstring GetOkButtonLabel() const;
IFileDialogPtr dialog_;
MockShow mock_show_;
MockShowResult mock_result_;
// The last set values, for IFileDialog properties that have setters but no
// corresponding getters.
std::wstring set_folder_path_;
std::wstring ok_button_label_;
std::vector<DialogFilter> filter_groups_;
// A controller factory that vends TestFileDialogController instances.
class TestFileDialogControllerFactory : public FileDialogControllerFactory {
// Creates a factory whose instances use mock_show for the Show callback.
TestFileDialogControllerFactory(MockShow mock_show);
virtual ~TestFileDialogControllerFactory();
// Disallow copy and assign.
TestFileDialogControllerFactory(const TestFileDialogControllerFactory&) =
TestFileDialogControllerFactory& operator=(
const TestFileDialogControllerFactory&) = delete;
// FileDialogControllerFactory:
std::unique_ptr<FileDialogController> CreateController(
IFileDialog* dialog) const override;
MockShow mock_show_;
} // namespace test
} // namespace file_selector_windows