Initial release

This commit is contained in:
civ
2026-08-16 18:24:52 +07:00
commit 876886a39a
13244 changed files with 2353959 additions and 0 deletions
@@ -0,0 +1,229 @@
##########################################################################################
# VSTGUI Unittests
##########################################################################################
set(target unittests)
set(VSTGUI_TEST_BASE "")
#set(VSTGUI_TEST_BASE "${VSTGUI_TEST_BASE}")
set(${target}_sources
"${VSTGUI_TEST_BASE}unittests.cpp"
"${VSTGUI_TEST_BASE}unittests.h"
"${VSTGUI_TEST_BASE}lib/animation/animations_test.cpp"
"${VSTGUI_TEST_BASE}lib/animation/animator_test.cpp"
"${VSTGUI_TEST_BASE}lib/animation/timingfunction_tests.cpp"
"${VSTGUI_TEST_BASE}lib/controls/ccheckbox_test.cpp"
"${VSTGUI_TEST_BASE}lib/controls/ccontrol_test.cpp"
"${VSTGUI_TEST_BASE}lib/controls/ckickbutton_test.cpp"
"${VSTGUI_TEST_BASE}lib/controls/clistcontrol_test.cpp"
"${VSTGUI_TEST_BASE}lib/controls/conoffbutton_test.cpp"
"${VSTGUI_TEST_BASE}lib/controls/coptionmenu_test.cpp"
"${VSTGUI_TEST_BASE}lib/controls/csegmentbutton_test.cpp"
"${VSTGUI_TEST_BASE}lib/controls/ctextbutton_test.cpp"
"${VSTGUI_TEST_BASE}lib/controls/cxypad_test.cpp"
"${VSTGUI_TEST_BASE}lib/algorithm_test.cpp"
"${VSTGUI_TEST_BASE}lib/cbitmap_test.cpp"
"${VSTGUI_TEST_BASE}lib/cbuttonstate_test.cpp"
"${VSTGUI_TEST_BASE}lib/cclipboard_test.cpp"
"${VSTGUI_TEST_BASE}lib/ccolor_test.cpp"
"${VSTGUI_TEST_BASE}lib/cframe_test.cpp"
"${VSTGUI_TEST_BASE}lib/cinvalidrectlist_test.cpp"
"${VSTGUI_TEST_BASE}lib/clinestyle_test.cpp"
"${VSTGUI_TEST_BASE}lib/cpoint_test.cpp"
"${VSTGUI_TEST_BASE}lib/crect_test.cpp"
"${VSTGUI_TEST_BASE}lib/csplitview_test.cpp"
"${VSTGUI_TEST_BASE}lib/cview_test.cpp"
"${VSTGUI_TEST_BASE}lib/cviewcontainer_test.cpp"
"${VSTGUI_TEST_BASE}lib/enumbitset_test.cpp"
"${VSTGUI_TEST_BASE}lib/event_test.cpp"
"${VSTGUI_TEST_BASE}lib/eventhelpers.h"
"${VSTGUI_TEST_BASE}lib/gridlayout_test.cpp"
"${VSTGUI_TEST_BASE}lib/idependency_test.cpp"
"${VSTGUI_TEST_BASE}lib/pixelbufferconverter_test.cpp"
"${VSTGUI_TEST_BASE}lib/platform_helper.h"
"${VSTGUI_TEST_BASE}lib/task_test.cpp"
"${VSTGUI_TEST_BASE}lib/utf8string_test.cpp"
"${VSTGUI_TEST_BASE}lib/utf8stringview_test.cpp"
"${VSTGUI_TEST_BASE}uidescription/uiviewcreator/canimationsplashscreencreator_test.cpp"
"${VSTGUI_TEST_BASE}uidescription/uiviewcreator/canimknobcreator_test.cpp"
"${VSTGUI_TEST_BASE}uidescription/uiviewcreator/ccheckboxcreator_test.cpp"
"${VSTGUI_TEST_BASE}uidescription/uiviewcreator/ccontrolcreator_test.cpp"
"${VSTGUI_TEST_BASE}uidescription/uiviewcreator/cgradientviewcreator_test.cpp"
"${VSTGUI_TEST_BASE}uidescription/uiviewcreator/chorizontalswitchcreator_test.cpp"
"${VSTGUI_TEST_BASE}uidescription/uiviewcreator/ckickbuttoncreator_test.cpp"
"${VSTGUI_TEST_BASE}uidescription/uiviewcreator/cknobcreator_test.cpp"
"${VSTGUI_TEST_BASE}uidescription/uiviewcreator/clayeredviewcontainercreator_test.cpp"
"${VSTGUI_TEST_BASE}uidescription/uiviewcreator/cmoviebitmapcreator_test.cpp"
"${VSTGUI_TEST_BASE}uidescription/uiviewcreator/cmoviebuttoncreator_test.cpp"
"${VSTGUI_TEST_BASE}uidescription/uiviewcreator/cmultilinetextlabelcreator_test.cpp"
"${VSTGUI_TEST_BASE}uidescription/uiviewcreator/conoffbuttoncreator_test.cpp"
"${VSTGUI_TEST_BASE}uidescription/uiviewcreator/coptionmenucreator_test.cpp"
"${VSTGUI_TEST_BASE}uidescription/uiviewcreator/cparamdisplaycreator_test.cpp"
"${VSTGUI_TEST_BASE}uidescription/uiviewcreator/crockerswitchcreator_test.cpp"
"${VSTGUI_TEST_BASE}uidescription/uiviewcreator/crowcolumnviewcreator_test.cpp"
"${VSTGUI_TEST_BASE}uidescription/uiviewcreator/cscrollviewcreator_test.cpp"
"${VSTGUI_TEST_BASE}uidescription/uiviewcreator/csearchtexteditcreator_test.cpp"
"${VSTGUI_TEST_BASE}uidescription/uiviewcreator/csegmentbuttoncreator_test.cpp"
"${VSTGUI_TEST_BASE}uidescription/uiviewcreator/cshadowviewcontainercreator_test.cpp"
"${VSTGUI_TEST_BASE}uidescription/uiviewcreator/cslidercreator_test.cpp"
"${VSTGUI_TEST_BASE}uidescription/uiviewcreator/csplitviewcreator_test.cpp"
"${VSTGUI_TEST_BASE}uidescription/uiviewcreator/ctextbuttoncreator_test.cpp"
"${VSTGUI_TEST_BASE}uidescription/uiviewcreator/ctexteditcreator_test.cpp"
"${VSTGUI_TEST_BASE}uidescription/uiviewcreator/ctextlabelcreator_test.cpp"
"${VSTGUI_TEST_BASE}uidescription/uiviewcreator/cverticalswitchcreator_test.cpp"
"${VSTGUI_TEST_BASE}uidescription/uiviewcreator/cviewcontainercreator_test.cpp"
"${VSTGUI_TEST_BASE}uidescription/uiviewcreator/cviewcreator_test.cpp"
"${VSTGUI_TEST_BASE}uidescription/uiviewcreator/cvumetercreator_test.cpp"
"${VSTGUI_TEST_BASE}uidescription/uiviewcreator/cxypadcreator_test.cpp"
"${VSTGUI_TEST_BASE}uidescription/uiviewcreator/helpers.h"
"${VSTGUI_TEST_BASE}uidescription/uiviewcreator/stringlistcreator_test.cpp"
"${VSTGUI_TEST_BASE}uidescription/uiviewcreator/uiviewcreator_test.cpp"
"${VSTGUI_TEST_BASE}uidescription/uiviewcreator/uiviewswitchcontainercreator_test.cpp"
"${VSTGUI_TEST_BASE}uidescription/base64codec.cpp"
"${VSTGUI_TEST_BASE}uidescription/cstream_test.cpp"
"${VSTGUI_TEST_BASE}uidescription/delegationcontroller_test.cpp"
"${VSTGUI_TEST_BASE}uidescription/uiattributes_test.cpp"
"${VSTGUI_TEST_BASE}uidescription/uidescription_addon_test.cpp"
"${VSTGUI_TEST_BASE}uidescription/uidescription_json_test.cpp"
"${VSTGUI_TEST_BASE}uidescription/uidescription_test_helper.h"
"${VSTGUI_TEST_BASE}uidescription/uidescription_xml_test.cpp"
"${VSTGUI_TEST_BASE}uidescription/uidescriptionadapter.h"
"${VSTGUI_TEST_BASE}uidescription/uiviewfactory_test.cpp"
"${VSTGUI_TEST_BASE}uidescription/uiviewswitchcontainer_test.cpp"
"${VSTGUI_TEST_BASE}uidescription/xmlparser_test.cpp"
)
##########################################################################################
if(CMAKE_HOST_APPLE)
set(${target}_sources
${${target}_sources}
"${VSTGUI_TEST_BASE}lib/platform_helper_mac.mm"
)
set(${target}_PLATFORM_LIBS
"-framework Cocoa"
"-framework OpenGL"
"-framework QuartzCore"
"-framework Accelerate"
)
endif()
##########################################################################################
if(MSVC)
set(${target}_sources
${${target}_sources}
"${VSTGUI_TEST_BASE}lib/platform_helper_win32.cpp"
"${VSTGUI_TEST_BASE}../../vstgui_win32.cpp"
)
endif()
##########################################################################################
if(UNIX AND NOT CMAKE_HOST_APPLE)
set(${target}_sources
${${target}_sources}
"${VSTGUI_TEST_BASE}lib/platform_helper_linux.cpp"
"${VSTGUI_TEST_BASE}../../vstgui_linux.cpp"
)
set(${target}_PLATFORM_LIBS
${LINUX_LIBRARIES}
stdc++fs
pthread
dl
)
endif()
##########################################################################################
if(XCODE)
option(VSTGUI_USE_XCODE_XCTEST "Use integrated Xcode testing" ON)
endif(XCODE)
if(VSTGUI_USE_XCODE_XCTEST)
include(FindXCTest REQUIRED)
set(${target}_sources
"${${target}_sources}"
"${VSTGUI_TEST_BASE}xcodetestintegration.mm"
)
xctest_add_bundle(${target} vstgui ${${target}_sources})
vstgui_set_cxx_version(${target} ${VSTGUI_CXX_VERSION})
target_compile_definitions(${target} ${VSTGUI_COMPILE_DEFINITIONS} ENABLE_UNIT_TESTS=1 VSTGUI_LIVE_EDITING=1)
target_link_libraries(${target} PRIVATE
${${target}_PLATFORM_LIBS}
vstgui
vstgui_uidescription
)
vstgui_source_group_by_folder(${target})
else()
if(CMAKE_HOST_APPLE)
set(${target}_sources
${${target}_sources}
"${VSTGUI_TEST_BASE}../../vstgui_mac.mm"
)
endif()
set(${target}_sources
${${target}_sources}
"${VSTGUI_TEST_BASE}../../vstgui_uidescription.cpp"
"${VSTGUI_TEST_BASE}unittestmain.cpp"
)
add_executable(${target} ${${target}_sources})
target_link_libraries(${target} PRIVATE
${${target}_PLATFORM_LIBS}
)
vstgui_set_cxx_version(${target} ${VSTGUI_CXX_VERSION})
target_compile_definitions(${target} ${VSTGUI_COMPILE_DEFINITIONS} ENABLE_UNIT_TESTS=1 VSTGUI_LIVE_EDITING=1)
vstgui_source_group_by_folder(${target})
add_custom_command(TARGET ${target} POST_BUILD COMMAND "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/unittests")
##########################################################################################
if(UNIX AND NOT CMAKE_HOST_APPLE)
target_include_directories(${target} PRIVATE ${X11_INCLUDE_DIR})
target_include_directories(${target} PRIVATE ${GTK3_INCLUDE_DIRS})
target_include_directories(${target} PRIVATE ${GTKMM3_INCLUDE_DIRS})
target_include_directories(${target} PRIVATE ${FREETYPE_INCLUDE_DIRS})
endif()
if(WIN32)
target_compile_options(${target} PRIVATE /bigobj)
endif()
endif(VSTGUI_USE_XCODE_XCTEST)
if(CMAKE_HOST_APPLE)
if(CMAKE_OSX_DEPLOYMENT_TARGET VERSION_GREATER_EQUAL 11.0)
target_compile_definitions(${target} PRIVATE "VSTGUI_USE_OBJC_UTTYPE")
target_link_libraries(${target} PRIVATE
"-framework UniformTypeIdentifiers"
)
endif()
endif()
#if(CMAKE_HOST_APPLE)
# option(VSTGUI_ENABLE_CODECOVERAGE "Generate Code Coverage Data" OFF)
# if(VSTGUI_ENABLE_CODECOVERAGE)
# add_executable(codecoverage ${${target}_sources})
#
# set(target codecoverage)
#
# target_link_libraries(${target}
# "-framework Cocoa"
# "-framework OpenGL"
# "-framework QuartzCore"
# "-framework Accelerate"
# "--coverage"
# )
#
# vstgui_set_cxx_version(${target} 14)
# target_compile_definitions(${target} ${VSTGUI_COMPILE_DEFINITIONS} ENABLE_UNIT_TESTS=1 VSTGUI_LIVE_EDITING=1 VSTGUI_ENABLE_DEPRECATED_METHODS=0)
# vstgui_source_group_by_folder(${target})
# target_compile_options(${target} PUBLIC "--coverage")
# add_custom_command(TARGET ${target} POST_BUILD COMMAND "/usr/bin/ruby" "${CMAKE_CURRENT_SOURCE_DIR}/lcov/generate.rb" "${PROJECT_SOURCE_DIR}" "${CMAKE_CURRENT_BINARY_DIR}/vstgui.build/Debug/codecoverage.build/Objects-normal/x86_64" "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/${target}" "${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/coverage_output" VERBATIM)
# endif()
#endif()
+225
View File
@@ -0,0 +1,225 @@
#!/usr/bin/perl -w
#
# Copyright (c) International Business Machines Corp., 2002
#
# This program 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 2 of the License, or (at
# your option) any later version.
#
# This program 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 this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
#
# gendesc
#
# This script creates a description file as understood by genhtml.
# Input file format:
#
# For each test case:
# <test name><optional whitespace>
# <at least one whitespace character (blank/tab)><test description>
#
# Actual description may consist of several lines. By default, output is
# written to stdout. Test names consist of alphanumeric characters
# including _ and -.
#
#
# History:
# 2002-09-02: created by Peter Oberparleiter <Peter.Oberparleiter@de.ibm.com>
#
use strict;
use File::Basename;
use Getopt::Long;
use Cwd qw/abs_path/;
# Constants
our $tool_dir = abs_path(dirname($0));
our $lcov_version = "LCOV version 1.13";
our $lcov_url = "http://ltp.sourceforge.net/coverage/lcov.php";
our $tool_name = basename($0);
# Prototypes
sub print_usage(*);
sub gen_desc();
sub warn_handler($);
sub die_handler($);
# Global variables
our $help;
our $version;
our $output_filename;
our $input_filename;
#
# Code entry point
#
$SIG{__WARN__} = \&warn_handler;
$SIG{__DIE__} = \&die_handler;
# Parse command line options
if (!GetOptions("output-filename=s" => \$output_filename,
"version" =>\$version,
"help|?" => \$help
))
{
print(STDERR "Use $tool_name --help to get usage information\n");
exit(1);
}
$input_filename = $ARGV[0];
# Check for help option
if ($help)
{
print_usage(*STDOUT);
exit(0);
}
# Check for version option
if ($version)
{
print("$tool_name: $lcov_version\n");
exit(0);
}
# Check for input filename
if (!$input_filename)
{
die("No input filename specified\n".
"Use $tool_name --help to get usage information\n");
}
# Do something
gen_desc();
#
# print_usage(handle)
#
# Write out command line usage information to given filehandle.
#
sub print_usage(*)
{
local *HANDLE = $_[0];
print(HANDLE <<END_OF_USAGE)
Usage: $tool_name [OPTIONS] INPUTFILE
Convert a test case description file into a format as understood by genhtml.
-h, --help Print this help, then exit
-v, --version Print version number, then exit
-o, --output-filename FILENAME Write description to FILENAME
For more information see: $lcov_url
END_OF_USAGE
;
}
#
# gen_desc()
#
# Read text file INPUT_FILENAME and convert the contained description to a
# format as understood by genhtml, i.e.
#
# TN:<test name>
# TD:<test description>
#
# If defined, write output to OUTPUT_FILENAME, otherwise to stdout.
#
# Die on error.
#
sub gen_desc()
{
local *INPUT_HANDLE;
local *OUTPUT_HANDLE;
my $empty_line = "ignore";
open(INPUT_HANDLE, "<", $input_filename)
or die("ERROR: cannot open $input_filename!\n");
# Open output file for writing
if ($output_filename)
{
open(OUTPUT_HANDLE, ">", $output_filename)
or die("ERROR: cannot create $output_filename!\n");
}
else
{
*OUTPUT_HANDLE = *STDOUT;
}
# Process all lines in input file
while (<INPUT_HANDLE>)
{
chomp($_);
if (/^(\w[\w-]*)(\s*)$/)
{
# Matched test name
# Name starts with alphanum or _, continues with
# alphanum, _ or -
print(OUTPUT_HANDLE "TN: $1\n");
$empty_line = "ignore";
}
elsif (/^(\s+)(\S.*?)\s*$/)
{
# Matched test description
if ($empty_line eq "insert")
{
# Write preserved empty line
print(OUTPUT_HANDLE "TD: \n");
}
print(OUTPUT_HANDLE "TD: $2\n");
$empty_line = "observe";
}
elsif (/^\s*$/)
{
# Matched empty line to preserve paragraph separation
# inside description text
if ($empty_line eq "observe")
{
$empty_line = "insert";
}
}
}
# Close output file if defined
if ($output_filename)
{
close(OUTPUT_HANDLE);
}
close(INPUT_HANDLE);
}
sub warn_handler($)
{
my ($msg) = @_;
warn("$tool_name: $msg");
}
sub die_handler($)
{
my ($msg) = @_;
die("$tool_name: $msg");
}
+68
View File
@@ -0,0 +1,68 @@
#!/usr/bin/ruby
VSTGUI_DIR = File.expand_path(ARGV[0])
OBJ_DIR = File.expand_path(ARGV[1])
UNITTEST_EXE = File.expand_path(ARGV[2])
OUTPUT_DIR = File.expand_path(ARGV[3])
SCRIPT_DIR = File.expand_path(File.dirname(__FILE__))
puts "Generating Code Coverage with:"
puts "VSTGUI_DIR=" + VSTGUI_DIR
puts "OBJ_DIR=" + OBJ_DIR
puts "UNITTEST_EXE=" + UNITTEST_EXE
puts "SCRIPT_DIR=" + SCRIPT_DIR
def removeDataFromTrace(infoFile, directory)
puts "Removing test coverage from #{directory}"
system ("./lcov --remove #{infoFile} --output-file #{infoFile} #{directory}/*")
Dir.foreach(directory) { |path|
if (path != ".." && path != ".")
d = File.join(directory, path)
if (File.directory?(d))
removeDataFromTrace(infoFile, d)
end
end
}
end
begin
system (UNITTEST_EXE)
if ($? != 0)
raise "unittest error"
end
Dir.chdir (SCRIPT_DIR)
COVERAGE_FILE = "vstgui-coverage.info"
system ("./lcov --capture --no-external --base-directory #{VSTGUI_DIR} --directory #{OBJ_DIR} --output-file vstgui-coverage.info")
system ("./lcov --remove #{COVERAGE_FILE} --output-file #{COVERAGE_FILE} #{VSTGUI_DIR}/vstgui_mac.mm")
removeDataFromTrace(COVERAGE_FILE, "#{VSTGUI_DIR}/uidescription/expat")
removeDataFromTrace(COVERAGE_FILE, "#{VSTGUI_DIR}/tests/unittest")
removeDataFromTrace(COVERAGE_FILE, "#{VSTGUI_DIR}/lib/platform")
# system ("./lcov --remove vstgui-coverage.info --output-file vstgui-coverage.info #{VSTGUI_DIR}/tests/unittest/**")
if ($? != 0)
raise "lcov error"
end
puts "Generating report..."
system ("./genhtml vstgui-coverage.info -t 'VSTGUI Test Coverage' --num-spaces 4 --demangle-cpp --output-directory #{OUTPUT_DIR}")
if ($? != 0)
raise "genhtml error"
end
ensure
Dir.foreach(OBJ_DIR) { |f|
ext = File.extname(f)
if (ext == ".gcda")
File.delete (File.join(OBJ_DIR, f))
end
}
end
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+388
View File
@@ -0,0 +1,388 @@
#!/usr/bin/perl -w
#
# Copyright (c) International Business Machines Corp., 2002
#
# This program 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 2 of the License, or (at
# your option) any later version.
#
# This program 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 this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
#
#
# genpng
#
# This script creates an overview PNG image of a source code file by
# representing each source code character by a single pixel.
#
# Note that the Perl module GD.pm is required for this script to work.
# It may be obtained from http://www.cpan.org
#
# History:
# 2002-08-26: created by Peter Oberparleiter <Peter.Oberparleiter@de.ibm.com>
#
use strict;
use File::Basename;
use Getopt::Long;
use Cwd qw/abs_path/;
# Constants
our $tool_dir = abs_path(dirname($0));
our $lcov_version = "LCOV version 1.13";
our $lcov_url = "http://ltp.sourceforge.net/coverage/lcov.php";
our $tool_name = basename($0);
# Prototypes
sub gen_png($$$@);
sub check_and_load_module($);
sub genpng_print_usage(*);
sub genpng_process_file($$$$);
sub genpng_warn_handler($);
sub genpng_die_handler($);
#
# Code entry point
#
# Check whether required module GD.pm is installed
if (check_and_load_module("GD"))
{
# Note: cannot use die() to print this message because inserting this
# code into another script via do() would not fail as required!
print(STDERR <<END_OF_TEXT)
ERROR: required module GD.pm not found on this system (see www.cpan.org).
END_OF_TEXT
;
exit(2);
}
# Check whether we're called from the command line or from another script
if (!caller)
{
my $filename;
my $tab_size = 4;
my $width = 80;
my $out_filename;
my $help;
my $version;
$SIG{__WARN__} = \&genpng_warn_handler;
$SIG{__DIE__} = \&genpng_die_handler;
# Parse command line options
if (!GetOptions("tab-size=i" => \$tab_size,
"width=i" => \$width,
"output-filename=s" => \$out_filename,
"help" => \$help,
"version" => \$version))
{
print(STDERR "Use $tool_name --help to get usage ".
"information\n");
exit(1);
}
$filename = $ARGV[0];
# Check for help flag
if ($help)
{
genpng_print_usage(*STDOUT);
exit(0);
}
# Check for version flag
if ($version)
{
print("$tool_name: $lcov_version\n");
exit(0);
}
# Check options
if (!$filename)
{
die("No filename specified\n");
}
# Check for output filename
if (!$out_filename)
{
$out_filename = "$filename.png";
}
genpng_process_file($filename, $out_filename, $width, $tab_size);
exit(0);
}
#
# genpng_print_usage(handle)
#
# Write out command line usage information to given filehandle.
#
sub genpng_print_usage(*)
{
local *HANDLE = $_[0];
print(HANDLE <<END_OF_USAGE)
Usage: $tool_name [OPTIONS] SOURCEFILE
Create an overview image for a given source code file of either plain text
or .gcov file format.
-h, --help Print this help, then exit
-v, --version Print version number, then exit
-t, --tab-size TABSIZE Use TABSIZE spaces in place of tab
-w, --width WIDTH Set width of output image to WIDTH pixel
-o, --output-filename FILENAME Write image to FILENAME
For more information see: $lcov_url
END_OF_USAGE
;
}
#
# check_and_load_module(module_name)
#
# Check whether a module by the given name is installed on this system
# and make it known to the interpreter if available. Return undefined if it
# is installed, an error message otherwise.
#
sub check_and_load_module($)
{
eval("use $_[0];");
return $@;
}
#
# genpng_process_file(filename, out_filename, width, tab_size)
#
sub genpng_process_file($$$$)
{
my $filename = $_[0];
my $out_filename = $_[1];
my $width = $_[2];
my $tab_size = $_[3];
local *HANDLE;
my @source;
open(HANDLE, "<", $filename)
or die("ERROR: cannot open $filename!\n");
# Check for .gcov filename extension
if ($filename =~ /^(.*).gcov$/)
{
# Assume gcov text format
while (<HANDLE>)
{
if (/^\t\t(.*)$/)
{
# Uninstrumented line
push(@source, ":$1");
}
elsif (/^ ###### (.*)$/)
{
# Line with zero execution count
push(@source, "0:$1");
}
elsif (/^( *)(\d*) (.*)$/)
{
# Line with positive execution count
push(@source, "$2:$3");
}
}
}
else
{
# Plain text file
while (<HANDLE>) { push(@source, ":$_"); }
}
close(HANDLE);
gen_png($out_filename, $width, $tab_size, @source);
}
#
# gen_png(filename, width, tab_size, source)
#
# Write an overview PNG file to FILENAME. Source code is defined by SOURCE
# which is a list of lines <count>:<source code> per source code line.
# The output image will be made up of one pixel per character of source,
# coloring will be done according to execution counts. WIDTH defines the
# image width. TAB_SIZE specifies the number of spaces to use as replacement
# string for tabulator signs in source code text.
#
# Die on error.
#
sub gen_png($$$@)
{
my $filename = shift(@_); # Filename for PNG file
my $overview_width = shift(@_); # Imagewidth for image
my $tab_size = shift(@_); # Replacement string for tab signs
my @source = @_; # Source code as passed via argument 2
my $height; # Height as define by source size
my $overview; # Source code overview image data
my $col_plain_back; # Color for overview background
my $col_plain_text; # Color for uninstrumented text
my $col_cov_back; # Color for background of covered lines
my $col_cov_text; # Color for text of covered lines
my $col_nocov_back; # Color for background of lines which
# were not covered (count == 0)
my $col_nocov_text; # Color for test of lines which were not
# covered (count == 0)
my $col_hi_back; # Color for background of highlighted lines
my $col_hi_text; # Color for text of highlighted lines
my $line; # Current line during iteration
my $row = 0; # Current row number during iteration
my $column; # Current column number during iteration
my $color_text; # Current text color during iteration
my $color_back; # Current background color during iteration
my $last_count; # Count of last processed line
my $count; # Count of current line
my $source; # Source code of current line
my $replacement; # Replacement string for tabulator chars
local *PNG_HANDLE; # Handle for output PNG file
# Handle empty source files
if (!@source) {
@source = ( "" );
}
$height = scalar(@source);
# Create image
$overview = new GD::Image($overview_width, $height)
or die("ERROR: cannot allocate overview image!\n");
# Define colors
$col_plain_back = $overview->colorAllocate(0xff, 0xff, 0xff);
$col_plain_text = $overview->colorAllocate(0xaa, 0xaa, 0xaa);
$col_cov_back = $overview->colorAllocate(0xaa, 0xa7, 0xef);
$col_cov_text = $overview->colorAllocate(0x5d, 0x5d, 0xea);
$col_nocov_back = $overview->colorAllocate(0xff, 0x00, 0x00);
$col_nocov_text = $overview->colorAllocate(0xaa, 0x00, 0x00);
$col_hi_back = $overview->colorAllocate(0x00, 0xff, 0x00);
$col_hi_text = $overview->colorAllocate(0x00, 0xaa, 0x00);
# Visualize each line
foreach $line (@source)
{
# Replace tabs with spaces to keep consistent with source
# code view
while ($line =~ /^([^\t]*)(\t)/)
{
$replacement = " "x($tab_size - ((length($1) - 1) %
$tab_size));
$line =~ s/^([^\t]*)(\t)/$1$replacement/;
}
# Skip lines which do not follow the <count>:<line>
# specification, otherwise $1 = count, $2 = source code
if (!($line =~ /(\*?)(\d*):(.*)$/)) { next; }
$count = $2;
$source = $3;
# Decide which color pair to use
# If this line was not instrumented but the one before was,
# take the color of that line to widen color areas in
# resulting image
if (($count eq "") && defined($last_count) &&
($last_count ne ""))
{
$count = $last_count;
}
if ($count eq "")
{
# Line was not instrumented
$color_text = $col_plain_text;
$color_back = $col_plain_back;
}
elsif ($count == 0)
{
# Line was instrumented but not executed
$color_text = $col_nocov_text;
$color_back = $col_nocov_back;
}
elsif ($1 eq "*")
{
# Line was highlighted
$color_text = $col_hi_text;
$color_back = $col_hi_back;
}
else
{
# Line was instrumented and executed
$color_text = $col_cov_text;
$color_back = $col_cov_back;
}
# Write one pixel for each source character
$column = 0;
foreach (split("", $source))
{
# Check for width
if ($column >= $overview_width) { last; }
if ($_ eq " ")
{
# Space
$overview->setPixel($column++, $row,
$color_back);
}
else
{
# Text
$overview->setPixel($column++, $row,
$color_text);
}
}
# Fill rest of line
while ($column < $overview_width)
{
$overview->setPixel($column++, $row, $color_back);
}
$last_count = $2;
$row++;
}
# Write PNG file
open (PNG_HANDLE, ">", $filename)
or die("ERROR: cannot write png file $filename!\n");
binmode(*PNG_HANDLE);
print(PNG_HANDLE $overview->png());
close(PNG_HANDLE);
}
sub genpng_warn_handler($)
{
my ($msg) = @_;
warn("$tool_name: $msg");
}
sub genpng_die_handler($)
{
my ($msg) = @_;
die("$tool_name: $msg");
}
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,66 @@
// This file is part of VSTGUI. It is subject to the license terms
// in the LICENSE file found in the top-level directory of this
// distribution and at http://github.com/steinbergmedia/vstgui/LICENSE
#include "../../../lib/algorithm.h"
#include "../unittests.h"
namespace VSTGUI {
//------------------------------------------------------------------------
TEST_CASE (Algorithm, Clamp)
{
EXPECT_EQ (clamp (2.8, 1.4, 1.8), 1.8);
EXPECT_EQ (clamp (1.2, 1.4, 1.8), 1.4);
}
//------------------------------------------------------------------------
TEST_CASE (Algorithm, ClampNorm)
{
EXPECT_EQ (clampNorm (1.8), 1.);
EXPECT_EQ (clampNorm (-0.1), 0.);
}
//------------------------------------------------------------------------
TEST_CASE (Algorithm, NormalizedToSteps)
{
EXPECT_EQ (normalizedToSteps (0., 1), 0);
EXPECT_EQ (normalizedToSteps (0.49, 1), 0);
EXPECT_EQ (normalizedToSteps (0.50, 1), 1);
EXPECT_EQ (normalizedToSteps (0.51, 1), 1);
EXPECT_EQ (normalizedToSteps (1., 1), 1);
EXPECT_EQ (normalizedToSteps (0., 3), 0);
EXPECT_EQ (normalizedToSteps (0.24, 3), 0);
EXPECT_EQ (normalizedToSteps (0.25, 3), 1);
EXPECT_EQ (normalizedToSteps (0.26, 3), 1);
EXPECT_EQ (normalizedToSteps (0.49, 3), 1);
EXPECT_EQ (normalizedToSteps (0.50, 3), 2);
EXPECT_EQ (normalizedToSteps (0.51, 3), 2);
EXPECT_EQ (normalizedToSteps (0.74, 3), 2);
EXPECT_EQ (normalizedToSteps (0.75, 3), 3);
EXPECT_EQ (normalizedToSteps (0.76, 3), 3);
EXPECT_EQ (normalizedToSteps (1., 3), 3);
EXPECT_EQ (normalizedToSteps (0., 1, 1), 1);
EXPECT_EQ (normalizedToSteps (0.5, 1, 1), 2);
EXPECT_EQ (normalizedToSteps (1., 1, 1), 2);
}
//------------------------------------------------------------------------
TEST_CASE (Agorithm, StepsToNormalized)
{
EXPECT_EQ (stepsToNormalized<double> (1, 1), 1.);
EXPECT_EQ (stepsToNormalized<double> (0, 1), 0.);
EXPECT_EQ (stepsToNormalized<double> (0, 4), 0.);
EXPECT_EQ (stepsToNormalized<double> (1, 4), 0.25);
EXPECT_EQ (stepsToNormalized<double> (2, 4), 0.50);
EXPECT_EQ (stepsToNormalized<double> (3, 4), 0.75);
EXPECT_EQ (stepsToNormalized<double> (4, 4), 1.);
EXPECT_EQ (stepsToNormalized<double> (2, 1, 1), 1.);
EXPECT_EQ (stepsToNormalized<double> (1, 1, 1), 0.);
}
} // VSTGUI
@@ -0,0 +1,247 @@
// This file is part of VSTGUI. It is subject to the license terms
// in the LICENSE file found in the top-level directory of this
// distribution and at http://github.com/steinbergmedia/vstgui/LICENSE
#include "../../../../lib/animation/animations.h"
#include "../../../../lib/controls/ccontrol.h"
#include "../../../../lib/cview.h"
#include "../../../../lib/cviewcontainer.h"
#include "../../unittests.h"
namespace VSTGUI {
using namespace Animation;
namespace {
//-----------------------------------------------------------------------------
class TestView : public CView
{
public:
TestView () : CView (CRect (0, 0, 0, 0)) {}
};
//-----------------------------------------------------------------------------
class TestControl : public CControl
{
public:
TestControl () : CControl (CRect (0, 0, 0, 0)) {}
void draw (CDrawContext* pContext) override {}
CLASS_METHODS (TestControl, CControl)
};
} // anonymous
TEST_CASE (AlphaValueAnimtionTest, Animation)
{
TestView view;
EXPECT (view.getAlphaValue () == 1.f);
AlphaValueAnimation a (0.f);
a.animationStart (&view, "");
a.animationTick (&view, "", 0.5f);
EXPECT (view.getAlphaValue () == 0.5f);
a.animationTick (&view, "", 1.f);
EXPECT (view.getAlphaValue () == 0.f);
a.animationFinished (&view, "", false);
EXPECT (view.getAlphaValue () == 0.f);
}
//-----------------------------------------------------------------------------
TEST_CASE (ViewSizeAnimationTest, Animation)
{
TestView view;
EXPECT (view.getViewSize () == CRect (0, 0, 0, 0));
ViewSizeAnimation a (CRect (10, 10, 100, 100));
a.animationStart (&view, "");
a.animationTick (&view, "", 0.5f);
EXPECT (view.getViewSize () == CRect (5, 5, 50, 50));
a.animationTick (&view, "", 1.f);
EXPECT (view.getViewSize () == CRect (10, 10, 100, 100));
a.animationFinished (&view, "", false);
EXPECT (view.getViewSize () == CRect (10, 10, 100, 100));
}
TEST_CASE (ViewSizeAnimationTest, UnfinishedAnimation)
{
TestView view;
ViewSizeAnimation a (CRect (10, 10, 100, 100));
a.animationStart (&view, "");
a.animationTick (&view, "", 0.5f);
EXPECT (view.getViewSize () == CRect (5, 5, 50, 50));
a.animationFinished (&view, "", false);
EXPECT (view.getViewSize () == CRect (10, 10, 100, 100));
}
//-----------------------------------------------------------------------------
TEST_CASE (ControlValueAnimationTest, Animation)
{
TestControl control;
EXPECT (control.getValue () == 0.f);
ControlValueAnimation a (1.f);
a.animationStart (&control, "");
EXPECT (control.getValue () == 0.f);
a.animationTick (&control, "", 0.3f);
EXPECT (control.getValue () == 0.3f);
a.animationTick (&control, "", 0.5f);
EXPECT (control.getValue () == 0.5f);
a.animationFinished (&control, "", false);
EXPECT (control.getValue () == 1.f);
}
//-----------------------------------------------------------------------------
TEST_CASE (ExchangeViewAnimationTest, AlphaValueFade)
{
auto parentContainer = owned (new CViewContainer (CRect (0, 0, 0, 0)));
auto container = new CViewContainer (CRect (0, 0, 0, 0));
container->attached (parentContainer);
auto oldView = new TestView ();
auto newView = new TestView ();
container->addView (oldView);
ExchangeViewAnimation a (oldView, newView, ExchangeViewAnimation::kAlphaValueFade);
a.animationStart (container, "");
EXPECT (oldView->getAlphaValue () == 1.f);
EXPECT (newView->getAlphaValue () == 0.f);
a.animationTick (container, "", 0.5f);
EXPECT (oldView->getAlphaValue () == 0.5f);
EXPECT (newView->getAlphaValue () == 0.5f);
a.animationTick (container, "", 1.f);
a.animationFinished (container, "", false);
EXPECT (oldView->isAttached () == false);
EXPECT (newView->getAlphaValue () == 1.f);
container->removed (parentContainer);
}
TEST_CASE (ExchangeViewAnimationTest, PushInFromLeft)
{
CRect r (0, 0, 100, 100);
auto parentContainer = owned (new CViewContainer (r));
auto container = new CViewContainer (r);
container->attached (parentContainer);
auto oldView = new CView (r);
auto newView = new CView (r);
container->addView (oldView);
ExchangeViewAnimation a (oldView, newView, ExchangeViewAnimation::kPushInFromLeft);
a.animationStart (container, "");
EXPECT (oldView->getViewSize () == r);
EXPECT (newView->getViewSize () == CRect (-100, 0, 0, 100));
a.animationTick (container, "", 0.5f);
EXPECT (newView->getViewSize () == CRect (-50, 0, 50, 100));
a.animationTick (container, "", 1.f);
a.animationFinished (container, "", false);
EXPECT (oldView->isAttached () == false);
EXPECT (newView->getViewSize () == r);
container->removed (parentContainer);
}
TEST_CASE (ExchangeViewAnimationTest, PushInFromRight)
{
CRect r (0, 0, 100, 100);
auto parentContainer = owned (new CViewContainer (r));
auto container = new CViewContainer (r);
container->attached (parentContainer);
auto oldView = new CView (r);
auto newView = new CView (r);
container->addView (oldView);
ExchangeViewAnimation a (oldView, newView, ExchangeViewAnimation::kPushInFromRight);
a.animationStart (container, "");
EXPECT (oldView->getViewSize () == r);
EXPECT (newView->getViewSize () == CRect (100, 0, 200, 100));
a.animationTick (container, "", 0.5f);
EXPECT (newView->getViewSize () == CRect (50, 0, 150, 100));
a.animationTick (container, "", 1.f);
a.animationFinished (container, "", false);
EXPECT (oldView->isAttached () == false);
EXPECT (newView->getViewSize () == r);
container->removed (parentContainer);
}
TEST_CASE (ExchangeViewAnimationTest, PushInFromTop)
{
CRect r (0, 0, 100, 100);
auto parentContainer = owned (new CViewContainer (r));
auto container = new CViewContainer (r);
container->attached (parentContainer);
auto oldView = new CView (r);
auto newView = new CView (r);
container->addView (oldView);
ExchangeViewAnimation a (oldView, newView, ExchangeViewAnimation::kPushInFromTop);
a.animationStart (container, "");
EXPECT (oldView->getViewSize () == r);
EXPECT (newView->getViewSize () == CRect (0, -100, 100, 0));
a.animationTick (container, "", 0.5f);
EXPECT (newView->getViewSize () == CRect (0, -50, 100, 50));
a.animationTick (container, "", 1.f);
a.animationFinished (container, "", false);
EXPECT (oldView->isAttached () == false);
EXPECT (newView->getViewSize () == r);
container->removed (parentContainer);
}
TEST_CASE (ExchangeViewAnimationTest, PushInFromBottom)
{
CRect r (0, 0, 100, 100);
auto parentContainer = owned (new CViewContainer (r));
auto container = new CViewContainer (r);
container->attached (parentContainer);
auto oldView = new CView (r);
auto newView = new CView (r);
container->addView (oldView);
ExchangeViewAnimation a (oldView, newView, ExchangeViewAnimation::kPushInFromBottom);
a.animationStart (container, "");
EXPECT (oldView->getViewSize () == r);
EXPECT (newView->getViewSize () == CRect (0, 100, 100, 200));
a.animationTick (container, "", 0.5f);
EXPECT (newView->getViewSize () == CRect (0, 50, 100, 150));
a.animationTick (container, "", 1.f);
a.animationFinished (container, "", false);
EXPECT (oldView->isAttached () == false);
EXPECT (newView->getViewSize () == r);
container->removed (parentContainer);
}
TEST_CASE (ExchangeViewAnimationTest, PushInOutFromLeft)
{
CRect r (0, 0, 100, 100);
auto parentContainer = owned (new CViewContainer (r));
auto container = new CViewContainer (r);
container->attached (parentContainer);
auto oldView = new CView (r);
auto newView = new CView (r);
container->addView (oldView);
ExchangeViewAnimation a (oldView, newView, ExchangeViewAnimation::kPushInOutFromLeft);
a.animationStart (container, "");
EXPECT (oldView->getViewSize () == r);
EXPECT (newView->getViewSize () == CRect (-100, 0, 0, 100));
a.animationTick (container, "", 0.5f);
EXPECT (oldView->getViewSize () == CRect (50, 0, 150, 100));
EXPECT (newView->getViewSize () == CRect (-50, 0, 50, 100));
a.animationTick (container, "", 1.f);
a.animationFinished (container, "", false);
EXPECT (oldView->isAttached () == false);
EXPECT (newView->getViewSize () == r);
container->removed (parentContainer);
}
TEST_CASE (ExchangeViewAnimationTest, PushInOutFromRight)
{
CRect r (0, 0, 100, 100);
auto parentContainer = owned (new CViewContainer (r));
auto container = new CViewContainer (r);
container->attached (parentContainer);
auto oldView = new CView (r);
auto newView = new CView (r);
container->addView (oldView);
ExchangeViewAnimation a (oldView, newView, ExchangeViewAnimation::kPushInOutFromRight);
a.animationStart (container, "");
EXPECT (oldView->getViewSize () == r);
EXPECT (newView->getViewSize () == CRect (100, 0, 200, 100));
a.animationTick (container, "", 0.5f);
EXPECT (oldView->getViewSize () == CRect (-50, 0, 50, 100));
EXPECT (newView->getViewSize () == CRect (50, 0, 150, 100));
a.animationFinished (container, "", true);
EXPECT (oldView->isAttached () == false);
EXPECT (newView->getViewSize () == r);
container->removed (parentContainer);
}
} // VSTGUI
@@ -0,0 +1,120 @@
// This file is part of VSTGUI. It is subject to the license terms
// in the LICENSE file found in the top-level directory of this
// distribution and at http://github.com/steinbergmedia/vstgui/LICENSE
#include "../../../../lib/animation/animations.h"
#include "../../../../lib/animation/animator.h"
#include "../../../../lib/animation/timingfunctions.h"
#include "../../../../lib/cview.h"
#include "../../unittests.h"
#if MAC
#include <CoreFoundation/CoreFoundation.h>
namespace VSTGUI {
using namespace Animation;
namespace {
struct RemoveAnimationInCallback : public IAnimationTarget
{
RemoveAnimationInCallback (Animator* animator) : animator (animator) {}
Animator* animator;
void animationStart (CView* view, IdStringPtr name) override {}
void animationTick (CView* view, IdStringPtr name, float pos) override
{
animator->removeAnimations (view);
}
void animationFinished (CView* view, IdStringPtr name, bool wasCanceled) override {}
};
} // anonymous
//-----------------------------------------------------------------------------
TEST_CASE (AnimatorTest, AddAnimation)
{
auto a = owned (new Animator ());
auto view = owned (new CView (CRect (0, 0, 0, 0)));
a->addAnimation (view, "Test", new AlphaValueAnimation (0.f), new LinearTimingFunction (100),
[] (CView*, const IdStringPtr, IAnimationTarget*) {
CFRunLoopStop (CFRunLoopGetCurrent ());
});
CFRunLoopRun ();
EXPECT (view->getAlphaValue () == 0.f);
}
TEST_CASE (AnimatorTest, CancelAnimation)
{
auto a = owned (new Animator ());
auto view = owned (new CView (CRect (0, 0, 0, 0)));
a->addAnimation (view, "Test", new AlphaValueAnimation (0.f), new LinearTimingFunction (2000));
CFRunLoopRunInMode (kCFRunLoopDefaultMode, 0.2, false);
a->removeAnimation (view, "Test");
EXPECT (view->getAlphaValue () != 0.f);
}
TEST_CASE (AnimatorTest, CancelAnimationWithCallback)
{
auto a = owned (new Animator ());
auto view = owned (new CView (CRect (0, 0, 0, 0)));
bool cancelDoneFunctionCalled = false;
auto doneFunc = [&] (auto, auto, auto) { cancelDoneFunctionCalled = true; };
a->addAnimation (view, "Test", new AlphaValueAnimation (0.f), new LinearTimingFunction (2000),
doneFunc, false);
CFRunLoopRunInMode (kCFRunLoopDefaultMode, 0.2, false);
a->removeAnimation (view, "Test");
EXPECT_FALSE (cancelDoneFunctionCalled);
EXPECT (view->getAlphaValue () != 0.f);
a->addAnimation (view, "Test", new AlphaValueAnimation (0.f), new LinearTimingFunction (2000),
doneFunc, true);
CFRunLoopRunInMode (kCFRunLoopDefaultMode, 0.2, false);
a->removeAnimation (view, "Test");
EXPECT_TRUE (cancelDoneFunctionCalled);
}
TEST_CASE (AnimatorTest, RemoveAnimationInCallback)
{
auto a = owned (new Animator ());
auto view = owned (new CView (CRect (0, 0, 0, 0)));
a->addAnimation (view, "Test", new RemoveAnimationInCallback (a),
new LinearTimingFunction (100),
[] (CView*, const IdStringPtr, IAnimationTarget*) {
CFRunLoopStop (CFRunLoopGetCurrent ());
});
CFRunLoopRun ();
}
#if VSTGUI_ENABLE_DEPRECATED_METHODS
#include "../../../../lib/private/disabledeprecatedmessage.h"
struct MessageReceiver : public CBaseObject
{
CMessageResult notify (CBaseObject* sender, IdStringPtr message) override
{
messageReceived = true;
CFRunLoopStop (CFRunLoopGetCurrent ());
return kMessageNotified;
}
bool messageReceived {false};
};
TEST_CASE (AnimatorTest, AnimationMessage)
{
auto a = owned (new Animator ());
auto view = owned (new CView (CRect (0, 0, 0, 0)));
MessageReceiver recevier;
a->addAnimation (view, "Test", new AlphaValueAnimation (0.f), new LinearTimingFunction (100),
&recevier);
CFRunLoopRun ();
EXPECT (recevier.messageReceived == true)
}
#include "../../../../lib/private/enabledeprecatedmessage.h"
#endif
} // VSTGUI
#endif // MAC
@@ -0,0 +1,98 @@
// This file is part of VSTGUI. It is subject to the license terms
// in the LICENSE file found in the top-level directory of this
// distribution and at http://github.com/steinbergmedia/vstgui/LICENSE
#include "../../../../lib/animation/timingfunctions.h"
#include "../../../../lib/controls/ccontrol.h"
#include "../../../../lib/cview.h"
#include "../../../../lib/cviewcontainer.h"
#include "../../unittests.h"
namespace VSTGUI {
using namespace Animation;
TEST_CASE (TimingFunctionTest, LinearTimingFunction)
{
LinearTimingFunction f (100);
ITimingFunction& tf = dynamic_cast<ITimingFunction&> (f);
EXPECT (tf.getPosition (0) == 0.f);
EXPECT (tf.getPosition (50) == 0.5f);
EXPECT (tf.getPosition (100) == 1.f);
EXPECT (tf.getPosition (150) == 1.f);
}
TEST_CASE (TimingFunctionTest, PowerTwoTimingFunction)
{
PowerTimingFunction f (100, 2);
ITimingFunction& tf = dynamic_cast<ITimingFunction&> (f);
EXPECT (tf.getPosition (0) == 0.f);
EXPECT (tf.getPosition (50) == 0.25f);
EXPECT (tf.getPosition (86) == 0.7396f);
EXPECT (tf.getPosition (100) == 1.f);
EXPECT (tf.getPosition (150) == 1.f);
}
TEST_CASE (TimingFunctionTest, PowerFourTimingFunction)
{
PowerTimingFunction f (100, 4);
ITimingFunction& tf = dynamic_cast<ITimingFunction&> (f);
EXPECT (tf.getPosition (0) == 0.f);
EXPECT (tf.getPosition (50) == 0.0625f);
EXPECT (tf.getPosition (100) == 1.f);
EXPECT (tf.getPosition (150) == 1.f);
}
TEST_CASE (TimingFunctionTest, InterpolationTimingFunction)
{
InterpolationTimingFunction f (100);
f.addPoint (0.5, 0.4f);
ITimingFunction& tf = dynamic_cast<ITimingFunction&> (f);
EXPECT (tf.getPosition (0) == 0.f);
EXPECT (tf.getPosition (25) == 0.2f);
EXPECT (tf.getPosition (50) == 0.4f);
EXPECT (tf.getPosition (75) == 0.7f);
EXPECT (tf.getPosition (100) == 1.f);
EXPECT (tf.getPosition (150) == 1.f);
}
TEST_CASE (TimingFunctionTest, RepeatTimingFunction)
{
auto lf = new LinearTimingFunction (100);
RepeatTimingFunction f (lf, 2, false);
ITimingFunction& tf = dynamic_cast<ITimingFunction&> (f);
EXPECT (tf.getPosition (0) == 0.f);
EXPECT (tf.getPosition (50) == 0.5f);
EXPECT (tf.getPosition (100) == 1.f);
EXPECT (tf.isDone (100) == false);
EXPECT (tf.getPosition (110) == 0.1f);
EXPECT (tf.getPosition (150) == 0.5f);
EXPECT (tf.getPosition (200) == 1.0f);
EXPECT (tf.isDone (200) == true);
}
TEST_CASE (TimingFunctionTest, RepeatTimingFunctionReverse)
{
auto lf = new LinearTimingFunction (100);
RepeatTimingFunction f (lf, 2, true);
ITimingFunction& tf = dynamic_cast<ITimingFunction&> (f);
EXPECT (tf.getPosition (0) == 0.f);
EXPECT (tf.getPosition (50) == 0.5f);
EXPECT (tf.getPosition (100) == 1.f);
EXPECT (tf.isDone (100) == false);
EXPECT (tf.getPosition (110) == 0.9f);
EXPECT (tf.getPosition (150) == 0.5f);
EXPECT (tf.getPosition (200) == 0.f);
EXPECT (tf.isDone (200) == true);
}
TEST_CASE (TimingFunctionTest, CubicBezierTimingFunction)
{
CubicBezierTimingFunction f (100, CPoint (0.42, 0.), CPoint (0.58, 1.));
EXPECT (f.getPosition (0) == 0.f);
EXPECT (f.getPosition (25) < 0.25f);
EXPECT (f.getPosition (50) == 0.5f);
EXPECT (f.getPosition (75) > 0.75f);
EXPECT (f.getPosition (100) == 1.0f);
}
} // VSTGUI
@@ -0,0 +1,201 @@
// This file is part of VSTGUI. It is subject to the license terms
// in the LICENSE file found in the top-level directory of this
// distribution and at http://github.com/steinbergmedia/vstgui/LICENSE
#include "../../../lib/cbitmap.h"
#include "../../../lib/ccolor.h"
#include "../../../lib/platform/iplatformbitmap.h"
#include "../../../lib/platform/platformfactory.h"
#include "../unittests.h"
namespace VSTGUI {
//------------------------------------------------------------------------
TEST_CASE (CBitmap, ScaleFactor)
{
CPoint p (10, 10);
auto b1 = getPlatformFactory ().createBitmap (p);
CBitmap bitmap (b1);
p (20, 20);
auto b2 = getPlatformFactory ().createBitmap (p);
b2->setScaleFactor (2.);
EXPECT_TRUE (bitmap.addBitmap (b2));
p (21, 21);
auto b3 = getPlatformFactory ().createBitmap (p);
EXPECT_EXCEPTION (bitmap.addBitmap (b3), "wrong bitmap size");
EXPECT_EQ (bitmap.getBestPlatformBitmapForScaleFactor (0.5), b1);
EXPECT_EQ (bitmap.getBestPlatformBitmapForScaleFactor (1.0), b1);
EXPECT_EQ (bitmap.getBestPlatformBitmapForScaleFactor (1.4), b1);
EXPECT_EQ (bitmap.getBestPlatformBitmapForScaleFactor (1.5), b2);
EXPECT_EQ (bitmap.getBestPlatformBitmapForScaleFactor (1.6), b2);
EXPECT_EQ (bitmap.getBestPlatformBitmapForScaleFactor (2.6), b2);
}
//------------------------------------------------------------------------
TEST_CASE (CBitmap, PixelAccess)
{
CBitmap bitmap (10, 10);
EXPECT_EQ (bitmap.getWidth (), 10);
EXPECT_EQ (bitmap.getHeight (), 10);
auto accessor = owned (CBitmapPixelAccess::create (&bitmap));
EXPECT (accessor);
uint32_t x = 0;
uint32_t y = 0;
CColor color;
do
{
accessor->getColor (color);
EXPECT_EQ (color, CColor (0, 0, 0, 0));
accessor->setColor (kRedCColor);
accessor->getColor (color);
EXPECT_EQ (color, kRedCColor);
accessor->setColor (kGreenCColor);
accessor->getColor (color);
EXPECT_EQ (color, kGreenCColor);
accessor->setColor (kBlueCColor);
accessor->getColor (color);
EXPECT_EQ (color, kBlueCColor);
EXPECT_EQ (accessor->getX (), x);
EXPECT_EQ (accessor->getY (), y);
if (++x == accessor->getBitmapWidth ())
{
++y;
x = 0;
}
} while (++(*accessor));
}
//------------------------------------------------------------------------
TEST_CASE (CBitmap, PixelAccess2)
{
CBitmap bitmap (10, 10);
CColor color (255, 1, 2, 150);
if (auto accessor = owned (CBitmapPixelAccess::create (&bitmap)))
{
do
{
accessor->setColor (color);
} while (++(*accessor));
}
if (auto accessor = owned (CBitmapPixelAccess::create (&bitmap)))
{
do
{
CColor c;
accessor->getColor (c);
EXPECT_EQ (c, color);
} while (++(*accessor));
}
}
//------------------------------------------------------------------------
//------------------------------------------------------------------------
//------------------------------------------------------------------------
TEST_CASE (CMultiFrameBitmap, NotInitialized)
{
CMultiFrameBitmap bitmap (100, 100);
auto fr = bitmap.calcFrameRect (0);
EXPECT_EQ (fr, CRect (0, 0, 100, 100));
}
//------------------------------------------------------------------------
TEST_CASE (CMultiFrameBitmap, CalcFrameRect)
{
CMultiFrameBitmap bitmap (100, 100);
EXPECT_TRUE (bitmap.setMultiFrameDesc ({{50, 50}, 4, 2}));
EXPECT_EQ (bitmap.getFrameSize (), CPoint (50., 50.));
EXPECT_EQ (bitmap.getNumFrames (), 4);
EXPECT_EQ (bitmap.getNumFramesPerRow (), 2);
EXPECT_EQ (bitmap.calcFrameRect (0), CRect (0, 0, 50, 50));
EXPECT_EQ (bitmap.calcFrameRect (1), CRect (50, 0, 100, 50));
EXPECT_EQ (bitmap.calcFrameRect (2), CRect (0, 50, 50, 100));
EXPECT_EQ (bitmap.calcFrameRect (3), CRect (50, 50, 100, 100));
EXPECT_EQ (bitmap.calcFrameRect (4), CRect (50, 50, 100, 100));
}
//------------------------------------------------------------------------
TEST_CASE (CMultiFrameBitmap, InvalidFrameDesc)
{
CMultiFrameBitmap bitmap (100, 100);
EXPECT_FALSE (bitmap.setMultiFrameDesc ({{50, 50}, 4, 1}));
EXPECT_FALSE (bitmap.setMultiFrameDesc ({{50, 50}, 4, 4}));
}
//------------------------------------------------------------------------
//------------------------------------------------------------------------
//------------------------------------------------------------------------
struct MultiFrameBitmapViewTest : MultiFrameBitmapView<MultiFrameBitmapViewTest>
{
void invalid () {}
};
//------------------------------------------------------------------------
TEST_CASE (MultiFrameBitmapViewTest, Default)
{
MultiFrameBitmapViewTest testView;
CMultiFrameBitmap bitmap (100, 100);
EXPECT_TRUE (bitmap.setMultiFrameDesc ({{50, 50}, 4, 2}));
EXPECT_EQ (testView.getMultiFrameBitmapIndex (bitmap, 0.f), 0);
EXPECT_EQ (testView.getMultiFrameBitmapIndex (bitmap, 0.33f), 1);
EXPECT_EQ (testView.getMultiFrameBitmapIndex (bitmap, 0.66f), 2);
EXPECT_EQ (testView.getMultiFrameBitmapIndex (bitmap, 1.f), 3);
EXPECT_EQ (testView.getNormValueFromMultiFrameBitmapIndex (bitmap, 0), 0.f);
EXPECT_EQ (
static_cast<int> (testView.getNormValueFromMultiFrameBitmapIndex (bitmap, 1) * 100.f), 33);
EXPECT_EQ (
static_cast<int> (testView.getNormValueFromMultiFrameBitmapIndex (bitmap, 2) * 100.f), 66);
EXPECT_EQ (testView.getNormValueFromMultiFrameBitmapIndex (bitmap, 3), 1.f);
}
//------------------------------------------------------------------------
TEST_CASE (MultiFrameBitmapViewTest, Range)
{
MultiFrameBitmapViewTest testView;
CMultiFrameBitmap bitmap (100, 100);
EXPECT_TRUE (bitmap.setMultiFrameDesc ({{50, 50}, 4, 2}));
testView.setMultiFrameBitmapRange (0, 1);
auto range = testView.getMultiFrameBitmapRange ();
EXPECT_EQ (range.first, 0);
EXPECT_EQ (range.second, 1);
EXPECT_EQ (testView.getMultiFrameBitmapIndex (bitmap, 0.f), 0);
EXPECT_EQ (testView.getMultiFrameBitmapIndex (bitmap, 1.f), 1);
EXPECT_EQ (testView.getNormValueFromMultiFrameBitmapIndex (bitmap, 0), 0.f);
EXPECT_EQ (testView.getNormValueFromMultiFrameBitmapIndex (bitmap, 1), 1.f);
testView.setMultiFrameBitmapRange (2, -1);
EXPECT_EQ (testView.getMultiFrameBitmapIndex (bitmap, 0.f), 2);
EXPECT_EQ (testView.getMultiFrameBitmapIndex (bitmap, 1.f), 3);
EXPECT_EQ (testView.getNormValueFromMultiFrameBitmapIndex (bitmap, 2), 0.f);
EXPECT_EQ (testView.getNormValueFromMultiFrameBitmapIndex (bitmap, 3), 1.f);
testView.setMultiFrameBitmapRange (2, 3);
EXPECT_EQ (testView.getMultiFrameBitmapIndex (bitmap, 0.f), 2);
EXPECT_EQ (testView.getMultiFrameBitmapIndex (bitmap, 1.f), 3);
EXPECT_EQ (testView.getNormValueFromMultiFrameBitmapIndex (bitmap, 2), 0.f);
EXPECT_EQ (testView.getNormValueFromMultiFrameBitmapIndex (bitmap, 3), 1.f);
}
//------------------------------------------------------------------------
TEST_CASE (MultiFrameBitmapViewTest, Inverse)
{
MultiFrameBitmapViewTest testView;
CMultiFrameBitmap bitmap (100, 100);
EXPECT_TRUE (bitmap.setMultiFrameDesc ({{50, 50}, 4, 2}));
testView.setMultiFrameBitmapRange (0, 1);
EXPECT_EQ (testView.getInverseIndex (bitmap, 0), 1);
EXPECT_EQ (testView.getInverseIndex (bitmap, 1), 0);
testView.setMultiFrameBitmapRange (2, -1);
EXPECT_EQ (testView.getInverseIndex (bitmap, 2), 3);
EXPECT_EQ (testView.getInverseIndex (bitmap, 3), 2);
testView.setMultiFrameBitmapRange (2, 3);
EXPECT_EQ (testView.getInverseIndex (bitmap, 2), 3);
EXPECT_EQ (testView.getInverseIndex (bitmap, 3), 2);
}
//------------------------------------------------------------------------
} // VSTGUI
@@ -0,0 +1,31 @@
// This file is part of VSTGUI. It is subject to the license terms
// in the LICENSE file found in the top-level directory of this
// distribution and at http://github.com/steinbergmedia/vstgui/LICENSE
#include "../unittests.h"
#include "../../../lib/cbuttonstate.h"
namespace VSTGUI {
TEST_CASE (CButtonStateTests, Test)
{
CButtonState s;
EXPECT_EQ (s.getButtonState (), 0);
EXPECT_EQ (s.getModifierState (), 0);
s = kLButton;
EXPECT_TRUE (s.isLeftButton ());
s |= kShift;
EXPECT_TRUE (s.isLeftButton ());
EXPECT_EQ (s.getModifierState (), kShift);
s = kRButton;
EXPECT_TRUE (s.isRightButton ());
s |= kDoubleClick;
EXPECT_TRUE (s.isDoubleClick ());
EXPECT (s & CButtonState (kDoubleClick));
CButtonState s2 (s);
EXPECT_EQ (s, s2);
s2 = ~s;
EXPECT_NE (s, s2);
}
} // VSTGUI
@@ -0,0 +1,36 @@
// This file is part of VSTGUI. It is subject to the license terms
// in the LICENSE file found in the top-level directory of this
// distribution and at http://github.com/steinbergmedia/vstgui/LICENSE
#include "../../../lib/cclipboard.h"
#include "../unittests.h"
namespace VSTGUI {
#if !WINDOWS
// the OLE clipboard functionality returns Ole not initialized even tho we call OleInitialize()
// so we disable the test for now on Windows
TEST_CASE (CClipboardTest, String)
{
EXPECT_TRUE (CClipboard::setString ("This is a test string"));
auto cbStr = CClipboard::getString ();
EXPECT_TRUE (cbStr);
EXPECT (*cbStr == "This is a test string");
}
TEST_CASE (CClipboardTest, FilePath)
{
#if WINDOWS
constexpr auto path = "C:\\Windows\\test.txt";
#else
constexpr auto path = "/tmp/test.txt";
#endif
EXPECT_TRUE (CClipboard::setFilePath (path));
auto cbStr = CClipboard::getFilePath ();
EXPECT_TRUE (cbStr);
EXPECT (*cbStr == path);
}
#endif
} // VSTGUI
@@ -0,0 +1,181 @@
// This file is part of VSTGUI. It is subject to the license terms
// in the LICENSE file found in the top-level directory of this
// distribution and at http://github.com/steinbergmedia/vstgui/LICENSE
#include "../../../lib/ccolor.h"
#include "../../../lib/cstring.h"
#include "../unittests.h"
namespace VSTGUI {
using namespace std::string_view_literals;
TEST_CASE (CColorTest, MakeCColor)
{
CColor c = MakeCColor (10, 20, 30, 40);
EXPECT_EQ (c.red, 10);
EXPECT_EQ (c.green, 20);
EXPECT_EQ (c.blue, 30);
EXPECT_EQ (c.alpha, 40);
}
TEST_CASE (CColorTest, Luma)
{
CColor c (30, 50, 80, 255);
EXPECT_EQ (c.getLuma (), 47);
}
TEST_CASE (CColorTest, Lightness)
{
CColor c (80, 30, 50, 255);
EXPECT_EQ (c.getLightness (), 55);
}
TEST_CASE (CColorTest, OperatorEqual)
{
CColor c (30, 40, 50, 60);
EXPECT_TRUE (c == CColor (30, 40, 50, 60));
}
TEST_CASE (CColorTest, OperatorNotEqual)
{
CColor c (30, 40, 50, 60);
EXPECT (c != CColor (50, 40, 50, 60));
EXPECT (c != CColor (30, 50, 50, 60));
EXPECT (c != CColor (30, 40, 60, 60));
EXPECT (c != CColor (30, 40, 50, 70));
}
TEST_CASE (CColorTest, CopyConstructor)
{
CColor c (60, 50, 40, 100);
CColor c2 (c);
EXPECT_EQ (c, c2);
}
TEST_CASE (CColorTest, AssignOperator)
{
CColor c;
c (20, 30, 40, 50);
EXPECT_EQ (c, CColor (20, 30, 40, 50));
}
#if DEBUG
static constexpr auto advanceCount = 16;
#else
static constexpr auto advanceCount = 1;
#endif
TEST_CASE (CColorTest, HSV)
{
double hue;
double saturation;
double value;
for (uint16_t red = 0; red <= 255; red += advanceCount)
{
for (uint16_t green = 0; green <= 255; green += advanceCount)
{
for (uint16_t blue = 0; blue <= 255; blue += advanceCount)
{
CColor c (static_cast<uint8_t> (red), static_cast<uint8_t> (green),
static_cast<uint8_t> (blue));
c.toHSV (hue, saturation, value);
c.fromHSV (hue, saturation, value);
EXPECT_EQ (c.red, red)
EXPECT_EQ (c.green, green)
EXPECT_EQ (c.blue, blue)
EXPECT_EQ (c.alpha, 255);
}
}
}
}
TEST_CASE (CColorTest, HSL)
{
double hue;
double saturation;
double lightness;
for (uint16_t red = 0; red <= 255; red += advanceCount)
{
for (uint16_t green = 0; green <= 255; green += advanceCount)
{
for (uint16_t blue = 0; blue <= 255; blue += advanceCount)
{
CColor c (static_cast<uint8_t> (red), static_cast<uint8_t> (green),
static_cast<uint8_t> (blue));
c.toHSL (hue, saturation, lightness);
c.fromHSL (hue, saturation, lightness);
EXPECT_EQ (c.red, red)
EXPECT_EQ (c.green, green)
EXPECT_EQ (c.blue, blue)
EXPECT_EQ (c.alpha, 255);
}
}
}
}
TEST_CASE (CColorTest, IsColorRepresentation)
{
EXPECT_TRUE (CColor::isColorRepresentation ("#FF00FFFF"sv));
// EXPECT_FALSE (CColor::isColorRepresentation ("#ABCDEFGH"));
EXPECT_FALSE (CColor::isColorRepresentation ("star"sv));
}
TEST_CASE (CColorTest, ToString)
{
auto str = CColor (255, 255, 255).toString ();
EXPECT_EQ (str, "#ffffffff")
}
TEST_CASE (CColorTest, FromString)
{
CColor c;
EXPECT_TRUE (c.fromString ("#FFFFFFFF"sv));
EXPECT_EQ (c, CColor (255, 255, 255));
c.fromString ("#FF0000FF"sv);
EXPECT_EQ (c, CColor (255, 0, 0));
c.fromString ("#00FF00FF"sv);
EXPECT_EQ (c, CColor (0, 255, 0));
c.fromString ("#0000FFFF"sv);
EXPECT_EQ (c, CColor (0, 0, 255));
c.fromString ("#0000FF00"sv);
EXPECT_EQ (c, CColor (0, 0, 255, 0));
}
TEST_CASE (CColorTest, SetNormalized)
{
CColor c (0, 0, 0, 0);
c.setNormRed (1.);
c.setNormGreen (1.);
c.setNormBlue (1.);
c.setNormAlpha (1.);
EXPECT_EQ (c.red, 255);
EXPECT_EQ (c.green, 255);
EXPECT_EQ (c.blue, 255);
EXPECT_EQ (c.alpha, 255);
c.setNormRed (0.5);
c.setNormGreen (0.5);
c.setNormBlue (0.5);
c.setNormAlpha (0.5);
EXPECT_EQ (c.red, 128);
EXPECT_EQ (c.green, 128);
EXPECT_EQ (c.blue, 128);
EXPECT_EQ (c.alpha, 128);
}
TEST_CASE (CColorTest, GetNormalized)
{
CColor r (kRedCColor);
EXPECT_EQ (r.normRed<double> (), 1.);
EXPECT_EQ (r.normGreen<double> (), 0.);
EXPECT_EQ (r.normBlue<double> (), 0.);
EXPECT_EQ (r.normAlpha<double> (), 1.);
r.green = 127;
EXPECT_EQ (r.normGreen<double> (), 127. / 255.);
r.blue = 33;
EXPECT_EQ (r.normBlue<double> (), 33. / 255.);
r.alpha = 250;
EXPECT_EQ (r.normAlpha<double> (), 250. / 255.);
}
} // VSTGUI
@@ -0,0 +1,46 @@
// This file is part of VSTGUI. It is subject to the license terms
// in the LICENSE file found in the top-level directory of this
// distribution and at http://github.com/steinbergmedia/vstgui/LICENSE
#include "../unittests.h"
#include "../../../lib/cfont.h"
namespace VSTGUI {
TESTCASE(CFontTests,
TEST(attributes,
CFontDesc f;
EXPECT(f.getName ().empty ());
EXPECT(f.getSize () == 0.);
EXPECT(f.getStyle () == kNormalFace);
f.setName ("Test");
EXPECT(strcmp (f.getName (), "Test") == 0);
f.setSize (20.2);
EXPECT(f.getSize () == 20.2);
f.setStyle (kBoldFace|kItalicFace);
EXPECT(f.getStyle () == (kBoldFace|kItalicFace));
CFontDesc::cleanup ();
);
TEST(copyConstructor,
CFontDesc f (*kSystemFont);
EXPECT(f == *kSystemFont);
);
TEST(notEqualOperator,
CFontDesc f (*kSystemFont);
EXPECT(f == *kSystemFont);
f.setSize (f.getSize ()+1);
EXPECT(f != *kSystemFont);
f = *kSystemFont;
f.setStyle (kBoldFace);
EXPECT(f != *kSystemFont);
f = *kSystemFont;
f.setName ("Bla");
EXPECT(f != *kSystemFont);
);
);
} // VSTGUI
@@ -0,0 +1,736 @@
// This file is part of VSTGUI. It is subject to the license terms
// in the LICENSE file found in the top-level directory of this
// distribution and at http://github.com/steinbergmedia/vstgui/LICENSE
#include "../../../lib/ccolor.h"
#include "../../../lib/cframe.h"
#include "../../../lib/events.h"
#include "../unittests.h"
#include "eventhelpers.h"
#include "platform_helper.h"
#include <vector>
namespace VSTGUI {
namespace {
class MouseObserver : public IMouseObserver
{
public:
void reset ()
{
enteredViews.clear ();
exitedViews.clear ();
}
void onMouseEntered (CView* view, CFrame* frame) override { enteredViews.push_back (view); }
void onMouseExited (CView* view, CFrame* frame) override { exitedViews.push_back (view); }
void onMouseEvent (MouseEvent&, CFrame*) override {}
std::vector<CView*> enteredViews;
std::vector<CView*> exitedViews;
};
bool contains (const std::vector<CView*>& c, CView* view)
{
auto it = std::find (c.begin (), c.end (), view);
return it != c.end ();
}
class View : public CView
{
public:
View () : CView (CRect (0, 0, 10, 10)) {}
bool onMouseDownCalled {false};
bool onKeyDownCalled {false};
bool onKeyUpCalled {false};
CMouseEventResult onMouseDown (CPoint& p, const CButtonState& buttons) override
{
onMouseDownCalled = true;
return kMouseEventHandled;
}
#if VSTGUI_ENABLE_DEPRECATED_METHODS
int32_t onKeyDown (VstKeyCode& key) override
{
onKeyDownCalled = true;
return 1;
}
int32_t onKeyUp (VstKeyCode& key) override
{
onKeyUpCalled = true;
return 1;
}
#else
void onKeyboardEvent (KeyboardEvent& event) override
{
if (event.type == EventType::KeyDown)
{
onKeyDownCalled = true;
event.consumed = true;
}
else if (event.type == EventType::KeyUp)
{
onKeyUpCalled = true;
event.consumed = true;
}
}
#endif
};
class ContainerTestingKeyboardEvents : public CViewContainer
{
public:
bool onKeyDownCalled {false};
bool onKeyUpCalled {false};
ContainerTestingKeyboardEvents () : CViewContainer (CRect (0, 0, 20, 20)) {}
#if VSTGUI_ENABLE_DEPRECATED_METHODS
int32_t onKeyDown (VstKeyCode& key) override
{
if (onKeyDownCalled)
return -1;
onKeyDownCalled = true;
return 1;
}
int32_t onKeyUp (VstKeyCode& key) override
{
if (onKeyUpCalled)
return -1;
onKeyUpCalled = true;
return 1;
}
#else
void onKeyboardEvent (KeyboardEvent& event) override
{
if (event.type == EventType::KeyDown)
{
onKeyDownCalled = true;
event.consumed = true;
}
else if (event.type == EventType::KeyUp)
{
onKeyUpCalled = true;
event.consumed = true;
}
}
#endif
};
class KeyboardHook : public IKeyboardHook
{
public:
bool keyDownCalled {false};
bool keyUpCalled {false};
void onKeyboardEvent (KeyboardEvent& event, CFrame* frame) override
{
if (event.type == EventType::KeyDown)
{
keyDownCalled = true;
}
else if (event.type == EventType::KeyUp)
{
keyUpCalled = true;
}
event.consumed = true;
}
};
class CollectInvalidRectView : public CView
{
public:
CRect redrawRect;
uint32_t callCount {0};
CollectInvalidRectView () : CView (CRect (0, 0, 10, 10)) {}
CMouseEventResult onMouseDown (CPoint& p, const CButtonState& buttons) override
{
invalidRect (CRect (3, 3, 8, 8));
invalidRect (CRect (0, 0, 8, 8));
invalidRect (CRect (1, 1, 2, 2));
return kMouseEventHandled;
}
void drawRect (CDrawContext* c, const CRect& r) override
{
++callCount;
redrawRect = r;
CView::drawRect (c, r);
}
};
} // anonymouse
TEST_CASE (CFrameTest, SetZoom)
{
auto frame = owned (new CFrame (CRect (0, 0, 100, 100), nullptr));
EXPECT (frame->setZoom (0.) == false);
EXPECT (frame->setZoom (2.) == true);
EXPECT (frame->getViewSize () == CRect (0, 0, 200, 200));
EXPECT (frame->setZoom (0.5) == true);
EXPECT (frame->getViewSize () == CRect (0, 0, 50, 50));
EXPECT (frame->setZoom (1.0) == true);
EXPECT (frame->getViewSize () == CRect (0, 0, 100, 100));
}
TEST_CASE (CFrameTest, MouseEnterExit)
{
MouseObserver observer;
auto frame = owned (new CFrame (CRect (0, 0, 100, 100), nullptr));
frame->registerMouseObserver (&observer);
auto v1 = new View ();
auto v2 = new View ();
CRect r2 (10, 10, 20, 20);
v2->setViewSize (r2);
v2->setMouseableArea (r2);
frame->addView (v1);
frame->addView (v2);
frame->attached (frame);
dispatchMouseEvent<MouseMoveEvent> (frame, {30., 30.});
EXPECT (observer.enteredViews.size () == 0);
EXPECT (observer.exitedViews.size () == 0);
observer.reset ();
dispatchMouseEvent<MouseMoveEvent> (frame, {19., 19.});
EXPECT (observer.enteredViews.size () == 1);
EXPECT (contains (observer.enteredViews, v2));
EXPECT (observer.exitedViews.size () == 0);
observer.reset ();
dispatchMouseEvent<MouseMoveEvent> (frame, {9., 9.});
EXPECT (observer.enteredViews.size () == 1);
EXPECT (contains (observer.enteredViews, v1));
EXPECT (observer.exitedViews.size () == 1);
EXPECT (contains (observer.exitedViews, v2));
frame->unregisterMouseObserver (&observer);
}
TEST_CASE (CFrameTest, MouseEnterExitInContainer)
{
MouseObserver observer;
auto frame = owned (new CFrame (CRect (0, 0, 100, 100), nullptr));
frame->registerMouseObserver (&observer);
auto v1 = new View ();
auto v2 = new View ();
CRect r2 (10, 10, 20, 20);
v2->setViewSize (r2);
v2->setMouseableArea (r2);
auto container = new CViewContainer (CRect (0, 0, 80, 80));
auto container2 = new CViewContainer (CRect (0, 0, 50, 50));
frame->addView (container);
container->addView (container2);
container2->addView (v1);
container2->addView (v2);
frame->attached (frame);
dispatchMouseEvent<MouseMoveEvent> (frame, {90., 90.});
EXPECT (observer.enteredViews.size () == 0);
EXPECT (observer.exitedViews.size () == 0);
observer.reset ();
dispatchMouseEvent<MouseMoveEvent> (frame, {79., 79.});
EXPECT (observer.enteredViews.size () == 1);
EXPECT (contains (observer.enteredViews, container));
EXPECT (observer.exitedViews.size () == 0);
observer.reset ();
dispatchMouseEvent<MouseMoveEvent> (frame, {49., 49.});
EXPECT (observer.enteredViews.size () == 1);
EXPECT (contains (observer.enteredViews, container2));
EXPECT (observer.exitedViews.size () == 0);
observer.reset ();
dispatchMouseEvent<MouseMoveEvent> (frame, {19., 19.});
EXPECT (observer.enteredViews.size () == 1);
EXPECT (contains (observer.enteredViews, v2));
EXPECT (observer.exitedViews.size () == 0);
observer.reset ();
dispatchMouseEvent<MouseMoveEvent> (frame, {18., 18.});
EXPECT (observer.enteredViews.size () == 0);
EXPECT (observer.exitedViews.size () == 0);
observer.reset ();
dispatchMouseEvent<MouseMoveEvent> (frame, {9., 9.});
EXPECT (observer.enteredViews.size () == 1);
EXPECT (contains (observer.enteredViews, v1));
EXPECT (observer.exitedViews.size () == 1);
EXPECT (contains (observer.exitedViews, v2));
observer.reset ();
dispatchMouseEvent<MouseMoveEvent> (frame, {51., 51.});
EXPECT (observer.enteredViews.size () == 0);
EXPECT (observer.exitedViews.size () == 2);
EXPECT (contains (observer.exitedViews, v1));
EXPECT (contains (observer.exitedViews, container2));
observer.reset ();
dispatchMouseEvent<MouseMoveEvent> (frame, {81., 81.});
EXPECT (observer.enteredViews.size () == 0);
EXPECT (observer.exitedViews.size () == 1);
EXPECT (contains (observer.exitedViews, container));
observer.reset ();
dispatchMouseEvent<MouseMoveEvent> (frame, {9., 9.});
EXPECT (observer.enteredViews.size () == 3);
EXPECT (observer.exitedViews.size () == 0);
EXPECT (contains (observer.enteredViews, container));
EXPECT (contains (observer.enteredViews, container2));
EXPECT (contains (observer.enteredViews, v1));
observer.reset ();
dispatchMouseEvent<MouseMoveEvent> (frame, {81., 81.});
EXPECT (observer.enteredViews.size () == 0);
EXPECT (observer.exitedViews.size () == 3);
EXPECT (contains (observer.exitedViews, container));
EXPECT (contains (observer.exitedViews, container2));
EXPECT (contains (observer.exitedViews, v1));
observer.reset ();
dispatchMouseEvent<MouseMoveEvent> (frame, {79., 79.});
EXPECT (observer.enteredViews.size () == 1);
EXPECT (observer.exitedViews.size () == 0);
EXPECT (contains (observer.enteredViews, container));
observer.reset ();
dispatchMouseEvent<MouseMoveEvent> (frame, {8., 8.});
EXPECT (observer.enteredViews.size () == 2);
EXPECT (observer.exitedViews.size () == 0);
EXPECT (contains (observer.enteredViews, container2));
EXPECT (contains (observer.enteredViews, v1));
observer.reset ();
frame->unregisterMouseObserver (&observer);
}
TEST_CASE (CFrameTest, MouseMoveInContainer)
{
struct TestViewContainer : CViewContainer
{
using CViewContainer::CViewContainer;
CPoint mouseMoveEventPos {};
CMouseEventResult onMouseMoved (CPoint& where, const CButtonState& buttons) override
{
mouseMoveEventPos = where;
return CViewContainer::onMouseMoved (where, buttons);
}
};
struct TestView : CView
{
using CView::CView;
CPoint mouseMoveEventPos {};
CMouseEventResult onMouseMoved (CPoint& where, const CButtonState& buttons) override
{
mouseMoveEventPos = where;
return kMouseEventNotHandled;
}
};
auto frame = owned (new CFrame (CRect (0, 0, 100, 100), nullptr));
auto container = new TestViewContainer (CRect (10, 10, 80, 80));
frame->addView (container);
auto testView = new TestView ({10, 10, 60, 60});
container->addView (testView);
frame->attached (frame);
EXPECT_EQ (dispatchMouseEvent<MouseMoveEvent> (frame, {30., 30.}, MouseButton::None),
EventConsumeState::NotHandled);
EXPECT_EQ (container->mouseMoveEventPos, CPoint (30., 30.));
EXPECT_EQ (testView->mouseMoveEventPos, CPoint (20., 20.));
container->mouseMoveEventPos = {};
testView->mouseMoveEventPos = {};
CGraphicsTransform tm;
tm.scale (2., 2.);
container->setTransform (tm);
EXPECT_EQ (dispatchMouseEvent<MouseMoveEvent> (frame, {30., 30.}, MouseButton::None),
EventConsumeState::NotHandled);
EXPECT_EQ (container->mouseMoveEventPos, CPoint (30., 30.));
EXPECT_EQ (testView->mouseMoveEventPos, CPoint (10., 10.));
}
TEST_CASE (CFrameTest, RemoveViewWhileMouseInside)
{
MouseObserver observer;
auto frame = owned (new CFrame (CRect (0, 0, 100, 100), nullptr));
frame->registerMouseObserver (&observer);
auto v1 = new View ();
frame->addView (v1);
frame->attached (frame);
dispatchMouseEvent<MouseMoveEvent> (frame, {5., 5.});
EXPECT (contains (observer.enteredViews, v1));
observer.reset ();
frame->removeView (v1);
EXPECT (contains (observer.exitedViews, v1));
frame->unregisterMouseObserver (&observer);
}
TEST_CASE (CFrameTest, FocusSettings)
{
auto frame = owned (new CFrame (CRect (0, 0, 100, 100), nullptr));
EXPECT (frame->getFocusColor () == kRedCColor);
EXPECT (frame->getFocusWidth () == 2.);
EXPECT (frame->focusDrawingEnabled () == false);
frame->setFocusColor (kWhiteCColor);
EXPECT (frame->getFocusColor () == kWhiteCColor);
frame->setFocusColor (kGreenCColor);
EXPECT (frame->getFocusColor () == kGreenCColor);
frame->setFocusWidth (5.);
EXPECT (frame->getFocusWidth () == 5.);
frame->setFocusWidth (8.);
EXPECT (frame->getFocusWidth () == 8.);
frame->setFocusDrawingEnabled (true);
EXPECT (frame->focusDrawingEnabled () == true);
frame->setFocusDrawingEnabled (false);
EXPECT (frame->focusDrawingEnabled () == false);
}
TEST_CASE (CFrameTest, SetModalView)
{
auto frame = owned (new CFrame (CRect (0, 0, 100, 100), nullptr));
auto view = shared (new View ());
EXPECT (frame->getModalView () == nullptr);
auto session = frame->beginModalViewSession (view);
EXPECT (session);
EXPECT (frame->getModalView () == view);
auto container = shared (new CViewContainer (CRect (0, 0, 0, 0)));
auto session2 = frame->beginModalViewSession (container);
EXPECT (session2)
EXPECT (frame->getModalView () == container);
EXPECT (frame->endModalViewSession (*session) == false);
EXPECT (frame->endModalViewSession (*session2) == true);
EXPECT (frame->getModalView () == view);
EXPECT (frame->endModalViewSession (*session) == true);
EXPECT (frame->getModalView () == nullptr);
}
TEST_CASE (CFrameTest, KeyDownEvent)
{
auto frame = owned (new CFrame (CRect (0, 0, 100, 100), nullptr));
auto view = new View ();
frame->addView (view);
frame->attached (frame);
frame->onActivate (true);
KeyboardEvent event;
event.type = EventType::KeyDown;
frame->dispatchEvent (event);
EXPECT (event.consumed == false);
frame->setFocusView (view);
frame->dispatchEvent (event);
EXPECT (event.consumed == true);
event.consumed = false;
EXPECT (view->onKeyDownCalled);
frame->removeAll ();
auto container = new ContainerTestingKeyboardEvents ();
auto view2 = new CView (CRect (0, 0, 10, 10));
container->addView (view2);
frame->addView (container);
frame->setFocusView (view2);
frame->dispatchEvent (event);
EXPECT (event.consumed == true);
event.consumed = false;
EXPECT (container->onKeyDownCalled);
frame->setFocusView (nullptr);
view2->setWantsFocus (true);
EXPECT (frame->getFocusView () == nullptr);
event.virt = VirtualKey::Tab;
frame->dispatchEvent (event);
EXPECT (event.consumed == true);
event.consumed = false;
EXPECT (frame->getFocusView () == view2);
auto view3 = shared (new View ());
auto modalSession = frame->beginModalViewSession (view3);
frame->dispatchEvent (event);
EXPECT (event.consumed == true);
EXPECT (view3->onKeyDownCalled);
frame->endModalViewSession (*modalSession);
}
TEST_CASE (CFrameTest, KeyUpEvent)
{
auto frame = owned (new CFrame (CRect (0, 0, 100, 100), nullptr));
auto view = new View ();
frame->addView (view);
frame->attached (frame);
frame->onActivate (true);
KeyboardEvent event;
event.type = EventType::KeyUp;
frame->dispatchEvent (event);
EXPECT (event.consumed == false);
frame->setFocusView (view);
frame->dispatchEvent (event);
EXPECT (event.consumed == true);
event.consumed = false;
EXPECT (view->onKeyUpCalled);
frame->removeAll ();
auto container = new ContainerTestingKeyboardEvents ();
auto view2 = new CView (CRect (0, 0, 10, 10));
container->addView (view2);
frame->addView (container);
frame->setFocusView (view2);
frame->dispatchEvent (event);
EXPECT (event.consumed == true);
event.consumed = false;
EXPECT (container->onKeyUpCalled);
auto view3 = shared (new View ());
auto modalSession = frame->beginModalViewSession (view3);
frame->dispatchEvent (event);
EXPECT (event.consumed == true);
EXPECT (view3->onKeyUpCalled);
frame->endModalViewSession (*modalSession);
}
TEST_CASE (CFrameTest, AdvanceNextFocusView)
{
auto frame = owned (new CFrame (CRect (0, 0, 100, 100), nullptr));
auto view = new View ();
frame->attached (frame);
frame->addView (view);
frame->onActivate (true);
EXPECT (frame->getFocusView () == nullptr);
view->setWantsFocus (true);
frame->advanceNextFocusView (frame->getFocusView ());
EXPECT (frame->getFocusView () == view);
frame->removeAll ();
auto container = new CViewContainer ({0., 0., 20., 20.});
auto view2 = new View ();
container->addView (view2);
frame->addView (container);
EXPECT (frame->getFocusView () == nullptr);
view2->setWantsFocus (true);
frame->advanceNextFocusView (frame->getFocusView ());
EXPECT (frame->getFocusView () == view2);
auto container2 = new CViewContainer ({0., 0., 20., 20.});
auto view3 = new View ();
container2->addView (view3);
container->addView (container2);
frame->advanceNextFocusView (frame->getFocusView ());
EXPECT (frame->getFocusView () == nullptr);
view3->setWantsFocus (true);
frame->setFocusView (view2);
frame->advanceNextFocusView (frame->getFocusView ());
EXPECT (frame->getFocusView () == view3);
auto view4 = new View ();
view4->setWantsFocus (true);
container2->addView (view4);
frame->advanceNextFocusView (frame->getFocusView ());
EXPECT (frame->getFocusView () == view4);
auto container3 = new CViewContainer ({0., 0., 20., 20.});
auto view5 = new View ();
view5->setWantsFocus (true);
container3->addView (view5);
container->addView (container3);
frame->advanceNextFocusView (frame->getFocusView ());
EXPECT (frame->getFocusView () == view5);
auto view6 = new View ();
view6->setWantsFocus (true);
frame->addView (view6);
frame->advanceNextFocusView (nullptr);
EXPECT (frame->getFocusView () == view6);
}
TEST_CASE (CFrameTest, AdvanceNextFocusViewInModalView)
{
auto frame = owned (new CFrame (CRect (0, 0, 100, 100), nullptr));
auto view = shared (new View ());
frame->attached (frame);
auto modalSession = frame->beginModalViewSession (view);
EXPECT (frame->getFocusView () == nullptr);
frame->onActivate (true);
view->setWantsFocus (true);
frame->advanceNextFocusView (frame->getFocusView ());
EXPECT (frame->getFocusView () == view);
frame->endModalViewSession (*modalSession);
auto container = shared (new CViewContainer ({0., 0., 20., 20.}));
auto view2 = new View ();
container->addView (view2);
modalSession = frame->beginModalViewSession (container);
EXPECT (frame->getFocusView () == nullptr);
view2->setWantsFocus (true);
frame->advanceNextFocusView (frame->getFocusView ());
EXPECT (frame->getFocusView () == view2);
auto container2 = new CViewContainer ({0., 0., 20., 20.});
auto view3 = new View ();
container2->addView (view3);
container->addView (container2);
frame->advanceNextFocusView (frame->getFocusView ());
EXPECT (frame->getFocusView () == view2);
view3->setWantsFocus (true);
frame->advanceNextFocusView (frame->getFocusView ());
EXPECT (frame->getFocusView () == view3);
auto view4 = new View ();
view4->setWantsFocus (true);
container2->addView (view4);
frame->advanceNextFocusView (frame->getFocusView ());
EXPECT (frame->getFocusView () == view4);
auto container3 = new CViewContainer ({0., 0., 20., 20.});
auto view5 = new View ();
view5->setWantsFocus (true);
container3->addView (view5);
container->addView (container3);
frame->advanceNextFocusView (frame->getFocusView ());
EXPECT (frame->getFocusView () == view5);
frame->endModalViewSession (*modalSession);
}
TEST_CASE (CFrameTest, GetViewAtModalView)
{
auto frame = owned (new CFrame (CRect (0, 0, 100, 100), nullptr));
auto container = new CViewContainer ({0., 0., 20., 20.});
auto view = new View ();
container->addView (view);
frame->attached (frame);
auto modalSession = frame->beginModalViewSession (container);
EXPECT (frame->getViewAt (CPoint (1, 1)) == container);
EXPECT (frame->getViewAt (CPoint (1, 1), GetViewOptions (GetViewOptions::kDeep)) == view);
EXPECT (frame->getViewAt (CPoint (90, 90)) == nullptr);
frame->endModalViewSession (*modalSession);
}
TEST_CASE (CFrameTest, GetContainerAtModalView)
{
auto frame = owned (new CFrame (CRect (0, 0, 100, 100), nullptr));
auto container = new CViewContainer ({0., 0., 20., 20.});
CRect r (0, 0, 50, 50);
container->setViewSize (r);
container->setMouseableArea (r);
auto container2 = new CViewContainer ({0., 0., 20., 20.});
container->addView (container2);
frame->attached (frame);
EXPECT (frame->getContainerAt (CPoint (1, 1)) == frame);
auto modalSession = frame->beginModalViewSession (container);
EXPECT (frame->getContainerAt (CPoint (1, 1), GetViewOptions (GetViewOptions::kNone)) ==
container);
EXPECT (frame->getContainerAt (CPoint (1, 1), GetViewOptions (GetViewOptions::kDeep)) ==
container2);
EXPECT (frame->getContainerAt (CPoint (80, 80), GetViewOptions (GetViewOptions::kDeep)) ==
nullptr);
frame->endModalViewSession (*modalSession);
}
TEST_CASE (CFrameTest, MouseDownModalView)
{
auto frame = owned (new CFrame (CRect (0, 0, 100, 100), nullptr));
auto container = new CViewContainer ({0., 0., 20., 20.});
auto view1 = new View ();
container->addView (view1);
frame->attached (frame);
auto modalSession = frame->beginModalViewSession (container);
EXPECT_EQ (dispatchMouseEvent<MouseDownEvent> (frame, {80., 80.}, MouseButton::Left),
EventConsumeState::NotHandled);
EXPECT_FALSE (view1->onMouseDownCalled);
EXPECT_EQ (dispatchMouseEvent<MouseDownEvent> (frame, {1., 1.}, MouseButton::Left),
EventConsumeState::Handled);
EXPECT_TRUE (view1->onMouseDownCalled);
frame->endModalViewSession (*modalSession);
}
TEST_CASE (CFrameTest, Activate)
{
auto frame = owned (new CFrame (CRect (0, 0, 100, 100), nullptr));
auto view = new View ();
view->setWantsFocus (true);
auto view2 = new View ();
view2->setWantsFocus (true);
frame->addView (view);
frame->addView (view2);
frame->attached (frame);
EXPECT (frame->getFocusView () == nullptr);
frame->onActivate (false);
EXPECT (frame->getFocusView () == nullptr);
frame->onActivate (true);
EXPECT (frame->getFocusView () == view);
frame->setFocusView (view2);
frame->onActivate (false);
EXPECT (frame->getFocusView () == nullptr);
frame->onActivate (true);
EXPECT (frame->getFocusView () == view2);
}
TEST_CASE (CFrameTest, KeyboardHook)
{
KeyboardHook hook;
EXPECT (hook.keyDownCalled == false);
auto frame = owned (new CFrame (CRect (0, 0, 100, 100), nullptr));
frame->attached (frame);
frame->registerKeyboardHook (&hook);
KeyboardEvent event;
event.type = EventType::KeyDown;
frame->dispatchEvent (event);
EXPECT (hook.keyDownCalled);
EXPECT (hook.keyUpCalled == false);
event.type = EventType::KeyUp;
frame->dispatchEvent (event);
EXPECT (hook.keyUpCalled);
frame->unregisterKeyboardHook (&hook);
}
TEST_CASE (CFrameTest, Open)
{
auto platformHandle = UnitTest::PlatformParentHandle::create ();
EXPECT (platformHandle);
auto frame = new CFrame (CRect (0, 0, 100, 100), nullptr);
EXPECT (frame->open (nullptr) == false);
EXPECT (frame->open (platformHandle->getHandle (), platformHandle->getType ()));
frame->close ();
}
TEST_CASE (CFrameTest, SetPosition)
{
auto platformHandle = UnitTest::PlatformParentHandle::create ();
EXPECT (platformHandle);
auto frame = new CFrame (CRect (0, 0, 100, 100), nullptr);
frame->open (platformHandle->getHandle (), platformHandle->getType ());
EXPECT (frame->setPosition (10, 10));
CRect r;
frame->getSize (r);
EXPECT (r == CRect (10, 10, 110, 110));
frame->close ();
}
#if 0
TEST_CASE (CFrameTest, CollectInvalidRectsOnMouseDown)
{
// It is expected that this test failes on Mac OS X 10.11 because of OS changes
auto platformHandle = UnitTest::PlatformParentHandle::create ();
auto frame = new CFrame (CRect (0, 0, 100, 100), nullptr);
auto view = new CollectInvalidRectView ();
frame->addView (view);
frame->open (platformHandle->getHandle (), platformHandle->getType ());
platformHandle->forceRedraw ();
EXPECT (view->callCount == 1);
EXPECT (view->redrawRect == view->getViewSize ());
auto platformFrameCallback = dynamic_cast<IPlatformFrameCallback*> (frame);
MouseDownEvent downEvent (CPoint (), MouseButton::Left);
platformFrameCallback->platformOnEvent (downEvent);
platformHandle->forceRedraw ();
EXPECT (view->redrawRect == CRect (0, 0, 8, 8));
EXPECT (view->callCount == 2);
frame->close ();
}
#endif
#if VSTGUI_ENABLE_DEPRECATED_METHODS
#include "../../../lib/private/disabledeprecatedmessage.h"
TEST_CASE (CFameLegacyTest, SetModalView)
{
auto frame = owned (new CFrame (CRect (0, 0, 100, 100), nullptr));
auto view = owned (new View ());
EXPECT (frame->getModalView () == nullptr);
EXPECT (frame->setModalView (view));
EXPECT (frame->getModalView () == view);
auto container = owned (new CViewContainer (CRect (0, 0, 0, 0)));
EXPECT (frame->setModalView (container) == false);
EXPECT (frame->setModalView (nullptr));
EXPECT (frame->setModalView (container));
EXPECT (frame->getModalView () == container);
EXPECT (frame->setModalView (nullptr));
EXPECT (frame->getModalView () == nullptr);
}
#include "../../../lib/private/enabledeprecatedmessage.h"
#endif
} // VSTGUI
@@ -0,0 +1,50 @@
// This file is part of VSTGUI. It is subject to the license terms
// in the LICENSE file found in the top-level directory of this
// distribution and at http://github.com/steinbergmedia/vstgui/LICENSE
#include "../../../lib/cinvalidrectlist.h"
#include "../unittests.h"
namespace VSTGUI {
TEST_CASE (CInvalidRectListTest, RectEqual)
{
CInvalidRectList list;
EXPECT_TRUE (list.add ({0, 0, 100, 100}));
EXPECT_FALSE (list.add ({0, 0, 100, 100}));
EXPECT_EQ (list.data ().size (), 1u);
}
TEST_CASE (CInvalidRectListTest, AddBiggerOne)
{
CInvalidRectList list;
EXPECT_TRUE (list.add ({0, 0, 100, 100}));
EXPECT_TRUE (list.add ({0, 0, 200, 200}));
EXPECT_EQ (list.data ().size (), 1u);
}
TEST_CASE (CInvalidRectListTest, AddSmallerOne)
{
CInvalidRectList list;
EXPECT_TRUE (list.add ({0, 0, 100, 100}));
EXPECT_FALSE (list.add ({10, 10, 20, 20}));
EXPECT_EQ (list.data ().size (), 1u);
}
TEST_CASE (CInvalidRectListTest, AddOverlappingOne)
{
CInvalidRectList list;
EXPECT_TRUE (list.add ({0, 0, 100, 100}));
EXPECT_TRUE (list.add ({90, 0, 120, 100}));
EXPECT_EQ (list.data ().size (), 1u);
}
TEST_CASE (CInvalidRectListTest, AddMulti)
{
CInvalidRectList list;
EXPECT_TRUE (list.add ({0, 0, 10, 10}));
EXPECT_TRUE (list.add ({20, 20, 30, 30}));
EXPECT_EQ (list.data ().size (), 2u);
}
} // VSTGUI
@@ -0,0 +1,113 @@
// This file is part of VSTGUI. It is subject to the license terms
// in the LICENSE file found in the top-level directory of this
// distribution and at http://github.com/steinbergmedia/vstgui/LICENSE
#include "../../../lib/clinestyle.h"
#include "../unittests.h"
namespace VSTGUI {
TEST_CASE (CLineStyleTest, DefaultConstructor)
{
CLineStyle style;
EXPECT (style.getLineCap () == CLineStyle::kLineCapButt);
EXPECT (style.getLineJoin () == CLineStyle::kLineJoinMiter);
EXPECT (style.getDashPhase () == 0.);
EXPECT (style.getDashCount () == 0);
EXPECT (style.getDashLengths ().size () == 0);
}
TEST_CASE (CLineStyleTest, SolidLine)
{
CLineStyle style;
EXPECT (style == kLineSolid);
}
TEST_CASE (CLineStyleTest, OnOffDashLine)
{
CLineStyle style (CLineStyle::kLineCapButt, CLineStyle::kLineJoinMiter, 0., {1., 1.});
EXPECT (kLineOnOffDash == style);
}
TEST_CASE (CLineStyleTest, DashLengths)
{
CLineStyle style (CLineStyle::kLineCapButt, CLineStyle::kLineJoinMiter, 0., {1., 3., 2.});
EXPECT (style.getDashCount () == 3);
const auto& dashLengths = style.getDashLengths ();
EXPECT (dashLengths[0] == 1.);
EXPECT (dashLengths[1] == 3.);
EXPECT (dashLengths[2] == 2.);
style.getDashLengths ().push_back (6.);
EXPECT (style.getDashCount () == 4);
EXPECT (style.getDashLengths ()[3] == 6.);
}
TEST_CASE (CLineStyleTest, LineCap)
{
CLineStyle style;
style.setLineCap (CLineStyle::kLineCapButt);
EXPECT (style.getLineCap () == CLineStyle::kLineCapButt);
style.setLineCap (CLineStyle::kLineCapRound);
EXPECT (style.getLineCap () == CLineStyle::kLineCapRound);
style.setLineCap (CLineStyle::kLineCapSquare);
EXPECT (style.getLineCap () == CLineStyle::kLineCapSquare);
}
TEST_CASE (CLineStyleTest, LineJoin)
{
CLineStyle style;
style.setLineJoin (CLineStyle::kLineJoinMiter);
EXPECT (style.getLineJoin () == CLineStyle::kLineJoinMiter);
style.setLineJoin (CLineStyle::kLineJoinRound);
EXPECT (style.getLineJoin () == CLineStyle::kLineJoinRound);
style.setLineJoin (CLineStyle::kLineJoinBevel);
EXPECT (style.getLineJoin () == CLineStyle::kLineJoinBevel);
}
TEST_CASE (CLineStyleTest, DashPhase)
{
CLineStyle style;
style.setDashPhase (1.5);
EXPECT (style.getDashPhase () == 1.5);
style.setDashPhase (2.5);
EXPECT (style.getDashPhase () == 2.5);
}
TEST_CASE (CLineStyleTest, CopyConstructor)
{
CLineStyle style;
style.setDashPhase (2.);
style.getDashLengths ().push_back (1.);
style.getDashLengths ().push_back (2.);
CLineStyle s2 (style);
EXPECT (style.getLineCap () == CLineStyle::kLineCapButt);
EXPECT (style.getLineJoin () == CLineStyle::kLineJoinMiter);
EXPECT (style.getDashPhase () == 2.);
EXPECT (style.getDashCount () == 2);
EXPECT (style.getDashLengths ()[0] == 1.);
EXPECT (style.getDashLengths ()[1] == 2.);
}
TEST_CASE (CLineStyleTest, MoveConstructor)
{
CLineStyle style;
style.getDashLengths ().push_back (1.);
style.getDashLengths ().push_back (2.);
CLineStyle s2 (std::move (style));
EXPECT (style.getDashCount () == 0);
EXPECT (s2.getDashCount () == 2);
}
TEST_CASE (CLineStyleTest, VectorConstructor)
{
CLineStyle::CoordVector dashLengths ({2., 4.});
CLineStyle style (CLineStyle::kLineCapButt, CLineStyle::kLineJoinMiter, 0., dashLengths);
EXPECT (dashLengths == style.getDashLengths ());
}
TEST_CASE (CLineStyleTest, UnequalOperator)
{
EXPECT (kLineSolid != kLineOnOffDash);
}
} // VSTGUI
@@ -0,0 +1,77 @@
// This file is part of VSTGUI. It is subject to the license terms
// in the LICENSE file found in the top-level directory of this
// distribution and at http://github.com/steinbergmedia/vstgui/LICENSE
#include "../../../../lib/controls/cbuttons.h"
#include "../../unittests.h"
#include "../eventhelpers.h"
namespace VSTGUI {
TEST_CASE (CCheckboxTest, MouseEvents)
{
auto b = owned (new CCheckBox (CRect (10, 10, 50, 20)));
b->setValue (b->getMin ());
EXPECT_EQ (dispatchMouseEvent<MouseDownEvent> (b, {10., 10.}, MouseButton::Right),
EventConsumeState::Handled | MouseDownUpMoveEvent::IgnoreFollowUpEventsMask);
EXPECT_FALSE (b->isEditing ());
EXPECT_EQ (dispatchMouseEvent<MouseDownEvent> (b, {10., 10.}, MouseButton::Left),
EventConsumeState::Handled);
EXPECT_TRUE (b->isEditing ());
EXPECT_EQ (dispatchMouseEvent<MouseMoveEvent> (b, {10., 10.}, MouseButton::Left),
EventConsumeState::Handled);
EXPECT_TRUE (b->isEditing ());
EXPECT_EQ (dispatchMouseEvent<MouseUpEvent> (b, {10., 10.}, MouseButton::Left),
EventConsumeState::Handled);
EXPECT_FALSE (b->isEditing ());
EXPECT_EQ (b->getValue (), b->getMax ());
EXPECT_EQ (dispatchMouseEvent<MouseDownEvent> (b, {10., 10.}, MouseButton::Left),
EventConsumeState::Handled);
EXPECT_TRUE (b->isEditing ());
EXPECT_EQ (dispatchMouseEvent<MouseUpEvent> (b, {10., 10.}, MouseButton::Left),
EventConsumeState::Handled);
EXPECT_FALSE (b->isEditing ());
EXPECT_EQ (b->getValue (), b->getMin ());
EXPECT_EQ (dispatchMouseEvent<MouseDownEvent> (b, {10., 10.}, MouseButton::Left),
EventConsumeState::Handled);
EXPECT_TRUE (b->isEditing ());
EXPECT_EQ (dispatchMouseEvent<MouseUpEvent> (b, {0., 0.}, MouseButton::Left),
EventConsumeState::Handled);
EXPECT_FALSE (b->isEditing ());
EXPECT_EQ (b->getValue (), b->getMin ());
EXPECT_EQ (dispatchMouseEvent<MouseDownEvent> (b, {10., 10.}, MouseButton::Left),
EventConsumeState::Handled);
EXPECT_TRUE (b->isEditing ());
MouseCancelEvent cancelEvent;
b->dispatchEvent (cancelEvent);
EXPECT_TRUE (cancelEvent.consumed);
EXPECT (b->isEditing () == false);
EXPECT_EQ (b->getValue (), b->getMin ());
}
TEST_CASE (CCheckboxTest, KeyEvents)
{
auto b = owned (new CCheckBox (CRect (10, 10, 50, 20)));
b->setValue (b->getMin ());
KeyboardEvent event;
event.virt = VirtualKey::Return;
b->onKeyboardEvent (event);
EXPECT_TRUE (event.consumed);
EXPECT (b->getValue () == b->getMax ());
event.consumed.reset ();
b->onKeyboardEvent (event);
EXPECT_TRUE (event.consumed);
EXPECT (b->getValue () == b->getMin ());
event.virt = VirtualKey::None;
event.character = 't';
event.consumed.reset ();
b->onKeyboardEvent (event);
EXPECT_FALSE (event.consumed);
}
} // VSTGUI
@@ -0,0 +1,153 @@
// This file is part of VSTGUI. It is subject to the license terms
// in the LICENSE file found in the top-level directory of this
// distribution and at http://github.com/steinbergmedia/vstgui/LICENSE
#include "../../../../lib/controls/ccontrol.h"
#include "../../../../lib/controls/icontrollistener.h"
#include "../../unittests.h"
#include "../eventhelpers.h"
namespace VSTGUI {
namespace {
class Control : public CControl
{
public:
Control () : CControl (CRect (0, 0, 10, 10)) {}
void draw (CDrawContext* pContext) override {}
#if VSTGUI_ENABLE_DEPRECATED_METHODS
static int32_t mapVstKeyModifier (int32_t vstModifier)
{
#include "../../../../lib/private/disabledeprecatedmessage.h"
return CControl::mapVstKeyModifier (vstModifier);
#include "../../../../lib/private/enabledeprecatedmessage.h"
}
#endif
CLASS_METHODS (Control, CControl)
};
struct Listener : IControlListener
{
bool valueChangedCalled {false};
bool beginEditCalled {false};
bool endEditCalled {false};
void valueChanged (CControl* pControl) override { valueChangedCalled = true; }
void controlBeginEdit (CControl* pControl) override { beginEditCalled = true; }
void controlEndEdit (CControl* pControl) override { endEditCalled = true; }
};
}
TEST_CASE (CControlTest, Editing)
{
Control c;
c.beginEdit ();
EXPECT (c.isEditing ());
c.setValue (0.5f);
c.endEdit ();
EXPECT (c.isEditing () == false);
}
TEST_CASE (CControlTest, Listener)
{
Control c;
Listener l;
c.setListener (&l);
c.beginEdit ();
EXPECT (l.beginEditCalled);
c.setValue (0.5f);
c.valueChanged ();
EXPECT (l.valueChangedCalled);
c.endEdit ();
EXPECT (l.endEditCalled);
}
TEST_CASE (CControlTest, SubListener)
{
Control c;
Listener l;
c.registerControlListener (&l);
c.beginEdit ();
EXPECT (l.beginEditCalled);
c.setValue (0.5f);
c.valueChanged ();
EXPECT (l.valueChangedCalled);
c.endEdit ();
EXPECT (l.endEditCalled);
c.unregisterControlListener (&l);
}
TEST_CASE (CControlTest, SetValueOutOfRange)
{
Control c;
EXPECT (c.getMin () == 0.f);
EXPECT (c.getMax () == 1.f);
c.setValue (0.5f);
EXPECT (c.getValue () == 0.5f);
c.setValue (-0.5f);
EXPECT (c.getValue () == 0.f);
c.setValue (1.5f);
EXPECT (c.getValue () == 1.f);
}
TEST_CASE (CControlTest, SetValueNormalized)
{
Control c;
c.setMin (1.f);
c.setMax (2.f);
c.setValueNormalized (0.f);
EXPECT (c.getValue () == 1.f);
c.setValueNormalized (1.f);
EXPECT (c.getValue () == 2.f);
c.setValueNormalized (0.5f);
EXPECT (c.getValue () == 1.5f);
c.setValueNormalized (-1.f);
EXPECT (c.getValue () == 1.f);
c.setValueNormalized (2.f);
EXPECT (c.getValue () == 2.f);
}
TEST_CASE (CControlTest, CheckDefaultValue)
{
Control c;
c.setValue (c.getDefaultValue () + 0.1f);
EXPECT_EQ (dispatchMouseEvent<MouseDownEvent> (&c, {0., 0.}, MouseButton::Left,
Modifiers (ModifierKey::Control)),
EventConsumeState::Handled + MouseDownUpMoveEvent::IgnoreFollowUpEventsMask);
EXPECT (c.getValue () == c.getDefaultValue ());
c.setValue (c.getDefaultValue () + 0.1f);
EXPECT_EQ (dispatchMouseEvent<MouseDownEvent> (&c, {0., 0.}, MouseButton::Right,
Modifiers (ModifierKey::Control)),
0);
EXPECT (c.getValue () == c.getDefaultValue () + 0.1f);
auto oldCheckDefaultValueFunc = CControl::CheckDefaultValueEventFunc;
CControl::CheckDefaultValueEventFunc = [] (CControl*, MouseDownEvent& event) {
return (event.buttonState.isMiddle () && event.modifiers.is (ModifierKey::Shift));
};
EXPECT_EQ (dispatchMouseEvent<MouseDownEvent> (&c, {0., 0.}, MouseButton::Left,
Modifiers (ModifierKey::Control)),
0);
EXPECT_EQ (dispatchMouseEvent<MouseDownEvent> (&c, {0., 0.}, MouseButton::Middle,
Modifiers (ModifierKey::Shift)),
EventConsumeState::Handled + MouseDownUpMoveEvent::IgnoreFollowUpEventsMask);
CControl::CheckDefaultValueEventFunc = oldCheckDefaultValueFunc;
}
#if VSTGUI_ENABLE_DEPRECATED_METHODS
TEST_CASE (CControlTest, mapVstKeyModifier)
{
EXPECT (Control::mapVstKeyModifier (MODIFIER_SHIFT) == kShift);
EXPECT (Control::mapVstKeyModifier (MODIFIER_ALTERNATE) == kAlt);
EXPECT (Control::mapVstKeyModifier (MODIFIER_COMMAND) == kApple);
EXPECT (Control::mapVstKeyModifier (MODIFIER_CONTROL) == kControl);
}
#endif
} // VSTGUI
@@ -0,0 +1,74 @@
// This file is part of VSTGUI. It is subject to the license terms
// in the LICENSE file found in the top-level directory of this
// distribution and at http://github.com/steinbergmedia/vstgui/LICENSE
#include "../../../../lib/controls/cbuttons.h"
#include "../../unittests.h"
#include "../eventhelpers.h"
namespace VSTGUI {
TEST_CASE (CKickButtonTest, MouseEvents)
{
auto b = owned (new CKickButton (CRect (10, 10, 50, 20), nullptr, 0, nullptr));
b->setValue (b->getMin ());
EXPECT_EQ (dispatchMouseEvent<MouseDownEvent> (b, {10., 10.}, MouseButton::Right),
EventConsumeState::NotHandled);
EXPECT_EQ (dispatchMouseEvent<MouseMoveEvent> (b, {10., 10.}, MouseButton::Left),
EventConsumeState::NotHandled);
EXPECT_FALSE (b->isEditing ());
EXPECT_EQ (dispatchMouseEvent<MouseDownEvent> (b, {10., 10.}, MouseButton::Left),
EventConsumeState::Handled);
EXPECT_TRUE (b->isEditing ());
EXPECT_EQ (b->getValue (), b->getMax ());
EXPECT_EQ (dispatchMouseEvent<MouseMoveEvent> (b, {0., 0.}, MouseButton::Left),
EventConsumeState::Handled);
EXPECT_TRUE (b->isEditing ());
EXPECT_EQ (b->getValue (), b->getMin ());
EXPECT_EQ (dispatchMouseEvent<MouseMoveEvent> (b, {10., 10.}, MouseButton::Left),
EventConsumeState::Handled);
EXPECT_TRUE (b->isEditing ());
EXPECT_EQ (b->getValue (), b->getMax ());
EXPECT_EQ (dispatchMouseEvent<MouseUpEvent> (b, {10., 10.}, MouseButton::Left),
EventConsumeState::Handled);
EXPECT_FALSE (b->isEditing ());
EXPECT_EQ (b->getValue (), b->getMin ());
EXPECT_EQ (dispatchMouseEvent<MouseDownEvent> (b, {10., 10.}, MouseButton::Left),
EventConsumeState::Handled);
EXPECT_EQ (b->getValue (), b->getMax ());
EXPECT_TRUE (b->isEditing ());
EXPECT_EQ (dispatchMouseCancelEvent (b), EventConsumeState::Handled);
EXPECT_FALSE (b->isEditing ());
EXPECT_EQ (b->getValue (), b->getMin ());
}
TEST_CASE (CKickButtonTest, KeyEvents)
{
auto b = owned (new CKickButton (CRect (10, 10, 50, 20), nullptr, 0, nullptr));
b->setValue (b->getMin ());
KeyboardEvent event;
event.virt = VirtualKey::Return;
b->onKeyboardEvent (event);
EXPECT_TRUE (event.consumed);
EXPECT_EQ (b->getValue (), b->getMax ());
event.consumed.reset ();
b->onKeyboardEvent (event);
EXPECT_TRUE (event.consumed);
EXPECT_EQ (b->getValue (), b->getMax ());
event.consumed.reset ();
event.type = EventType::KeyUp;
b->onKeyboardEvent (event);
EXPECT_TRUE (event.consumed);
EXPECT_EQ (b->getValue (), b->getMin ());
KeyboardEvent event2;
event2.character = 't';
b->onKeyboardEvent (event2);
EXPECT_FALSE (event2.consumed);
event2.type = EventType::KeyUp;
b->onKeyboardEvent (event2);
EXPECT_FALSE (event2.consumed);
}
} // VSTGUI
@@ -0,0 +1,304 @@
// This file is part of VSTGUI. It is subject to the license terms
// in the LICENSE file found in the top-level directory of this
// distribution and at http://github.com/steinbergmedia/vstgui/LICENSE
#include "../../../../lib/controls/clistcontrol.h"
#include "../../../../lib/cscrollview.h"
#include "../../unittests.h"
#include "../eventhelpers.h"
//------------------------------------------------------------------------
namespace VSTGUI {
//------------------------------------------------------------------------
static SharedPointer<CListControl>
createTestListControl (CCoord rowHeight, int32_t numRows = 10,
CListControlRowDesc::Flags rowFlags = CListControlRowDesc::Flags {
CListControlRowDesc::Selectable | CListControlRowDesc::Hoverable})
{
auto listControl = makeOwned<CListControl> (CRect (0, 0, 100, 100));
auto config = makeOwned<StaticListControlConfigurator> (rowHeight, rowFlags);
listControl->setMin (0.f);
listControl->setMax (static_cast<float> (numRows));
listControl->setConfigurator (config);
listControl->recalculateLayout ();
listControl->setValue (0.f);
return listControl;
}
//------------------------------------------------------------------------
static SharedPointer<CScrollView> createScrollViewAndEmbedListControl (CViewContainer* parent,
CListControl* listControl)
{
auto scrollView =
makeOwned<CScrollView> (CRect (0, 0, 100, listControl->getHeight () / 2),
listControl->getViewSize (), CScrollView::kVerticalScrollbar);
scrollView->addView (listControl);
listControl->remember ();
parent->addView (scrollView);
scrollView->attached (parent);
return scrollView;
}
//------------------------------------------------------------------------
static KeyboardEvent makeKeyboardEvent (int32_t c, VirtualKey virt,
ModifierKey modifier = ModifierKey::None)
{
KeyboardEvent event;
event.type = EventType::KeyDown;
event.character = c;
event.virt = virt;
event.modifiers.add (modifier);
return event;
}
TEST_CASE (CListControlTest, minMax)
{
constexpr auto rowHeight = 20;
auto listControl = createTestListControl (rowHeight);
listControl->setMin (-5.f);
listControl->setMax (5.f);
auto row = listControl->getRowAtPoint (CPoint (0, 0));
EXPECT (row);
if (row)
{
EXPECT (*row == -5);
}
row = listControl->getRowAtPoint (CPoint (0, listControl->getHeight () - 1));
EXPECT (row);
if (row)
{
EXPECT (*row == 5);
}
}
TEST_CASE (CListControlTest, MouseRowSelection)
{
constexpr auto rowHeight = 20;
auto listControl = createTestListControl (rowHeight);
dispatchMouseEvent<MouseDownEvent> (listControl, {0., rowHeight}, MouseButton::Left);
dispatchMouseEvent<MouseUpEvent> (listControl, {0., rowHeight}, MouseButton::Left);
EXPECT_EQ (listControl->getValue (), 1.f);
dispatchMouseEvent<MouseDownEvent> (listControl, {0., rowHeight * 3.}, MouseButton::Left);
dispatchMouseEvent<MouseUpEvent> (listControl, {0., rowHeight * 3.}, MouseButton::Left);
EXPECT_EQ (listControl->getValue (), 3.f);
}
TEST_CASE (CListControlTest, Hovering)
{
constexpr auto rowHeight = 20;
constexpr auto numRows = 5;
auto listControl = createTestListControl (rowHeight, numRows);
EXPECT_FALSE (listControl->getHoveredRow ());
dispatchMouseEvent<MouseMoveEvent>(listControl, {10., 5.});
EXPECT_TRUE (listControl->getHoveredRow ());
EXPECT_EQ (*listControl->getHoveredRow (), 0);
dispatchMouseEvent<MouseMoveEvent>(listControl, {10., 5. + rowHeight});
EXPECT_TRUE (listControl->getHoveredRow ());
EXPECT_EQ (*listControl->getHoveredRow (), 1);
dispatchMouseEvent<MouseExitEvent>(listControl, {10., 5. + rowHeight});
EXPECT_FALSE (listControl->getHoveredRow ());
}
TEST_CASE (CListControlTest, RowRect)
{
constexpr auto rowHeight = 20;
auto listControl = createTestListControl (rowHeight);
auto rr = listControl->getRowRect (1);
EXPECT (rr);
if (rr)
{
EXPECT (*rr == CRect (0, rowHeight, 100, rowHeight * 2.));
}
}
TEST_CASE (CListControlTest, KeyDownOnUnselectableRows)
{
constexpr auto rowHeight = 20;
constexpr auto numRows = 20;
auto listControl = createTestListControl (rowHeight, numRows, {});
listControl->setValue (2.f);
EXPECT (listControl->getValue () == 2.f);
auto event = makeKeyboardEvent (0, VirtualKey::Down);
listControl->onKeyboardEvent (event);
EXPECT (event.consumed == false);
EXPECT (listControl->getValue () == 2.f);
}
TEST_CASE (CListControlTest, KeyWithModifier)
{
constexpr auto rowHeight = 20;
constexpr auto numRows = 20;
auto listControl = createTestListControl (rowHeight, numRows, {});
listControl->setValue (1.f);
auto event = makeKeyboardEvent (0, VirtualKey::Down, ModifierKey::Shift);
listControl->onKeyboardEvent (event);
EXPECT (event.consumed == false);
EXPECT (listControl->getValue () == 1.f);
event = makeKeyboardEvent (0, VirtualKey::Up, ModifierKey::Shift);
listControl->onKeyboardEvent (event);
EXPECT (event.consumed == false);
EXPECT (listControl->getValue () == 1.f);
event = makeKeyboardEvent (0, VirtualKey::Home, ModifierKey::Shift);
listControl->onKeyboardEvent (event);
EXPECT (event.consumed == false);
EXPECT (listControl->getValue () == 1.f);
event = makeKeyboardEvent (0, VirtualKey::End, ModifierKey::Shift);
listControl->onKeyboardEvent (event);
EXPECT (event.consumed == false);
EXPECT (listControl->getValue () == 1.f);
event = makeKeyboardEvent (0, VirtualKey::PageUp, ModifierKey::Shift);
listControl->onKeyboardEvent (event);
EXPECT (event.consumed == false);
EXPECT (listControl->getValue () == 1.f);
event = makeKeyboardEvent (0, VirtualKey::PageDown, ModifierKey::Shift);
listControl->onKeyboardEvent (event);
EXPECT (event.consumed == false);
EXPECT (listControl->getValue () == 1.f);
}
TEST_CASE (CListControlTest, KeyHome)
{
constexpr auto rowHeight = 20;
auto listControl = createTestListControl (rowHeight);
listControl->setValue (5.f);
EXPECT (listControl->getValue () == 5.f);
auto event = makeKeyboardEvent (0, VirtualKey::Home);
listControl->onKeyboardEvent (event);
EXPECT (event.consumed == true);
EXPECT (listControl->getValue () == 0.f);
}
TEST_CASE (CListControlTest, KeyEnd)
{
constexpr auto rowHeight = 20;
constexpr auto numRows = 20;
auto listControl = createTestListControl (rowHeight, numRows);
listControl->setValue (0.f);
EXPECT (listControl->getValue () == 0.f);
auto event = makeKeyboardEvent (0, VirtualKey::End);
listControl->onKeyboardEvent (event);
EXPECT (event.consumed == true);
EXPECT (listControl->getValue () == numRows);
}
TEST_CASE (CListControlTest, KeyUp)
{
constexpr auto rowHeight = 20;
constexpr auto numRows = 20;
auto listControl = createTestListControl (rowHeight, numRows);
listControl->setValue (2.f);
EXPECT (listControl->getValue () == 2.f);
auto event = makeKeyboardEvent (0, VirtualKey::Up);
listControl->onKeyboardEvent (event);
EXPECT (event.consumed == true);
EXPECT (listControl->getValue () == 1.f);
event.consumed.reset ();
listControl->setValue (0.f);
listControl->onKeyboardEvent (event);
EXPECT (event.consumed == true);
EXPECT (listControl->getValue () == numRows);
}
TEST_CASE (CListControlTest, KeyDown)
{
constexpr auto rowHeight = 20;
constexpr auto numRows = 20;
auto listControl = createTestListControl (rowHeight, numRows);
listControl->setValue (2.f);
EXPECT (listControl->getValue () == 2.f);
auto event = makeKeyboardEvent (0, VirtualKey::Down);
listControl->onKeyboardEvent (event);
EXPECT (event.consumed == true);
EXPECT (listControl->getValue () == 3.f);
event.consumed.reset ();
listControl->setValue (numRows);
listControl->onKeyboardEvent (event);
EXPECT (event.consumed == true);
EXPECT (listControl->getValue () == 0.f);
}
TEST_CASE (CListControlTest, PageUp)
{
constexpr auto rowHeight = 20;
constexpr auto numRows = 30;
auto parent = makeOwned<CViewContainer> (CRect (0, 0, 1000, 1000));
auto listControl = createTestListControl (rowHeight, numRows);
auto scrollView = createScrollViewAndEmbedListControl (parent, listControl);
listControl->setValue (numRows);
auto rect = listControl->getRowRect (0);
scrollView->makeRectVisible (*rect);
auto event = makeKeyboardEvent (0, VirtualKey::PageUp);
listControl->onKeyboardEvent (event);
EXPECT (event.consumed == true);
EXPECT (listControl->getValue () == 15.f);
event.consumed.reset ();
listControl->setValue (16);
listControl->onKeyboardEvent (event);
EXPECT (event.consumed == true);
EXPECT (listControl->getValue () == 15.f);
event.consumed.reset ();
listControl->onKeyboardEvent (event);
EXPECT (event.consumed == true);
EXPECT (listControl->getValue () == 0.f);
scrollView->removed (parent);
parent->removeAll (false);
}
TEST_CASE (CListControlTest, PageDown)
{
constexpr auto rowHeight = 20;
constexpr auto numRows = 30;
auto parent = makeOwned<CViewContainer> (CRect (0, 0, 1000, 1000));
auto listControl = createTestListControl (rowHeight, numRows);
auto scrollView = createScrollViewAndEmbedListControl (parent, listControl);
listControl->setValue (0.f);
auto rect = listControl->getRowRect (numRows);
scrollView->makeRectVisible (*rect);
auto event = makeKeyboardEvent (0, VirtualKey::PageDown);
listControl->onKeyboardEvent (event);
EXPECT (event.consumed == true);
EXPECT (listControl->getValue () == 15.f);
event.consumed.reset ();
listControl->setValue (14);
listControl->onKeyboardEvent (event);
EXPECT (event.consumed == true);
EXPECT (listControl->getValue () == 15.f);
event.consumed.reset ();
listControl->onKeyboardEvent (event);
EXPECT (event.consumed == true);
EXPECT (listControl->getValue () == 30.f);
scrollView->removed (parent);
parent->removeAll (false);
}
//------------------------------------------------------------------------
} // VSTGUI
@@ -0,0 +1,68 @@
// This file is part of VSTGUI. It is subject to the license terms
// in the LICENSE file found in the top-level directory of this
// distribution and at http://github.com/steinbergmedia/vstgui/LICENSE
#include "../../../../lib/controls/cbuttons.h"
#include "../../unittests.h"
#include "../eventhelpers.h"
namespace VSTGUI {
TEST_CASE (COnOffButtonTest, MouseEvents)
{
auto b = owned (new COnOffButton (CRect (10, 10, 50, 20)));
b->setValue (b->getMin ());
EXPECT_EQ (dispatchMouseEvent<MouseDownEvent> (b, {10., 10.}, MouseButton::Right),
EventConsumeState::NotHandled);
EXPECT_FALSE (b->isEditing ());
EXPECT_EQ (dispatchMouseEvent<MouseDownEvent> (b, {10., 10.}, MouseButton::Left),
EventConsumeState::Handled);
EXPECT_TRUE (b->isEditing ());
EXPECT_EQ (dispatchMouseEvent<MouseMoveEvent> (b, {10., 10.}, MouseButton::Left),
EventConsumeState::Handled);
EXPECT_TRUE (b->isEditing ());
EXPECT_EQ (dispatchMouseEvent<MouseUpEvent> (b, {10., 10.}, MouseButton::Left),
EventConsumeState::Handled);
EXPECT_FALSE (b->isEditing ());
EXPECT_EQ (b->getValue (), b->getMax ());
EXPECT_EQ (dispatchMouseEvent<MouseDownEvent> (b, {10., 10.}, MouseButton::Left),
EventConsumeState::Handled);
EXPECT_TRUE (b->isEditing ());
EXPECT_EQ (dispatchMouseEvent<MouseMoveEvent> (b, {10., 10.}, MouseButton::Left),
EventConsumeState::Handled);
EXPECT_TRUE (b->isEditing ());
EXPECT_EQ (dispatchMouseEvent<MouseUpEvent> (b, {0., 0.}, MouseButton::Left),
EventConsumeState::Handled);
EXPECT_FALSE (b->isEditing ());
EXPECT_EQ (b->getValue (), b->getMax ());
EXPECT_EQ (dispatchMouseEvent<MouseDownEvent> (b, {10., 10.}, MouseButton::Left),
EventConsumeState::Handled);
EXPECT_TRUE (b->isEditing ());
EXPECT_EQ (dispatchMouseCancelEvent (b), EventConsumeState::Handled);
EXPECT_FALSE (b->isEditing ());
}
TEST_CASE (COnOffButtonTest, KeyEvents)
{
auto b = owned (new COnOffButton (CRect (10, 10, 50, 20)));
b->setValue (b->getMin ());
KeyboardEvent event;
event.virt = VirtualKey::Return;
b->onKeyboardEvent (event);
EXPECT_TRUE (event.consumed);
EXPECT_EQ (b->getValue (), b->getMax ());
event.consumed.reset ();
b->onKeyboardEvent (event);
EXPECT_TRUE (event.consumed);
EXPECT_EQ (b->getValue (), b->getMin ());
event.consumed.reset ();
event.virt = VirtualKey::None;
event.character = 't';
b->onKeyboardEvent (event);
EXPECT_FALSE (event.consumed);
}
} // VSTGUI
@@ -0,0 +1,58 @@
// This file is part of VSTGUI. It is subject to the license terms
// in the LICENSE file found in the top-level directory of this
// distribution and at http://github.com/steinbergmedia/vstgui/LICENSE
#include "../../../../lib/controls/coptionmenu.h"
#include "../../unittests.h"
#include "../eventhelpers.h"
namespace VSTGUI {
//------------------------------------------------------------------------
class TestCommandMenuItemTarget
: public CommandMenuItemTargetAdapter
, public NonAtomicReferenceCounted
{
};
TEST_CASE (CCommandMenuItemTest, DescConstructor1)
{
auto target = makeOwned<TestCommandMenuItemTarget> ();
CCommandMenuItem item (
{"Title", "k", 0, nullptr, CMenuItem::kNoFlags, target, "CommandCategory", "CommandName"});
EXPECT_EQ (item.getTitle (), "Title");
EXPECT_EQ (item.getKeycode (), "k");
EXPECT_EQ (item.getIcon (), nullptr);
EXPECT_EQ (item.getItemTarget (), target);
EXPECT_EQ (item.getCommandCategory (), "CommandCategory");
EXPECT_EQ (item.getCommandName (), "CommandName");
}
TEST_CASE (CCommandMenuItemTest, DescConstructor2)
{
auto target = makeOwned<TestCommandMenuItemTarget> ();
CCommandMenuItem item ({"Title", 100, target, "CommandCat", "CmdName"});
EXPECT_EQ (item.getTitle (), "Title");
EXPECT_EQ (item.getItemTarget (), target);
EXPECT_EQ (item.getCommandCategory (), "CommandCat");
EXPECT_EQ (item.getCommandName (), "CmdName");
EXPECT_EQ (item.getTag (), 100);
}
TEST_CASE (CCommandMenuItemTest, DescConstructor3)
{
auto target = makeOwned<TestCommandMenuItemTarget> ();
CCommandMenuItem item ({"MenuItem", target, "CmdCat", "CommandNme"});
EXPECT_EQ (item.getTitle (), "MenuItem");
EXPECT_EQ (item.getItemTarget (), target);
EXPECT_EQ (item.getCommandCategory (), "CmdCat");
EXPECT_EQ (item.getCommandName (), "CommandNme");
}
TEST_CASE (COptionMenuTest, GetMaxWhenEmpty)
{
COptionMenu menu;
EXPECT_EQ (menu.getMax (), 0.f);
}
} // VSTGUI
@@ -0,0 +1,446 @@
// This file is part of VSTGUI. It is subject to the license terms
// in the LICENSE file found in the top-level directory of this
// distribution and at http://github.com/steinbergmedia/vstgui/LICENSE
#include "../../../../lib/controls/csegmentbutton.h"
#include "../../../../lib/cviewcontainer.h"
#include "../../unittests.h"
#include "../eventhelpers.h"
namespace VSTGUI {
TEST_CASE (CSegmentButtonTest, AddSegment)
{
CSegmentButton b (CRect (0, 0, 10, 10));
EXPECT (b.getSegments ().size () == 0);
CSegmentButton::Segment s;
s.name = "1";
b.addSegment (s);
EXPECT (b.getSegments ().size () == 1);
s.name = "2";
b.addSegment (s);
EXPECT (b.getSegments ().size () == 2);
EXPECT (b.getSegments ()[1].name == "2");
s.name = "3";
b.addSegment (s, 0);
EXPECT (b.getSegments ().size () == 3);
EXPECT (b.getSegments ()[0].name == "3");
EXPECT (b.getSegments ()[1].name == "1");
EXPECT (b.getSegments ()[2].name == "2");
}
TEST_CASE (CSegmentButtonTest, InsertSegment)
{
CSegmentButton b (CRect (0, 0, 10, 10));
CSegmentButton::Segment s;
s.name = "0";
b.addSegment (std::move (s));
s.name = "1";
b.addSegment (std::move (s), 0);
EXPECT (b.getSegments ()[0].name == "1");
EXPECT (b.getSegments ()[1].name == "0");
}
TEST_CASE (CSegmentButtonTest, RemoveSegment)
{
CSegmentButton b (CRect (0, 0, 10, 10));
CSegmentButton::Segment s;
s.name = "0";
b.addSegment (s);
s.name = "1";
b.addSegment (s);
s.name = "2";
b.addSegment (s);
s.name = "3";
b.addSegment (s);
EXPECT (b.getSegments ().size () == 4);
b.removeSegment (0);
EXPECT (b.getSegments ().size () == 3);
EXPECT (b.getSegments ()[0].name == "1");
EXPECT (b.getSegments ()[1].name == "2");
EXPECT (b.getSegments ()[2].name == "3");
}
TEST_CASE (CSegmentButtonTest, SelectedSegment)
{
CSegmentButton b (CRect (0, 0, 10, 10));
CSegmentButton::Segment s;
s.name = "0";
b.addSegment (s);
s.name = "1";
b.addSegment (s);
s.name = "2";
b.addSegment (s);
s.name = "3";
b.addSegment (s);
b.setSelectedSegment (1);
EXPECT (b.getSelectedSegment () == 1);
b.setSelectedSegment (2);
EXPECT (b.getSelectedSegment () == 2);
b.setSelectedSegment (3);
EXPECT (b.getSelectedSegment () == 3);
b.setSelectedSegment (4);
EXPECT (b.getSelectedSegment () == 3);
b.setSelectedSegment (0);
EXPECT (b.getSelectedSegment () == 0);
}
TEST_CASE (CSegmentButtonTest, RightKeyEvent)
{
CSegmentButton b (CRect (0, 0, 10, 10));
CSegmentButton::Segment s;
s.name = "0";
b.addSegment (s);
s.name = "1";
b.addSegment (s);
s.name = "2";
b.addSegment (s);
b.setStyle (CSegmentButton::Style::kHorizontal);
b.setSelectedSegment (0);
KeyboardEvent event;
event.virt = VirtualKey::Right;
b.onKeyboardEvent (event);
EXPECT_TRUE (event.consumed);
EXPECT (b.getSelectedSegment () == 1);
event.consumed.reset ();
b.onKeyboardEvent (event);
EXPECT_TRUE (event.consumed);
EXPECT (b.getSelectedSegment () == 2);
event.consumed.reset ();
b.onKeyboardEvent (event);
EXPECT_TRUE (event.consumed);
EXPECT (b.getSelectedSegment () == 2);
b.setSelectedSegment (1);
b.setStyle (CSegmentButton::Style::kVertical);
event.consumed.reset ();
b.onKeyboardEvent (event);
EXPECT_TRUE (event.consumed);
EXPECT (b.getSelectedSegment () == 1);
event.consumed.reset ();
b.onKeyboardEvent (event);
EXPECT_TRUE (event.consumed);
EXPECT (b.getSelectedSegment () == 1);
}
TEST_CASE (CSegmentButtonTest, LeftKeyEvent)
{
CSegmentButton b (CRect (0, 0, 10, 10));
CSegmentButton::Segment s;
s.name = "0";
b.addSegment (s);
s.name = "1";
b.addSegment (s);
s.name = "2";
b.addSegment (s);
b.setStyle (CSegmentButton::Style::kHorizontal);
b.setSelectedSegment (2);
KeyboardEvent event;
event.virt = VirtualKey::Left;
b.onKeyboardEvent (event);
EXPECT_TRUE (event.consumed);
EXPECT (b.getSelectedSegment () == 1);
event.consumed.reset ();
b.onKeyboardEvent (event);
EXPECT_TRUE (event.consumed);
EXPECT (b.getSelectedSegment () == 0);
event.consumed.reset ();
b.onKeyboardEvent (event);
EXPECT_TRUE (event.consumed);
EXPECT (b.getSelectedSegment () == 0);
b.setSelectedSegment (1);
b.setStyle (CSegmentButton::Style::kVertical);
event.consumed.reset ();
b.onKeyboardEvent (event);
EXPECT_TRUE (event.consumed);
EXPECT (b.getSelectedSegment () == 1);
event.consumed.reset ();
b.onKeyboardEvent (event);
EXPECT_TRUE (event.consumed);
EXPECT (b.getSelectedSegment () == 1);
}
TEST_CASE (CSegmentButtonTest, DownKeyEvent)
{
CSegmentButton b (CRect (0, 0, 10, 10));
CSegmentButton::Segment s;
s.name = "0";
b.addSegment (s);
s.name = "1";
b.addSegment (s);
s.name = "2";
b.addSegment (s);
b.setStyle (CSegmentButton::Style::kVertical);
b.setSelectedSegment (0);
KeyboardEvent event;
event.virt = VirtualKey::Down;
b.onKeyboardEvent (event);
EXPECT_TRUE (event.consumed);
EXPECT (b.getSelectedSegment () == 1);
event.consumed.reset ();
b.onKeyboardEvent (event);
EXPECT_TRUE (event.consumed);
EXPECT (b.getSelectedSegment () == 2);
event.consumed.reset ();
b.onKeyboardEvent (event);
EXPECT_TRUE (event.consumed);
EXPECT (b.getSelectedSegment () == 2);
b.setSelectedSegment (1);
b.setStyle (CSegmentButton::Style::kHorizontal);
event.consumed.reset ();
b.onKeyboardEvent (event);
EXPECT_TRUE (event.consumed);
EXPECT (b.getSelectedSegment () == 1);
event.consumed.reset ();
b.onKeyboardEvent (event);
EXPECT_TRUE (event.consumed);
EXPECT (b.getSelectedSegment () == 1);
}
TEST_CASE (CSegmentButtonTest, UpKeyEvent)
{
CSegmentButton b (CRect (0, 0, 10, 10));
CSegmentButton::Segment s;
s.name = "0";
b.addSegment (s);
s.name = "1";
b.addSegment (s);
s.name = "2";
b.addSegment (s);
b.setStyle (CSegmentButton::Style::kVertical);
b.setSelectedSegment (2);
KeyboardEvent event;
event.virt = VirtualKey::Up;
b.onKeyboardEvent (event);
EXPECT_TRUE (event.consumed);
EXPECT (b.getSelectedSegment () == 1);
event.consumed.reset ();
b.onKeyboardEvent (event);
EXPECT_TRUE (event.consumed);
EXPECT (b.getSelectedSegment () == 0);
event.consumed.reset ();
b.onKeyboardEvent (event);
EXPECT_TRUE (event.consumed);
EXPECT (b.getSelectedSegment () == 0);
b.setSelectedSegment (1);
b.setStyle (CSegmentButton::Style::kHorizontal);
event.consumed.reset ();
b.onKeyboardEvent (event);
EXPECT_TRUE (event.consumed);
EXPECT (b.getSelectedSegment () == 1);
event.consumed.reset ();
b.onKeyboardEvent (event);
EXPECT_TRUE (event.consumed);
EXPECT (b.getSelectedSegment () == 1);
}
TEST_CASE (CSegmentButtonTest, HorizontalSegmentSizeCalculation)
{
const auto numSegments = 5;
CRect r (0, 0, 100, 100);
auto b = new CSegmentButton (r);
b->setStyle (CSegmentButton::Style::kHorizontal);
for (auto i = 0; i < numSegments; ++i)
b->addSegment ({});
for (const auto& s : b->getSegments ())
EXPECT (s.rect == CRect (0, 0, 0, 0));
auto root = owned (new CViewContainer (r));
auto parent = new CViewContainer (r);
root->addView (parent);
parent->addView (b);
parent->attached (root);
EXPECT (b->getSegments ()[0].rect == CRect (0, 0, 20, 100));
EXPECT (b->getSegments ()[1].rect == CRect (20, 0, 40, 100));
EXPECT (b->getSegments ()[2].rect == CRect (40, 0, 60, 100));
EXPECT (b->getSegments ()[3].rect == CRect (60, 0, 80, 100));
EXPECT (b->getSegments ()[4].rect == CRect (80, 0, 100, 100));
parent->removed (root);
}
TEST_CASE (CSegmentButtonTest, VerticalSegmentSizeCalculation)
{
const auto numSegments = 5;
CRect r (0, 0, 100, 100);
auto b = new CSegmentButton (r);
b->setStyle (CSegmentButton::Style::kVertical);
for (auto i = 0; i < numSegments; ++i)
b->addSegment ({});
for (const auto& s : b->getSegments ())
EXPECT (s.rect == CRect (0, 0, 0, 0));
auto root = owned (new CViewContainer (r));
auto parent = new CViewContainer (r);
root->addView (parent);
parent->addView (b);
parent->attached (root);
EXPECT (b->getSegments ()[0].rect == CRect (0, 0, 100, 20));
EXPECT (b->getSegments ()[1].rect == CRect (0, 20, 100, 40));
EXPECT (b->getSegments ()[2].rect == CRect (0, 40, 100, 60));
EXPECT (b->getSegments ()[3].rect == CRect (0, 60, 100, 80));
EXPECT (b->getSegments ()[4].rect == CRect (0, 80, 100, 100));
parent->removed (root);
}
TEST_CASE (CSegmentButtonTest, UpdateViewSize)
{
const auto numSegments = 5;
auto b = new CSegmentButton (CRect (0, 0, 50, 100));
b->setStyle (CSegmentButton::Style::kHorizontal);
for (auto i = 0; i < numSegments; ++i)
b->addSegment ({});
for (const auto& s : b->getSegments ())
EXPECT (s.rect == CRect (0, 0, 0, 0));
CRect r (0, 0, 100, 100);
auto root = owned (new CViewContainer (r));
auto parent = new CViewContainer (r);
root->addView (parent);
parent->addView (b);
parent->attached (root);
EXPECT (b->getSegments ()[0].rect == CRect (0, 0, 10, 100));
EXPECT (b->getSegments ()[1].rect == CRect (10, 0, 20, 100));
EXPECT (b->getSegments ()[2].rect == CRect (20, 0, 30, 100));
EXPECT (b->getSegments ()[3].rect == CRect (30, 0, 40, 100));
EXPECT (b->getSegments ()[4].rect == CRect (40, 0, 50, 100));
b->setViewSize (r);
EXPECT (b->getSegments ()[0].rect == CRect (0, 0, 20, 100));
EXPECT (b->getSegments ()[1].rect == CRect (20, 0, 40, 100));
EXPECT (b->getSegments ()[2].rect == CRect (40, 0, 60, 100));
EXPECT (b->getSegments ()[3].rect == CRect (60, 0, 80, 100));
EXPECT (b->getSegments ()[4].rect == CRect (80, 0, 100, 100));
parent->removed (root);
}
TEST_CASE (CSegmentButtonTest, MouseDownEvent)
{
const auto numSegments = 5;
CRect r (0, 0, 100, 100);
auto b = new CSegmentButton (r);
b->setStyle (CSegmentButton::Style::kHorizontal);
for (auto i = 0; i < numSegments; ++i)
b->addSegment ({});
for (const auto& s : b->getSegments ())
EXPECT (s.rect == CRect (0, 0, 0, 0));
auto root = owned (new CViewContainer (r));
auto parent = new CViewContainer (r);
root->addView (parent);
parent->addView (b);
parent->attached (root);
EXPECT_EQ (dispatchMouseEvent<MouseDownEvent> (b, {0., 0.}, MouseButton::Left),
EventConsumeState::Handled | MouseDownUpMoveEvent::IgnoreFollowUpEventsMask);
EXPECT_EQ (b->getSelectedSegment (), 0);
EXPECT_EQ (dispatchMouseEvent<MouseDownEvent> (b, {25., 0.}, MouseButton::Left),
EventConsumeState::Handled | MouseDownUpMoveEvent::IgnoreFollowUpEventsMask);
EXPECT_EQ (b->getSelectedSegment (), 1);
EXPECT_EQ (dispatchMouseEvent<MouseDownEvent> (b, {45., 0.}, MouseButton::Left),
EventConsumeState::Handled | MouseDownUpMoveEvent::IgnoreFollowUpEventsMask);
EXPECT_EQ (b->getSelectedSegment (), 2);
EXPECT_EQ (dispatchMouseEvent<MouseDownEvent> (b, {65., 0.}, MouseButton::Left),
EventConsumeState::Handled | MouseDownUpMoveEvent::IgnoreFollowUpEventsMask);
EXPECT_EQ (b->getSelectedSegment (), 3);
EXPECT_EQ (dispatchMouseEvent<MouseDownEvent> (b, {85., 0.}, MouseButton::Left),
EventConsumeState::Handled | MouseDownUpMoveEvent::IgnoreFollowUpEventsMask);
EXPECT_EQ (b->getSelectedSegment (), 4);
parent->removed (root);
}
TEST_CASE (CSegmentButtonTest, MouseDownEventWithManySegments)
{
// Create segment button with 32 segments and attach it
const auto numSegments = 32;
CRect r (0, 0, 20 * numSegments, 100);
auto b = new CSegmentButton (r);
b->setStyle (CSegmentButton::Style::kHorizontal);
for (auto i = 0; i < numSegments; ++i)
b->addSegment ({});
for (const auto& s : b->getSegments ())
EXPECT_EQ (s.rect, CRect (0, 0, 0, 0));
auto root = owned (new CViewContainer (r));
auto parent = new CViewContainer (r);
root->addView (parent);
parent->addView (b);
parent->attached (root);
// Select the e.g. 20th segment
constexpr auto kSelectedSegment = 20;
CPoint p (20 * kSelectedSegment + 5, 0);
EXPECT_EQ (dispatchMouseEvent<MouseDownEvent> (b, p, MouseButton::Left),
EventConsumeState::Handled | MouseDownUpMoveEvent::IgnoreFollowUpEventsMask);
EXPECT_EQ (b->getSelectedSegment (), kSelectedSegment);
parent->removed (root);
}
TEST_CASE (CSegmentButtonTest, MouseDownEventOnLastSegment)
{
// Create segment button with 31 segments and attach it.
// 31 segments causing rounding errors inside segment button.
const auto numSegments = 31;
CRect r (0, 0, 20 * numSegments, 100);
auto b = new CSegmentButton (r);
b->setStyle (CSegmentButton::Style::kHorizontal);
for (auto i = 0; i < numSegments; ++i)
b->addSegment ({});
for (const auto& s : b->getSegments ())
EXPECT_EQ (s.rect, CRect (0, 0, 0, 0));
auto root = owned (new CViewContainer (r));
auto parent = new CViewContainer (r);
root->addView (parent);
parent->addView (b);
parent->attached (root);
// Select the last segment
constexpr auto kSelectedSegment = numSegments - 1;
CPoint p (0, 0);
p (20 * kSelectedSegment + 5, 0);
EXPECT_EQ (dispatchMouseEvent<MouseDownEvent> (b, p, MouseButton::Left),
EventConsumeState::Handled | MouseDownUpMoveEvent::IgnoreFollowUpEventsMask);
EXPECT_EQ (b->getSelectedSegment (), kSelectedSegment);
parent->removed (root);
}
TEST_CASE (CSegmentButtonTest, FocusPathSetting)
{
CSegmentButton b (CRect (0, 0, 10, 10));
EXPECT (b.drawFocusOnTop () == false);
}
TEST_CASE (CSegmentButtonTest, MultiSelection)
{
CSegmentButton b (CRect (0, 0, 10, 10));
b.setSelectionMode (CSegmentButton::SelectionMode::kMultiple);
b.addSegment ({});
b.addSegment ({});
b.addSegment ({});
b.selectSegment (0, true);
b.selectSegment (1, false);
b.selectSegment (2, true);
EXPECT (b.isSegmentSelected (0) == true);
EXPECT (b.isSegmentSelected (1) == false);
EXPECT (b.isSegmentSelected (2) == true);
}
TEST_CASE (CSegmentButtonTest, MultiSelectionMaxEntries)
{
CSegmentButton b (CRect (0, 0, 10, 10));
b.setSelectionMode (CSegmentButton::SelectionMode::kMultiple);
CSegmentButton::Segment s;
for (auto i = 0; i < 32; ++i)
{
EXPECT (b.addSegment (s) == true);
}
EXPECT (b.addSegment (s) == false);
EXPECT (b.addSegment (std::move (s)) == false);
}
} // VSTGUI
@@ -0,0 +1,151 @@
// This file is part of VSTGUI. It is subject to the license terms
// in the LICENSE file found in the top-level directory of this
// distribution and at http://github.com/steinbergmedia/vstgui/LICENSE
#include "../../../../lib/controls/cbuttons.h"
#include "../../unittests.h"
#include "../eventhelpers.h"
namespace VSTGUI {
TEST_CASE (CTextButtonTest, MouseEventsKickStyle)
{
auto b = owned (new CTextButton (CRect (10, 10, 50, 20)));
b->setStyle (CTextButton::kKickStyle);
b->setValue (b->getMin ());
EXPECT_EQ (dispatchMouseEvent<MouseDownEvent> (b, {10., 10.}, MouseButton::Right),
EventConsumeState::NotHandled);
EXPECT_FALSE (b->isEditing ());
EXPECT_EQ (dispatchMouseEvent<MouseDownEvent> (b, {10., 10.}, MouseButton::Left),
EventConsumeState::Handled);
EXPECT_TRUE (b->isEditing ());
EXPECT_EQ (b->getValue (), b->getMax ());
EXPECT_EQ (dispatchMouseEvent<MouseMoveEvent> (b, {10., 10.}, MouseButton::Left),
EventConsumeState::Handled);
EXPECT_TRUE (b->isEditing ());
EXPECT_EQ (b->getValue (), b->getMax ());
EXPECT_EQ (dispatchMouseEvent<MouseUpEvent> (b, {10., 10.}, MouseButton::Left),
EventConsumeState::Handled);
EXPECT_FALSE (b->isEditing ());
EXPECT_EQ (b->getValue (), b->getMin ());
EXPECT_EQ (dispatchMouseEvent<MouseDownEvent> (b, {10., 10.}, MouseButton::Left),
EventConsumeState::Handled);
EXPECT_TRUE (b->isEditing ());
EXPECT_EQ (dispatchMouseEvent<MouseUpEvent> (b, {10., 10.}, MouseButton::Left),
EventConsumeState::Handled);
EXPECT_FALSE (b->isEditing ());
EXPECT_EQ (b->getValue (), b->getMin ());
EXPECT_EQ (dispatchMouseEvent<MouseDownEvent> (b, {10., 10.}, MouseButton::Left),
EventConsumeState::Handled);
EXPECT_TRUE (b->isEditing ());
EXPECT_EQ (dispatchMouseEvent<MouseUpEvent> (b, {0., 0.}, MouseButton::Left),
EventConsumeState::Handled);
EXPECT_FALSE (b->isEditing ());
EXPECT_EQ (b->getValue (), b->getMin ());
EXPECT_EQ (dispatchMouseEvent<MouseDownEvent> (b, {10., 10.}, MouseButton::Left),
EventConsumeState::Handled);
EXPECT_TRUE (b->isEditing ());
EXPECT_EQ (dispatchMouseCancelEvent (b), EventConsumeState::Handled);
EXPECT_FALSE (b->isEditing ());
EXPECT_EQ (dispatchMouseEvent<MouseMoveEvent> (b, {10., 10.}, MouseButton::Left),
EventConsumeState::NotHandled);
}
TEST_CASE (CTextButtonTest, MouseEventsOnOffStyle)
{
auto b = owned (new CTextButton (CRect (10, 10, 50, 20)));
b->setStyle (CTextButton::kOnOffStyle);
b->setValue (b->getMin ());
EXPECT_EQ (dispatchMouseEvent<MouseDownEvent> (b, {10., 10.}, MouseButton::Right),
EventConsumeState::NotHandled);
EXPECT_FALSE (b->isEditing ());
EXPECT_EQ (dispatchMouseEvent<MouseDownEvent> (b, {10., 10.}, MouseButton::Left),
EventConsumeState::Handled);
EXPECT_TRUE (b->isEditing ());
EXPECT_EQ (b->getValue (), b->getMax ());
EXPECT_EQ (dispatchMouseEvent<MouseMoveEvent> (b, {10., 10.}, MouseButton::Left),
EventConsumeState::Handled);
EXPECT_TRUE (b->isEditing ());
EXPECT_EQ (b->getValue (), b->getMax ());
EXPECT_EQ (dispatchMouseEvent<MouseUpEvent> (b, {10., 10.}, MouseButton::Left),
EventConsumeState::Handled);
EXPECT_FALSE (b->isEditing ());
EXPECT_EQ (b->getValue (), b->getMax ());
EXPECT_EQ (dispatchMouseEvent<MouseDownEvent> (b, {10., 10.}, MouseButton::Left),
EventConsumeState::Handled);
EXPECT_TRUE (b->isEditing ());
EXPECT_EQ (dispatchMouseEvent<MouseUpEvent> (b, {10., 10.}, MouseButton::Left),
EventConsumeState::Handled);
EXPECT_FALSE (b->isEditing ());
EXPECT_EQ (b->getValue (), b->getMin ());
EXPECT_EQ (dispatchMouseEvent<MouseDownEvent> (b, {10., 10.}, MouseButton::Left),
EventConsumeState::Handled);
EXPECT_TRUE (b->isEditing ());
EXPECT_EQ (dispatchMouseEvent<MouseMoveEvent> (b, {0., 0.}, MouseButton::Left),
EventConsumeState::Handled);
EXPECT_EQ (b->getValue (), b->getMin ());
EXPECT_EQ (dispatchMouseEvent<MouseUpEvent> (b, {0., 0.}, MouseButton::Left),
EventConsumeState::Handled);
EXPECT_FALSE (b->isEditing ());
EXPECT_EQ (b->getValue (), b->getMin ());
EXPECT_EQ (dispatchMouseEvent<MouseDownEvent> (b, {10., 10.}, MouseButton::Left),
EventConsumeState::Handled);
EXPECT_TRUE (b->isEditing ());
EXPECT_EQ (dispatchMouseCancelEvent (b), EventConsumeState::Handled);
EXPECT_FALSE (b->isEditing ());
EXPECT_EQ (dispatchMouseEvent<MouseMoveEvent> (b, {10., 10.}, MouseButton::Left),
EventConsumeState::NotHandled);
}
TEST_CASE (CTextButtonTest, KeyEvents)
{
auto b = owned (new CTextButton (CRect (10, 10, 50, 20)));
b->setStyle (CTextButton::kOnOffStyle);
b->setValue (b->getMin ());
KeyboardEvent retEvent;
retEvent.virt = VirtualKey::Return;
b->onKeyboardEvent (retEvent);
EXPECT_TRUE (retEvent.consumed);
EXPECT_EQ (b->getValue (), b->getMax ());
retEvent.consumed.reset ();
b->onKeyboardEvent (retEvent);
EXPECT_TRUE (retEvent.consumed);
EXPECT_EQ (b->getValue (), b->getMin ());
KeyboardEvent charEvent;
charEvent.character = 't';
b->onKeyboardEvent (charEvent);
EXPECT_FALSE (charEvent.consumed);
b->setStyle (CTextButton::kKickStyle);
retEvent.consumed.reset ();
b->onKeyboardEvent (retEvent);
EXPECT_TRUE (retEvent.consumed);
EXPECT_EQ (b->getValue (), b->getMin ());
retEvent.consumed.reset ();
b->onKeyboardEvent (retEvent);
EXPECT_TRUE (retEvent.consumed);
EXPECT_EQ (b->getValue (), b->getMin ());
KeyboardEvent upEvent;
upEvent.type = EventType::KeyUp;
upEvent.virt = VirtualKey::Return;
b->onKeyboardEvent (upEvent);
EXPECT_FALSE (upEvent.consumed);
}
TEST_CASE (CTextButtonTest, FocusPathSetting)
{
auto b = owned (new CTextButton (CRect (10, 10, 50, 20)));
EXPECT_FALSE (b->drawFocusOnTop ());
}
} // VSTGUI
@@ -0,0 +1,125 @@
// This file is part of VSTGUI. It is subject to the license terms
// in the LICENSE file found in the top-level directory of this
// distribution and at http://github.com/steinbergmedia/vstgui/LICENSE
#include "../../../../lib/controls/cxypad.h"
#include "../../unittests.h"
#include "../eventhelpers.h"
namespace VSTGUI {
TEST_CASE (CXYPadTest, valueCalculation)
{
auto value = CXYPad::calculateValue (0.f, 0.f);
float x = 1.f;
float y = 1.f;
CXYPad::calculateXY (value, x, y);
EXPECT (x == 0.f);
EXPECT (y == 0.f);
value = CXYPad::calculateValue (1.f, 0.f);
CXYPad::calculateXY (value, x, y);
EXPECT (x == 1.f);
EXPECT (y == 0.f);
value = CXYPad::calculateValue (0.f, 1.f);
CXYPad::calculateXY (value, x, y);
EXPECT (x == 0.f);
EXPECT (y == 1.f);
value = CXYPad::calculateValue (0.5f, 0.5f);
CXYPad::calculateXY (value, x, y);
EXPECT (x == 0.5f);
EXPECT (y == 0.5f);
value = CXYPad::calculateValue (0.25f, 0.25f);
CXYPad::calculateXY (value, x, y);
EXPECT (x == 0.25f);
EXPECT (y == 0.25f);
}
TEST_CASE (CXYPadTest, MouseLeftDownInteraction)
{
CXYPad pad (CRect (0, 0, 100, 100));
pad.setRoundRectRadius (0.f);
dispatchMouseEvent<MouseDownEvent> (&pad, {0., 0.}, MouseButton::Left);
dispatchMouseEvent<MouseMoveEvent> (&pad, {10., 10.}, MouseButton::Left);
float x = 1.f;
float y = 1.f;
pad.calculateXY (pad.getValue (), x, y);
EXPECT (x == 0.1f);
EXPECT (y == 0.1f);
dispatchMouseEvent<MouseMoveEvent> (&pad, {110., 110.}, MouseButton::Left);
pad.calculateXY (pad.getValue (), x, y);
EXPECT (x == 1.f);
EXPECT (y == 1.f);
dispatchMouseEvent<MouseMoveEvent> (&pad, {-10., -10.}, MouseButton::Left);
pad.calculateXY (pad.getValue (), x, y);
EXPECT (x == 0.f);
EXPECT (y == 0.f);
dispatchMouseEvent<MouseUpEvent> (&pad, {-10., -10.}, MouseButton::Left);
EXPECT_FALSE(pad.isEditing ());
}
TEST_CASE (CXYPadTest, CancelMouseInteraction)
{
CXYPad pad (CRect (0, 0, 100, 100));
float startX {-1.f};
float startY {-1.f};
pad.calculateXY (pad.getValue (), startX, startY);
dispatchMouseEvent<MouseDownEvent> (&pad, {0., 0.}, MouseButton::Left);
dispatchMouseEvent<MouseMoveEvent> (&pad, {10., 10.}, MouseButton::Left);
float x {-1.f};
float y {-1.f};
pad.calculateXY (pad.getValue (), x, y);
EXPECT (startX != x);
EXPECT (startY != y);
dispatchMouseCancelEvent (&pad);
pad.calculateXY (pad.getValue (), x, y);
EXPECT (startX == x);
EXPECT (startY == y);
}
TEST_CASE (CXYPadTest, OtherMouseInteraction)
{
CXYPad pad (CRect (0, 0, 100, 100));
EXPECT_EQ (dispatchMouseEvent<MouseDownEvent> (&pad, {0., 0.}, MouseButton::Right),
EventConsumeState::NotHandled);
EXPECT_EQ (dispatchMouseEvent<MouseMoveEvent> (&pad, {0., 0.}, MouseButton::Right),
EventConsumeState::NotHandled);
EXPECT_EQ (dispatchMouseEvent<MouseUpEvent> (&pad, {0., 0.}, MouseButton::Right),
EventConsumeState::NotHandled);
}
TEST_CASE (CXYPadTest, StopTrackingOnMouseExit)
{
CXYPad pad (CRect (0, 0, 100, 100));
pad.setStopTrackingOnMouseExit (true);
pad.setRoundRectRadius (0.f);
EXPECT_EQ (dispatchMouseEvent<MouseDownEvent> (&pad, {0., 0.}, MouseButton::Left),
EventConsumeState::Handled);
EXPECT_TRUE (pad.isEditing ());
EXPECT_EQ (dispatchMouseEvent<MouseDownEvent> (&pad, {50., 50.}, MouseButton::Left),
EventConsumeState::Handled);
EXPECT_TRUE (pad.isEditing ());
EXPECT_EQ (dispatchMouseEvent<MouseDownEvent> (&pad, {150., 150.}, MouseButton::Left),
EventConsumeState::Handled | MouseDownUpMoveEvent::IgnoreFollowUpEventsMask);
EXPECT_FALSE (pad.isEditing ());
}
TEST_CASE (CXYPadTest, MouseWheel)
{
CXYPad pad (CRect (0, 0, 100, 100));
float x = 1.f;
float y = 1.f;
CXYPad::calculateXY (pad.getValue (), x, y);
EXPECT (x == 0.f && y == 0.f);
dispatchMouseWheelEvent (&pad, {1., 1.}, 1., 0.);
CXYPad::calculateXY (pad.getValue (), x, y);
EXPECT (x == pad.getWheelInc () && y == 0.f);
dispatchMouseWheelEvent (&pad, {1., 1.}, 0., 1.);
CXYPad::calculateXY (pad.getValue (), x, y);
EXPECT (x == pad.getWheelInc () && y == pad.getWheelInc ());
}
} // VSTGUI
@@ -0,0 +1,97 @@
// This file is part of VSTGUI. It is subject to the license terms
// in the LICENSE file found in the top-level directory of this
// distribution and at http://github.com/steinbergmedia/vstgui/LICENSE
#include "../../../lib/cpoint.h"
#include "../unittests.h"
namespace VSTGUI {
TEST_CASE (CPointTest, Unequal)
{
EXPECT (CPoint (0, 0) != CPoint (1, 1));
EXPECT (CPoint (0, 0) != CPoint (0, 1));
EXPECT (CPoint (0, 0) != CPoint (1, 0));
}
TEST_CASE (CPointTest, Equal)
{
EXPECT (CPoint (0, 0) == CPoint (0, 0));
}
TEST_CASE (CPointTest, OperatorAddAssign)
{
CPoint p (1, 1);
p += CPoint (1, 1);
EXPECT (p == CPoint (2, 2));
}
TEST_CASE (CPointTest, OperatorSubtractAssign)
{
CPoint p (2, 2);
p -= CPoint (1, 1);
EXPECT (p == CPoint (1, 1));
}
TEST_CASE (CPointTest, OperatorAdd)
{
CPoint p (2, 2);
auto p2 = p + CPoint (1, 1);
EXPECT (p2 == CPoint (3, 3));
EXPECT (p == CPoint (2, 2));
}
TEST_CASE (CPointTest, OperatorSubtract)
{
CPoint p (2, 2);
auto p2 = p - CPoint (1, 1);
EXPECT (p2 == CPoint (1, 1));
EXPECT (p == CPoint (2, 2));
}
TEST_CASE (CPointTest, OperatorInverse)
{
CPoint p (2, 2);
auto p2 = -p;
EXPECT (p2 == CPoint (-2, -2));
EXPECT (p == CPoint (2, 2));
}
TEST_CASE (CPointTest, OffsetCoords)
{
CPoint p (1, 2);
p.offset (1, 2);
EXPECT (p == CPoint (2, 4));
}
TEST_CASE (CPointTest, OffsetPoint)
{
CPoint p (1, 2);
p.offset (CPoint (2, 3));
EXPECT (p == CPoint (3, 5));
}
TEST_CASE (CPointTest, OffsetInverse)
{
CPoint p (5, 3);
p.offsetInverse (CPoint (2, 1));
EXPECT (p == CPoint (3, 2));
}
TEST_CASE (CPointTest, MakeIntegral)
{
CPoint p (5.3, 4.2);
p.makeIntegral ();
EXPECT (p == CPoint (5, 4));
p (5.5, 4.5);
p.makeIntegral ();
EXPECT (p == CPoint (6, 5));
p (5.9, 4.1);
p.makeIntegral ();
EXPECT (p == CPoint (6, 4));
p (5.1, 4.501);
p.makeIntegral ();
EXPECT (p == CPoint (5, 5));
}
} // VSTGUI
@@ -0,0 +1,225 @@
// This file is part of VSTGUI. It is subject to the license terms
// in the LICENSE file found in the top-level directory of this
// distribution and at http://github.com/steinbergmedia/vstgui/LICENSE
#include "../../../lib/crect.h"
#include "../unittests.h"
namespace VSTGUI {
TEST_CASE (CRectTest, MakeIntegral)
{
CRect r (0.2, 0.5, 10.8, 12.1);
r.makeIntegral ();
EXPECT (r.left == 0.0)
EXPECT (r.top == 0.0)
EXPECT (r.right == 11.0)
EXPECT (r.bottom == 13.0)
}
TEST_CASE (CRectTest, GetCenter)
{
CRect r (0, 0, 50, 50);
CPoint p = r.getCenter ();
EXPECT (p.x == 25 && p.y == 25)
}
TEST_CASE (CRectTest, CenterInside)
{
CRect r (0, 0, 500, 500);
CRect r2 (0, 0, 10, 10);
r2.centerInside (r);
EXPECT (r2.left == 245 && r2.top == 245 && r2.getWidth () == 10 && r2.getHeight () == 10)
}
TEST_CASE (CRectTest, PointInside)
{
CRect r (0, 0, 250, 250);
CPoint p (50, 50);
EXPECT (r.pointInside (p))
}
TEST_CASE (CRectTest, PointNotInside)
{
CRect r (0, 0, 250, 250);
CPoint p (250, 50);
EXPECT (r.pointInside (p) == false)
}
TEST_CASE (CRectTest, RectOverlap)
{
CRect r (50, 50, 100, 100);
CRect r2 (90, 90, 120, 120);
EXPECT (r.rectOverlap (r2))
}
TEST_CASE (CRectTest, RectNotOverlap)
{
CRect r (50, 50, 100, 100);
CRect r2 (100, 101, 120, 120);
CRect r3 (101, 100, 120, 120);
CRect r4 (0, 0, 40, 40);
CRect r5 (51, 51, 100, 40);
EXPECT (r.rectOverlap (r2) == false)
EXPECT (r.rectOverlap (r3) == false)
EXPECT (r.rectOverlap (r4) == false)
EXPECT (r.rectOverlap (r5) == false)
}
TEST_CASE (CRectTest, Bound)
{
CRect r (50, 50, 100, 100);
CRect r2 (90, 90, 200, 200);
r.bound (r2);
EXPECT (r.left == 90 && r.top == 90 && r.right == 100 && r.bottom == 100)
r (0, 0, 80, 80);
r.bound (r2);
EXPECT (r.left == 90 && r.top == 90 && r.right == 90 && r.bottom == 90)
r (0, 0, 280, 280);
r.bound (r2);
EXPECT (r.left == 90 && r.top == 90 && r.right == 200 && r.bottom == 200)
}
TEST_CASE (CRectTest, Unite)
{
CRect r (20, 20, 40, 40);
CRect r2 (40, 40, 80, 80);
r.unite (r2);
EXPECT (r.left == 20 && r.top == 20 && r.right == 80 && r.bottom == 80)
r (50, 50, 120, 120);
r.unite (r2);
EXPECT (r.left == 40 && r.top == 40 && r.right == 120 && r.bottom == 120)
}
TEST_CASE (CRectTest, SetWidth)
{
CRect r (0., 0., 0., 0.);
EXPECT (r.getWidth () == 0.);
r.setWidth (100.);
EXPECT (r.getWidth () == 100.);
}
TEST_CASE (CRectTest, setHeight)
{
CRect r (0., 0., 0., 0.);
EXPECT (r.getHeight () == 0.);
r.setHeight (100.);
EXPECT (r.getHeight () == 100.);
}
TEST_CASE (CRectTest, Offset)
{
CRect r (0, 0, 10, 10);
r.offset (CPoint (5, 5));
EXPECT (r.left == 5 && r.top == 5 && r.right == 15 && r.bottom == 15);
}
TEST_CASE (CRectTest, OffsetInverse)
{
CRect r (10, 10, 20, 20);
r.offsetInverse (CPoint (5, 5));
EXPECT (r.left == 5 && r.top == 5 && r.right == 15 && r.bottom == 15);
}
TEST_CASE (CRectTest, Extend)
{
CRect r (5, 5, 10, 10);
r.extend (CPoint (5, 5));
EXPECT (r.left == 0 && r.top == 0 && r.right == 15 && r.bottom == 15);
}
TEST_CASE (CRectTest, Assign4CoordOperator)
{
CRect r;
r (0, 0, 15, 15);
EXPECT (r.left == 0 && r.top == 0 && r.right == 15 && r.bottom == 15);
r (15, 15, 0, 0);
EXPECT (r.left == 0 && r.top == 0 && r.right == 15 && r.bottom == 15);
}
TEST_CASE (CRectTest, OriginSizeConstructor)
{
CRect r (CPoint (10, 10), CPoint (10, 10));
EXPECT (r.left == 10 && r.top == 10 && r.right == 20 && r.bottom == 20);
}
TEST_CASE (CRectTest, Inset)
{
CRect r (0., 0., 100., 100.);
r.inset (CPoint (5, 5));
EXPECT (r.left == 5.);
EXPECT (r.top == 5.);
EXPECT (r.right == 95.);
EXPECT (r.bottom == 95.);
}
TEST_CASE (CRectTest, Normalize)
{
CRect r (50, 50, 0, 0);
r.normalize ();
EXPECT (r.left == 0 && r.top == 0 && r.right == 50 && r.bottom == 50);
}
TEST_CASE (CRectTest, Originize)
{
CRect r (50, 50, 150, 150);
r.originize ();
EXPECT (r.left == 0 && r.top == 0 && r.right == 100 && r.bottom == 100);
}
TEST_CASE (CRectTest, MoveTo)
{
CRect r (0, 0, 20, 20);
r.moveTo (CPoint (20, 20));
EXPECT (r.left == 20 && r.top == 20 && r.right == 40 && r.bottom == 40);
}
TEST_CASE (CRectTest, Corners)
{
CRect r (10, 10, 20, 20);
auto topLeft = r.getTopLeft ();
EXPECT (topLeft.x == 10 && topLeft.y == 10);
auto topRight = r.getTopRight ();
EXPECT (topRight.x == 20 && topRight.y == 10);
auto bottomLeft = r.getBottomLeft ();
EXPECT (bottomLeft.x == 10 && bottomLeft.y == 20);
auto bottomRight = r.getBottomRight ();
EXPECT (bottomRight.x == 20 && bottomRight.y == 20);
}
TEST_CASE (CRectTest, SetCorners)
{
CRect r (0, 0, 0, 0);
r.setTopLeft (CPoint (10, 10));
EXPECT (r.left == 10 && r.top == 10);
r.setTopRight (CPoint (10, 10));
EXPECT (r.right == 10 && r.top == 10);
r.setBottomLeft (CPoint (10, 10));
EXPECT (r.left == 10 && r.bottom == 10);
r.setBottomRight (CPoint (10, 10));
EXPECT (r.right == 10 && r.bottom == 10);
}
TEST_CASE (CRectTest, GetSize)
{
CRect r (20, 20, 22, 22);
auto s = r.getSize ();
EXPECT (s.x == 2 && s.y == 2);
}
TEST_CASE (CRectTest, IsEmpty)
{
CRect r (1, 1, 1, 2);
EXPECT (r.isEmpty ());
r (1, 1, 2, 1);
EXPECT (r.isEmpty ());
}
TEST_CASE (CRectTest, OperatorEqual)
{
CRect r1 (0, 1, 2, 3);
CRect r2 (0, 1, 2, 3);
EXPECT (r1 == r2);
}
} // VSTGUI
@@ -0,0 +1,315 @@
// This file is part of VSTGUI. It is subject to the license terms
// in the LICENSE file found in the top-level directory of this
// distribution and at http://github.com/steinbergmedia/vstgui/LICENSE
#include "../../../lib/crowcolumnview.h"
#include "../unittests.h"
#include <vector>
#include <map>
namespace VSTGUI {
using Rects = std::vector<CRect>;
static const CRect templateSize (0., 0., 100., 100.);
static const CRect layoutSize (0., 0., 80., 80.);
// clang-format off
static const Rects childrenDefaultSizes = {
{0., 0., 10., 10.},
{0., 0., 20., 20.},
{0., 0., 30., 30.}
};
using ExpectedResults = std::map<CRowColumnView::LayoutStyle, Rects>;
static const ExpectedResults kRowLayoutChildrenResultSizes = {
{
CRowColumnView::kTopLeft, {
{0., 0., 10., 10.},
{0., 10., 20., 30.},
{0., 30., 30., 60.}
}
},
{
CRowColumnView::kTopCenter, {
{35., 0., 45., 10.},
{30., 10., 50., 30.},
{25., 30., 55., 60.}
}
},
{
CRowColumnView::kTopRight, {
{70., 0., 80., 10.},
{60., 10., 80., 30.},
{50., 30., 80., 60.}
}
},
{
CRowColumnView::kMiddleLeft, {
{0., 10., 10., 20.},
{0., 20., 20., 40.},
{0., 40., 30., 70.}
}
},
{
CRowColumnView::kMiddleCenter, {
{35., 10., 45., 20.},
{30., 20., 50., 40.},
{25., 40., 55., 70.}
}
},
{
CRowColumnView::kMiddleRight, {
{70., 10., 80., 20.},
{60., 20., 80., 40.},
{50., 40., 80., 70.}
}
},
{
CRowColumnView::kBottomLeft, {
{0., 20., 10., 30.},
{0., 30., 20., 50.},
{0., 50., 30., 80.}
}
},
{
CRowColumnView::kBottomCenter, {
{35., 20., 45., 30.},
{30., 30., 50., 50.},
{25., 50., 55., 80.}
}
},
{
CRowColumnView::kBottomRight, {
{70., 20., 80., 30.},
{60., 30., 80., 50.},
{50., 50., 80., 80.}
}
}
};
static const ExpectedResults kColumnLayoutChildrenResultSizes = {
{
CRowColumnView::kTopLeft, {
{0., 0., 10., 10.},
{10., 0., 30., 20.},
{30., 0., 60., 30.}
}
},
{
CRowColumnView::kTopCenter, {
{10., 0., 20., 10.},
{20., 0., 40., 20.},
{40., 0., 70., 30.}
}
},
{
CRowColumnView::kTopRight, {
{20., 0., 30., 10.},
{30., 0., 50., 20.},
{50., 0., 80., 30.}
}
},
{
CRowColumnView::kMiddleLeft, {
{0., 35., 10., 45.},
{10., 30., 30., 50.},
{30., 25., 60., 55.}
}
},
{
CRowColumnView::kMiddleCenter, {
{10., 35., 20., 45.},
{20., 30., 40., 50.},
{40., 25., 70., 55.}
}
},
{
CRowColumnView::kMiddleRight, {
{20., 35., 30., 45.},
{30., 30., 50., 50.},
{50., 25., 80., 55.}
}
},
{
CRowColumnView::kBottomLeft, {
{0., 70., 10., 80.},
{10., 60., 30., 80.},
{30., 50., 60., 80.}
}
},
{
CRowColumnView::kBottomCenter, {
{10., 70., 20., 80.},
{20., 60., 40., 80.},
{40., 50., 70., 80.}
}
},
{
CRowColumnView::kBottomRight, {
{20., 70., 30., 80.},
{30., 60., 50., 80.},
{50., 50., 80., 80.}
}
}
};
static const ExpectedResults kRowLayoutChildrenResultSizesWithSpacing = {
{
CRowColumnView::kMiddleCenter, {
{35., 6., 45., 16.},
{30., 20., 50., 40.},
{25., 44., 55., 74.}
}
}
};
// clang-format on
struct TestData
{
CRowColumnView::LayoutStyle layoutStyle = CRowColumnView::LayoutStyle::kTopLeft;
CRowColumnView::Style style = CRowColumnView::Style::kRowStyle;
double spacing = 0.;
ExpectedResults expected;
};
auto testWithLayoutStyle (const TestData& testData) -> void
{
const auto& expected = testData.expected.find (testData.layoutStyle)->second;
auto rowColumnView = owned (new CRowColumnView (layoutSize));
rowColumnView->setStyle (testData.style);
rowColumnView->setLayoutStyle (testData.layoutStyle);
rowColumnView->setSpacing (testData.spacing);
for (auto& rect : childrenDefaultSizes)
{
auto child = new CView (rect);
rowColumnView->CViewContainer::addView (child);
rowColumnView->layoutViews ();
}
size_t i = 0;
rowColumnView->forEachChild ([&] (CView* child) {
const auto& childrenResults = testData.expected.find (testData.layoutStyle);
auto viewSize = child->getViewSize ();
EXPECT (viewSize == expected.at (i))
i++;
});
}
TEST_CASE (CRowColumnViewTest, RowLayoutTopLeftStyle)
{
testWithLayoutStyle (
{CRowColumnView::kTopLeft, CRowColumnView::kRowStyle, 0., kRowLayoutChildrenResultSizes});
}
TEST_CASE (CRowColumnViewTest, RowLayoutTopCenterStyle)
{
testWithLayoutStyle (
{CRowColumnView::kTopCenter, CRowColumnView::kRowStyle, 0., kRowLayoutChildrenResultSizes});
}
TEST_CASE (CRowColumnViewTest, RowLayoutTopRightStyle)
{
testWithLayoutStyle (
{CRowColumnView::kTopRight, CRowColumnView::kRowStyle, 0., kRowLayoutChildrenResultSizes});
}
TEST_CASE (CRowColumnViewTest, RowLayoutMiddleLeftStyle)
{
testWithLayoutStyle ({CRowColumnView::kMiddleLeft, CRowColumnView::kRowStyle, 0.,
kRowLayoutChildrenResultSizes});
}
TEST_CASE (CRowColumnViewTest, RowLayoutMiddleCenterStyle)
{
testWithLayoutStyle ({CRowColumnView::kMiddleCenter, CRowColumnView::kRowStyle, 0.,
kRowLayoutChildrenResultSizes});
}
TEST_CASE (CRowColumnViewTest, RowLayoutMiddleRightStyle)
{
testWithLayoutStyle ({CRowColumnView::kMiddleRight, CRowColumnView::kRowStyle, 0.,
kRowLayoutChildrenResultSizes});
}
TEST_CASE (CRowColumnViewTest, RowLayoutBottomLeftStyle)
{
testWithLayoutStyle ({CRowColumnView::kBottomLeft, CRowColumnView::kRowStyle, 0.,
kRowLayoutChildrenResultSizes});
}
TEST_CASE (CRowColumnViewTest, RowLayoutBottomCenterStyle)
{
testWithLayoutStyle ({CRowColumnView::kBottomCenter, CRowColumnView::kRowStyle, 0.,
kRowLayoutChildrenResultSizes});
}
TEST_CASE (CRowColumnViewTest, RowLayoutBottomRightStyle)
{
testWithLayoutStyle ({CRowColumnView::kBottomRight, CRowColumnView::kRowStyle, 0.,
kRowLayoutChildrenResultSizes});
}
TEST_CASE (CRowColumnViewTest, ColumnLayoutTopLeftStyle)
{
testWithLayoutStyle ({CRowColumnView::kTopLeft, CRowColumnView::kColumnStyle, 0.,
kColumnLayoutChildrenResultSizes});
}
TEST_CASE (CRowColumnViewTest, ColumnLayoutTopCenterStyle)
{
testWithLayoutStyle ({CRowColumnView::kTopCenter, CRowColumnView::kColumnStyle, 0.,
kColumnLayoutChildrenResultSizes});
}
TEST_CASE (CRowColumnViewTest, ColumnLayoutTopRightStyle)
{
testWithLayoutStyle ({CRowColumnView::kTopRight, CRowColumnView::kColumnStyle, 0.,
kColumnLayoutChildrenResultSizes});
}
TEST_CASE (CRowColumnViewTest, ColumnLayoutMiddleLeftStyle)
{
testWithLayoutStyle ({CRowColumnView::kMiddleLeft, CRowColumnView::kColumnStyle, 0.,
kColumnLayoutChildrenResultSizes});
}
TEST_CASE (CRowColumnViewTest, ColumnLayoutMiddleCenterStyle)
{
testWithLayoutStyle ({CRowColumnView::kMiddleCenter, CRowColumnView::kColumnStyle, 0.,
kColumnLayoutChildrenResultSizes});
}
TEST_CASE (CRowColumnViewTest, ColumnLayoutMiddleRightStyle)
{
testWithLayoutStyle ({CRowColumnView::kMiddleRight, CRowColumnView::kColumnStyle, 0.,
kColumnLayoutChildrenResultSizes});
}
TEST_CASE (CRowColumnViewTest, ColumnLayoutBottomLeftStyle)
{
testWithLayoutStyle ({CRowColumnView::kBottomLeft, CRowColumnView::kColumnStyle, 0.,
kColumnLayoutChildrenResultSizes});
}
TEST_CASE (CRowColumnViewTest, ColumnLayoutBottomCenterStyle)
{
testWithLayoutStyle ({CRowColumnView::kBottomCenter, CRowColumnView::kColumnStyle, 0.,
kColumnLayoutChildrenResultSizes});
}
TEST_CASE (CRowColumnViewTest, ColumnLayoutBottomRightStyle)
{
testWithLayoutStyle ({CRowColumnView::kBottomRight, CRowColumnView::kColumnStyle, 0.,
kColumnLayoutChildrenResultSizes});
}
TEST_CASE (CRowColumnViewTest, RowLayoutMiddleCenterStyleWithSpacing)
{
testWithLayoutStyle ({CRowColumnView::kMiddleCenter, CRowColumnView::kRowStyle, 4.,
kRowLayoutChildrenResultSizesWithSpacing});
}
} // VSTGUI
@@ -0,0 +1,378 @@
// This file is part of VSTGUI. It is subject to the license terms
// in the LICENSE file found in the top-level directory of this
// distribution and at http://github.com/steinbergmedia/vstgui/LICENSE
#include "../../../lib/csplitview.h"
#include "../../../uidescription/icontroller.h"
#include "../unittests.h"
#include "eventhelpers.h"
#include <array>
namespace VSTGUI {
namespace {
class SplitViewController : public IController, public ISplitViewController
{
public:
void valueChanged (CControl* pControl) override {}
bool getSplitViewSizeConstraint (int32_t index, CCoord& minSize, CCoord& maxSize,
CSplitView* splitView) override
{
if (index == 0)
{
minSize = 10;
maxSize = 50;
}
else
{
minSize = 10;
maxSize = 100;
}
return true;
}
ISplitViewSeparatorDrawer* getSplitViewSeparatorDrawer (CSplitView* splitView) override
{
return nullptr;
}
bool storeViewSize (int32_t index, const CCoord& size, CSplitView* splitView) override
{
sizes[static_cast<size_t> (index)] = size;
return true;
}
bool restoreViewSize (int32_t index, CCoord& size, CSplitView* splitView) override
{
if (index == 0)
size = 20;
else if (index == 1)
size = 70;
return true;
}
std::array<CCoord, 2> sizes;
};
class SeparatorSubView : public CView
{
public:
SeparatorSubView () : CView (CRect (0, 0, 0, 0)) {}
bool mouseDownCalled {false};
bool mouseMovedCalled {false};
bool mouseUpCalled {false};
bool mouseCancelCalled {false};
CMouseEventResult onMouseDown (CPoint& where, const CButtonState& buttons) override
{
mouseDownCalled = true;
return kMouseEventHandled;
}
CMouseEventResult onMouseMoved (CPoint& where, const CButtonState& buttons) override
{
mouseMovedCalled = true;
return kMouseEventHandled;
}
CMouseEventResult onMouseUp (CPoint& where, const CButtonState& buttons) override
{
mouseUpCalled = true;
return kMouseEventHandled;
}
CMouseEventResult onMouseCancel () override
{
mouseCancelCalled = true;
return kMouseEventHandled;
}
};
} // anonymous
TEST_CASE (CSplitViewTest, AddViewsHorizontal)
{
auto sv = owned (new CSplitView (CRect (0, 0, 100, 100)));
sv->setStyle (CSplitView::kHorizontal);
sv->setSeparatorWidth (10);
auto view1 = new CView (CRect (0, 0, 50, 100));
auto view2 = new CView (CRect (0, 0, 40, 100));
sv->addView (view1);
EXPECT (sv->getNbViews () == 1);
sv->addView (view2);
EXPECT (sv->getNbViews () == 3);
EXPECT (view1->getViewSize () == CRect (0, 0, 50, 100));
EXPECT (view2->getViewSize () == CRect (60, 0, 100, 100));
sv->removeView (view1);
EXPECT (sv->getNbViews () == 1);
EXPECT (view2->getViewSize () == CRect (60, 0, 100, 100));
}
TEST_CASE (CSplitViewTest, AddViewsVertical)
{
auto sv = owned (new CSplitView (CRect (0, 0, 100, 100)));
sv->setStyle (CSplitView::kVertical);
sv->setSeparatorWidth (10);
auto view1 = new CView (CRect (0, 0, 100, 50));
auto view2 = new CView (CRect (0, 0, 100, 40));
sv->addView (view1);
EXPECT (sv->getNbViews () == 1);
sv->addView (view2);
EXPECT (sv->getNbViews () == 3);
EXPECT (view1->getViewSize () == CRect (0, 0, 100, 50));
EXPECT (view2->getViewSize () == CRect (0, 60, 100, 100));
sv->removeView (view2);
EXPECT (sv->getNbViews () == 1);
EXPECT (view1->getViewSize () == CRect (0, 0, 100, 50));
}
TEST_CASE (CSplitViewTest, ResizeAllViewsHorizontal)
{
auto sv = owned (new CSplitView (CRect (0, 0, 100, 100)));
sv->setStyle (CSplitView::kHorizontal);
sv->setResizeMethod (CSplitView::kResizeAllViews);
sv->setSeparatorWidth (10);
auto view1 = new CView (CRect (0, 0, 50, 100));
auto view2 = new CView (CRect (0, 0, 40, 100));
sv->addView (view1);
sv->addView (view2);
sv->setViewSize (CRect (0, 0, 120, 100));
EXPECT (view1->getViewSize () == CRect (0, 0, 60, 100));
EXPECT (view2->getViewSize () == CRect (70, 0, 120, 100));
}
TEST_CASE (CSplitViewTest, ResizeAllViewsVertical)
{
auto sv = owned (new CSplitView (CRect (0, 0, 100, 100)));
sv->setStyle (CSplitView::kVertical);
sv->setResizeMethod (CSplitView::kResizeAllViews);
sv->setSeparatorWidth (10);
auto view1 = new CView (CRect (0, 0, 100, 50));
auto view2 = new CView (CRect (0, 0, 100, 40));
sv->addView (view1);
sv->addView (view2);
sv->setViewSize (CRect (0, 0, 100, 120));
EXPECT (view1->getViewSize () == CRect (0, 0, 100, 60));
EXPECT (view2->getViewSize () == CRect (0, 70, 100, 120));
}
TEST_CASE (CSplitViewTest, ResizeFirstViewHorizontal)
{
auto sv = owned (new CSplitView (CRect (0, 0, 100, 100)));
sv->setStyle (CSplitView::kHorizontal);
sv->setResizeMethod (CSplitView::kResizeFirstView);
sv->setSeparatorWidth (10);
auto view1 = new CView (CRect (0, 0, 50, 100));
auto view2 = new CView (CRect (0, 0, 40, 100));
sv->addView (view1);
sv->addView (view2);
sv->setViewSize (CRect (0, 0, 120, 100));
EXPECT (view1->getViewSize () == CRect (0, 0, 70, 100));
EXPECT (view2->getViewSize () == CRect (80, 0, 120, 100));
}
TEST_CASE (CSplitViewTest, ResizeFirstViewVertical)
{
auto sv = owned (new CSplitView (CRect (0, 0, 100, 100)));
sv->setStyle (CSplitView::kVertical);
sv->setResizeMethod (CSplitView::kResizeFirstView);
sv->setSeparatorWidth (10);
auto view1 = new CView (CRect (0, 0, 100, 50));
auto view2 = new CView (CRect (0, 0, 100, 40));
sv->addView (view1);
sv->addView (view2);
sv->setViewSize (CRect (0, 0, 100, 120));
EXPECT (view1->getViewSize () == CRect (0, 0, 100, 70));
EXPECT (view2->getViewSize () == CRect (0, 80, 100, 120));
}
TEST_CASE (CSplitViewTest, ResizeLastViewHorizontal)
{
auto sv = owned (new CSplitView (CRect (0, 0, 100, 100)));
sv->setStyle (CSplitView::kHorizontal);
sv->setResizeMethod (CSplitView::kResizeLastView);
sv->setSeparatorWidth (10);
auto view1 = new CView (CRect (0, 0, 50, 100));
auto view2 = new CView (CRect (0, 0, 40, 100));
sv->addView (view1);
sv->addView (view2);
sv->setViewSize (CRect (0, 0, 120, 100));
EXPECT (view1->getViewSize () == CRect (0, 0, 50, 100));
EXPECT (view2->getViewSize () == CRect (60, 0, 120, 100));
}
TEST_CASE (CSplitViewTest, resizeLastViewVertical)
{
auto sv = owned (new CSplitView (CRect (0, 0, 100, 100)));
sv->setStyle (CSplitView::kVertical);
sv->setResizeMethod (CSplitView::kResizeLastView);
sv->setSeparatorWidth (10);
auto view1 = new CView (CRect (0, 0, 100, 50));
auto view2 = new CView (CRect (0, 0, 100, 40));
sv->addView (view1);
sv->addView (view2);
sv->setViewSize (CRect (0, 0, 100, 120));
EXPECT (view1->getViewSize () == CRect (0, 0, 100, 50));
EXPECT (view2->getViewSize () == CRect (0, 60, 100, 120));
}
TEST_CASE (CSplitViewTest, ResizeSecondViewHorizontal)
{
auto sv = owned (new CSplitView (CRect (0, 0, 100, 100)));
sv->setStyle (CSplitView::kHorizontal);
sv->setResizeMethod (CSplitView::kResizeSecondView);
sv->setSeparatorWidth (10);
auto view1 = new CView (CRect (0, 0, 50, 100));
auto view2 = new CView (CRect (0, 0, 20, 100));
auto view3 = new CView (CRect (0, 0, 10, 100));
sv->addView (view1);
sv->addView (view2);
sv->addView (view3);
sv->setViewSize (CRect (0, 0, 120, 100));
EXPECT (view1->getViewSize () == CRect (0, 0, 50, 100));
EXPECT (view2->getViewSize () == CRect (60, 0, 100, 100));
EXPECT (view3->getViewSize () == CRect (110, 0, 120, 100));
}
TEST_CASE (CSplitViewTest, ResizeSecondViewVertical)
{
auto sv = owned (new CSplitView (CRect (0, 0, 100, 100)));
sv->setStyle (CSplitView::kVertical);
sv->setResizeMethod (CSplitView::kResizeSecondView);
sv->setSeparatorWidth (10);
auto view1 = new CView (CRect (0, 0, 100, 50));
auto view2 = new CView (CRect (0, 0, 100, 20));
auto view3 = new CView (CRect (0, 0, 100, 10));
sv->addView (view1);
sv->addView (view2);
sv->addView (view3);
sv->setViewSize (CRect (0, 0, 100, 120));
EXPECT (view1->getViewSize () == CRect (0, 0, 100, 50));
EXPECT (view2->getViewSize () == CRect (0, 60, 100, 100));
EXPECT (view3->getViewSize () == CRect (0, 110, 100, 120));
}
TEST_CASE (CSplitViewTest, SetSeparatorWidth)
{
auto sv = owned (new CSplitView (CRect (0, 0, 100, 100)));
sv->setStyle (CSplitView::kHorizontal);
sv->setResizeMethod (CSplitView::kResizeFirstView);
sv->setSeparatorWidth (10);
auto view1 = new CView (CRect (0, 0, 40, 100));
auto view2 = new CView (CRect (0, 0, 20, 100));
auto view3 = new CView (CRect (0, 0, 20, 100));
sv->addView (view1);
sv->addView (view2);
sv->addView (view3);
EXPECT (view1->getViewSize () == CRect (0, 0, 40, 100));
EXPECT (view2->getViewSize () == CRect (50, 0, 70, 100));
EXPECT (view3->getViewSize () == CRect (80, 0, 100, 100));
sv->setSeparatorWidth (20);
EXPECT (view1->getViewSize () == CRect (0, 0, 40, 100));
EXPECT (view2->getViewSize () == CRect (60, 0, 70, 100));
EXPECT (view3->getViewSize () == CRect (90, 0, 100, 100));
}
TEST_CASE (CSplitViewTest, ControllerHorizontal)
{
auto controller = new SplitViewController ();
auto container = owned (new CViewContainer (CRect (0, 0, 100, 100)));
auto sv = owned (new CSplitView (CRect (0, 0, 100, 100)));
sv->setAttribute (kCViewControllerAttribute, controller);
sv->setStyle (CSplitView::kHorizontal);
sv->setSeparatorWidth (10);
auto view1 = new CView (CRect (0, 0, 40, 100));
auto view2 = new CView (CRect (0, 0, 50, 100));
sv->addView (view1);
sv->addView (view2);
sv->attached (container);
EXPECT (view1->getViewSize () == CRect (0, 0, 20, 100));
EXPECT (view2->getViewSize () == CRect (30, 0, 100, 100));
dispatchMouseEvent<MouseDownEvent> (sv, {25., 1.}, MouseButton::Left);
dispatchMouseEvent<MouseMoveEvent> (sv, {55., 1.}, MouseButton::Left);
EXPECT (view1->getViewSize () == CRect (0, 0, 50, 100));
EXPECT (view2->getViewSize () == CRect (60, 0, 100, 100));
dispatchMouseEvent<MouseMoveEvent> (sv, {65., 1.}, MouseButton::Left);
EXPECT (view1->getViewSize () == CRect (0, 0, 50, 100));
EXPECT (view2->getViewSize () == CRect (60, 0, 100, 100));
dispatchMouseEvent<MouseMoveEvent> (sv, {15., 1.}, MouseButton::Left);
EXPECT (view1->getViewSize () == CRect (0, 0, 10, 100));
EXPECT (view2->getViewSize () == CRect (20, 0, 100, 100));
dispatchMouseEvent<MouseMoveEvent> (sv, {1., 1.}, MouseButton::Left);
EXPECT (view1->getViewSize () == CRect (0, 0, 10, 100));
EXPECT (view2->getViewSize () == CRect (20, 0, 100, 100));
dispatchMouseEvent<MouseUpEvent> (sv, {1., 1.}, MouseButton::Left);
sv->removed (container);
EXPECT (controller->sizes[0] == 10);
EXPECT (controller->sizes[1] == 80);
}
TEST_CASE (CSplitViewTest, ControllerVertical)
{
auto controller = new SplitViewController ();
auto container = owned (new CViewContainer (CRect (0, 0, 100, 100)));
auto sv = owned (new CSplitView (CRect (0, 0, 100, 100)));
sv->setAttribute (kCViewControllerAttribute, controller);
sv->setStyle (CSplitView::kVertical);
sv->setSeparatorWidth (10);
auto view1 = new CView (CRect (0, 0, 100, 40));
auto view2 = new CView (CRect (0, 0, 100, 50));
sv->addView (view1);
sv->addView (view2);
sv->attached (container);
EXPECT (view1->getViewSize () == CRect (0, 0, 100, 20));
EXPECT (view2->getViewSize () == CRect (0, 30, 100, 100));
dispatchMouseEvent<MouseDownEvent> (sv, {1., 25.}, MouseButton::Left);
dispatchMouseEvent<MouseMoveEvent> (sv, {1., 55.}, MouseButton::Left);
EXPECT (view1->getViewSize () == CRect (0, 0, 100, 50));
EXPECT (view2->getViewSize () == CRect (0, 60, 100, 100));
dispatchMouseEvent<MouseMoveEvent> (sv, {1., 65.}, MouseButton::Left);
EXPECT (view1->getViewSize () == CRect (0, 0, 100, 50));
EXPECT (view2->getViewSize () == CRect (0, 60, 100, 100));
dispatchMouseEvent<MouseMoveEvent> (sv, {1., 15.}, MouseButton::Left);
EXPECT (view1->getViewSize () == CRect (0, 0, 100, 10));
EXPECT (view2->getViewSize () == CRect (00, 20, 100, 100));
dispatchMouseEvent<MouseMoveEvent> (sv, {1., 1.}, MouseButton::Left);
EXPECT (view1->getViewSize () == CRect (0, 0, 100, 10));
EXPECT (view2->getViewSize () == CRect (0, 20, 100, 100));
dispatchMouseEvent<MouseUpEvent> (sv, {1., 1.}, MouseButton::Left);
sv->removed (container);
EXPECT (controller->sizes[0] == 10);
EXPECT (controller->sizes[1] == 80);
}
TEST_CASE (CSplitViewTest, SeparatorSubView)
{
auto container = owned (new CViewContainer (CRect (0, 0, 100, 100)));
auto sv = owned (new CSplitView (CRect (0, 0, 100, 100)));
sv->setStyle (CSplitView::kHorizontal);
sv->setResizeMethod (CSplitView::kResizeFirstView);
sv->setSeparatorWidth (10);
auto view1 = new CView (CRect (0, 0, 40, 100));
auto view2 = new CView (CRect (0, 0, 20, 100));
sv->addView (view1);
sv->addView (view2);
auto sepView = new SeparatorSubView ();
sepView->setViewSize (CRect (0, 0, 10, 10));
sepView->setMouseableArea (CRect (0, 0, 10, 10));
sv->addViewToSeparator (0, sepView);
sv->attached (container);
dispatchMouseEvent<MouseDownEvent> (sv, {41., 25.}, MouseButton::Left);
EXPECT (sepView->mouseDownCalled == false);
dispatchMouseEvent<MouseDownEvent> (sv, {41., 1.}, MouseButton::Left);
EXPECT (sepView->mouseDownCalled);
dispatchMouseEvent<MouseMoveEvent> (sv, {41., 3.}, MouseButton::Left);
EXPECT (sepView->mouseMovedCalled);
dispatchMouseEvent<MouseUpEvent> (sv, {41., 3.}, MouseButton::Left);
EXPECT (sepView->mouseUpCalled);
dispatchMouseEvent<MouseDownEvent> (sv, {41., 1.}, MouseButton::Left);
dispatchMouseCancelEvent (sv);
EXPECT (sepView->mouseCancelCalled);
sv->removed (container);
}
} // VSTGUI
@@ -0,0 +1,617 @@
// This file is part of VSTGUI. It is subject to the license terms
// in the LICENSE file found in the top-level directory of this
// distribution and at http://github.com/steinbergmedia/vstgui/LICENSE
#include "../../../lib/cstring.h"
#include "../../../lib/cgraphicspath.h"
#include "../../../lib/coffscreencontext.h"
#include "../../../lib/cview.h"
#include "../../../lib/cviewcontainer.h"
#include "../../../lib/dragging.h"
#include "../../../lib/events.h"
#include "../../../lib/idatapackage.h"
#include "../../../lib/iviewlistener.h"
#include "../unittests.h"
#if MAC
#include <CoreFoundation/CoreFoundation.h>
#endif
#include <array>
namespace VSTGUI {
namespace {
class View : public CView
{
public:
View () : CView (CRect (0, 0, 10, 10)) {}
void onIdle () override { onIdleCalled = true; }
bool onIdleCalled {false};
};
struct ViewListener : public IViewListener
{
void viewSizeChanged (CView* view, const CRect& oldSize) override { sizeChangedCalled = true; }
void viewAttached (CView* view) override { attachedCalled = true; }
void viewRemoved (CView* view) override { removedCalled = true; }
void viewLostFocus (CView* view) override { lostFocusCalled = true; }
void viewTookFocus (CView* view) override { tookFocusCalled = true; }
void viewWillDelete (CView* view) override
{
view->unregisterViewListener (this);
willDeleteCalled = true;
}
void viewOnMouseEnabled (CView* view, bool state) override {}
bool sizeChangedCalled {false};
bool attachedCalled {false};
bool removedCalled {false};
bool lostFocusCalled {false};
bool tookFocusCalled {false};
bool willDeleteCalled {false};
};
} // anonymous
TEST_CASE (CViewTest, VisibleState)
{
auto v = owned (new View ());
EXPECT (v->isVisible () == true);
v->setVisible (false);
EXPECT (v->isVisible () == false);
v->setVisible (true);
EXPECT (v->isVisible () == true);
v->setAlphaValue (0.f);
EXPECT (v->isVisible () == false);
}
TEST_CASE (CViewTest, TransparencyState)
{
auto v = owned (new View ());
EXPECT (v->getTransparency () == false);
v->setTransparency (true);
EXPECT (v->getTransparency () == true);
v->setTransparency (false);
EXPECT (v->getTransparency () == false);
}
TEST_CASE (CViewTest, FocusState)
{
auto v = owned (new View ());
EXPECT (v->wantsFocus () == false);
v->setWantsFocus (true);
EXPECT (v->wantsFocus () == true);
v->setWantsFocus (false);
EXPECT (v->wantsFocus () == false);
}
TEST_CASE (CViewTest, IdleState)
{
auto v = owned (new View ());
EXPECT (v->wantsIdle () == false);
v->setWantsIdle (true);
EXPECT (v->wantsIdle () == true);
v->setWantsIdle (false);
EXPECT (v->wantsIdle () == false);
}
TEST_CASE (CViewTest, MouseEnabledState)
{
auto v = owned (new View ());
EXPECT (v->getMouseEnabled () == true);
v->setMouseEnabled (false);
EXPECT (v->getMouseEnabled () == false);
v->setMouseEnabled (true);
EXPECT (v->getMouseEnabled () == true);
}
TEST_CASE (CViewTest, AutosizeFlags)
{
auto v = owned (new View ());
EXPECT (v->getAutosizeFlags () == kAutosizeNone);
v->setAutosizeFlags (kAutosizeLeft);
EXPECT (v->getAutosizeFlags () == kAutosizeLeft);
v->setAutosizeFlags (kAutosizeLeft | kAutosizeTop);
EXPECT (v->getAutosizeFlags () == (kAutosizeLeft | kAutosizeTop));
}
TEST_CASE (CViewTest, Attributes)
{
auto v = owned (new View ());
uint32_t outSize;
void* outData = nullptr;
EXPECT (v->getAttribute (0, 10, outData, outSize) == false);
EXPECT (v->removeAttribute (0) == false);
uint64_t myAttr = 500;
EXPECT (v->setAttribute (0, 0, &myAttr) == false);
EXPECT (v->setAttribute (0, sizeof (myAttr), nullptr) == false);
EXPECT (v->setAttribute ('myAt', sizeof (myAttr), &myAttr) == true);
myAttr = 10;
EXPECT (v->getAttributeSize ('myAt', outSize) == true);
EXPECT (outSize == sizeof (myAttr));
EXPECT (v->getAttribute ('myAt', sizeof (myAttr), &myAttr, outSize) == true);
EXPECT (myAttr == 500);
myAttr = 100;
EXPECT (v->setAttribute ('myAt', sizeof (myAttr), &myAttr) == true);
myAttr = 102;
EXPECT (v->getAttribute ('myAt', sizeof (myAttr), &myAttr, outSize) == true);
EXPECT (myAttr == 100);
EXPECT (v->removeAttribute ('myAt') == true);
EXPECT (v->getAttribute ('myAt', sizeof (myAttr), &myAttr, outSize) == false);
}
TEST_CASE (CViewTest, ResizeAttribute)
{
auto v = owned (new View ());
uint32_t outSize;
uint8_t firstData = 8;
EXPECT (v->setAttribute (0, sizeof (firstData), &firstData));
firstData = 0;
EXPECT (v->getAttribute (0, sizeof (firstData), &firstData, outSize));
EXPECT (firstData == 8);
uint32_t secondData = 32;
EXPECT (v->setAttribute (0, sizeof (secondData), &secondData));
secondData = 0;
EXPECT (v->getAttribute (0, sizeof (firstData), &firstData, outSize) == false);
EXPECT (v->getAttribute (0, sizeof (secondData), &secondData, outSize));
EXPECT (secondData == 32);
}
TEST_CASE (CViewTest, ViewListener)
{
ViewListener listener;
{
auto v = new View ();
v->registerViewListener (&listener);
v->setViewSize (CRect (1, 2, 3, 4));
auto container1 = owned (new CViewContainer (CRect (0, 0, 100, 100)));
auto container2 = owned (new CViewContainer (CRect (0, 0, 100, 100)));
container2->addView (v);
container2->attached (container1);
v->takeFocus ();
v->looseFocus ();
container2->removeView (v);
container2->removed (container1);
}
EXPECT (listener.sizeChangedCalled);
EXPECT (listener.attachedCalled);
EXPECT (listener.removedCalled);
EXPECT (listener.tookFocusCalled);
EXPECT (listener.lostFocusCalled);
EXPECT (listener.willDeleteCalled);
}
TEST_CASE (CViewTest, CoordCalculations)
{
auto parent = owned (new CViewContainer (CRect (0, 0, 100, 100)));
auto container = owned (new CViewContainer (CRect (50, 50, 100, 100)));
container->attached (parent);
auto v = new View ();
container->addView (v);
CPoint p (0, 0);
v->localToFrame (p);
EXPECT (p.x == 50 && p.y == 50);
p (52, 53);
v->frameToLocal (p);
EXPECT (p.x == 2 && p.y == 3);
container->removed (parent);
}
TEST_CASE (CViewTest, VisibleViewSize)
{
auto parent = owned (new CViewContainer (CRect (0, 0, 100, 100)));
auto container = owned (new CViewContainer (CRect (50, 50, 100, 100)));
container->attached (parent);
auto v = new View ();
v->setViewSize (CRect (20, 20, 150, 150));
container->addView (v);
auto visible = v->getVisibleViewSize ();
EXPECT (visible == CRect (20, 20, 50, 50));
container->removeView (v);
container->removed (parent);
}
TEST_CASE (CViewTest, GlobalTransform)
{
auto container1 = owned (new CViewContainer (CRect (0, 0, 10, 10)));
auto container2 = new CViewContainer (CRect (0, 0, 10, 10));
container1->setTransform (CGraphicsTransform ().translate (10, 20));
container2->setTransform (CGraphicsTransform ().translate (15, 35));
container1->addView (container2);
auto v = new View ();
container2->addView (v);
container2->attached (container1);
auto transform = v->getGlobalTransform ();
EXPECT (transform.dx == 25 && transform.dy == 55);
CPoint p (0, 0);
v->translateToGlobal (p);
EXPECT (p.x == 25 && p.y == 55);
v->translateToLocal (p);
EXPECT (p.x == 0 && p.y == 0);
auto p2 = v->translateToGlobal (CRect (0, 0, 1, 1));
EXPECT (p2 == CRect (25, 55, 26, 56));
p2 = v->translateToLocal (CRect (25, 55, 26, 56));
EXPECT (p2 == CRect (0, 0, 1, 1));
container2->removed (container1);
}
TEST_CASE (CViewTest, HitTest)
{
auto v = owned (new View ());
v->setMouseableArea (CRect (20, 20, 40, 40));
EXPECT (v->hitTest (CPoint (5, 5)) == false);
EXPECT (v->hitTest (CPoint (20, 20)) == true);
EXPECT (v->hitTest (CPoint (40, 40)) == false);
}
TEST_CASE (CViewTest, DefaultHandling)
{
auto v = makeOwned<View> ();
KeyboardEvent keyEvent;
v->dispatchEvent (keyEvent);
EXPECT (keyEvent.consumed == false);
keyEvent.type = EventType::KeyUp;
v->dispatchEvent (keyEvent);
EXPECT (keyEvent.consumed == false);
MouseWheelEvent event;
v->onMouseWheelEvent (event);
EXPECT (event.consumed == false);
CPoint p (0, 0);
EXPECT (v->onMouseDown (p, kLButton) == kMouseEventNotImplemented);
EXPECT (v->onMouseUp (p, kLButton) == kMouseEventNotImplemented);
EXPECT (v->onMouseMoved (p, kLButton) == kMouseEventNotImplemented);
EXPECT (v->onMouseCancel () == kMouseEventNotImplemented);
EXPECT (v->onMouseEntered (p, kLButton) == kMouseEventNotImplemented);
EXPECT (v->onMouseExited (p, kLButton) == kMouseEventNotImplemented);
EXPECT (v->notify (nullptr, nullptr) == kMessageUnknown);
EXPECT (v->doDrag (DragDescription (nullptr)) == false);
EXPECT (v->getDropTarget () == nullptr);
EXPECT (v->getEditor () == nullptr);
EXPECT (v->isDirty () == false);
EXPECT (v->sizeToFit () == false);
EXPECT (v->getBackground () == nullptr);
EXPECT (v->getDisabledBackground () == nullptr);
EXPECT (v->getDrawBackground () == nullptr);
EXPECT (v->checkUpdate (CRect (0, 0, 5, 5)) == true);
EXPECT (v->getWidth () == 10);
EXPECT (v->getHeight () == 10);
EXPECT (v->getViewSize () == v->getMouseableArea ());
}
TEST_CASE (CViewTest, PathHitTest)
{
auto v = makeOwned<View> ();
v->setViewSize ({0., 0., 100., 100.});
{
auto drawContext = COffscreenContext::create ({100., 100.});
auto path = owned (drawContext->createGraphicsPath ());
path->addRect ({10., 10., 80., 80.});
v->setHitTestPath (path);
}
EXPECT_FALSE (v->hitTest ({5., 5.}, noEvent ()));
EXPECT_TRUE (v->hitTest ({15., 15.}, noEvent ()));
}
namespace {
class TestView : public CView
{
public:
TestView () : CView (CRect (0, 0, 10, 10))
{
std::fill (called.begin (), called.end (), false);
}
void onMouseDownEvent (MouseDownEvent& event) override
{
called[e2p (EventType::MouseDown)] = true;
}
void onMouseMoveEvent (MouseMoveEvent& event) override
{
called[e2p (EventType::MouseMove)] = true;
}
void onMouseUpEvent (MouseUpEvent& event) override { called[e2p (EventType::MouseUp)] = true; }
void onMouseCancelEvent (MouseCancelEvent& event) override
{
called[e2p (EventType::MouseCancel)] = true;
}
void onMouseEnterEvent (MouseEnterEvent& event) override
{
called[e2p (EventType::MouseEnter)] = true;
}
void onMouseExitEvent (MouseExitEvent& event) override
{
called[e2p (EventType::MouseExit)] = true;
}
void onMouseWheelEvent (MouseWheelEvent& event) override
{
called[e2p (EventType::MouseWheel)] = true;
}
void onZoomGestureEvent (ZoomGestureEvent& event) override
{
called[e2p (EventType::ZoomGesture)] = true;
}
void onKeyboardEvent (KeyboardEvent& event) override { called[e2p (EventType::KeyUp)] = true; }
bool eventCalled (EventType t) const { return called[e2p (t)]; }
private:
static constexpr size_t e2p (EventType t) { return static_cast<size_t> (t); }
std::array<bool, static_cast<size_t> (EventType::KeyDown)> called;
};
struct TestViewEventHandler : IViewEventListener
{
using Func = std::function<void (CView*, Event&)>;
TestViewEventHandler (Func&& func) : func (std::move (func)) {}
void viewOnEvent (CView* view, Event& event) override { func (view, event); }
Func func;
};
} // anonymous
TEST_CASE (CViewTest, ViewEventListenerMouseDownEvent)
{
auto v = makeOwned<TestView> ();
TestViewEventHandler listener ([] (CView*, Event& event) { event.consumed = true; });
v->registerViewEventListener (&listener);
MouseDownEvent event;
v->dispatchEvent (event);
EXPECT_FALSE (v->eventCalled (EventType::MouseDown));
v->unregisterViewEventListener (&listener);
event.consumed.reset ();
v->dispatchEvent (event);
EXPECT_TRUE (v->eventCalled (EventType::MouseDown));
}
TEST_CASE (CViewTest, ViewEventListenerMouseMoveEvent)
{
auto v = makeOwned<TestView> ();
TestViewEventHandler listener ([] (CView*, Event& event) { event.consumed = true; });
v->registerViewEventListener (&listener);
MouseMoveEvent event;
v->dispatchEvent (event);
EXPECT_FALSE (v->eventCalled (EventType::MouseMove));
v->unregisterViewEventListener (&listener);
event.consumed.reset ();
v->dispatchEvent (event);
EXPECT_TRUE (v->eventCalled (EventType::MouseMove));
}
TEST_CASE (CViewTest, ViewEventListenerMouseUpEvent)
{
auto v = makeOwned<TestView> ();
TestViewEventHandler listener ([] (CView*, Event& event) { event.consumed = true; });
v->registerViewEventListener (&listener);
MouseUpEvent event;
v->dispatchEvent (event);
EXPECT_FALSE (v->eventCalled (EventType::MouseUp));
v->unregisterViewEventListener (&listener);
event.consumed.reset ();
v->dispatchEvent (event);
EXPECT_TRUE (v->eventCalled (EventType::MouseUp));
}
TEST_CASE (CViewTest, ViewEventListenerMouseCancelEvent)
{
auto v = makeOwned<TestView> ();
TestViewEventHandler listener ([] (CView*, Event& event) { event.consumed = true; });
v->registerViewEventListener (&listener);
MouseCancelEvent event;
v->dispatchEvent (event);
EXPECT_FALSE (v->eventCalled (EventType::MouseCancel));
v->unregisterViewEventListener (&listener);
event.consumed.reset ();
v->dispatchEvent (event);
EXPECT_TRUE (v->eventCalled (EventType::MouseCancel));
}
TEST_CASE (CViewTest, ViewEventListenerMouseEnterEvent)
{
auto v = makeOwned<TestView> ();
TestViewEventHandler listener ([] (CView*, Event& event) { event.consumed = true; });
v->registerViewEventListener (&listener);
MouseEnterEvent event;
v->dispatchEvent (event);
EXPECT_FALSE (v->eventCalled (EventType::MouseEnter));
v->unregisterViewEventListener (&listener);
event.consumed.reset ();
v->dispatchEvent (event);
EXPECT_TRUE (v->eventCalled (EventType::MouseEnter));
}
TEST_CASE (CViewTest, ViewEventListenerMouseExitEvent)
{
auto v = makeOwned<TestView> ();
TestViewEventHandler listener ([] (CView*, Event& event) { event.consumed = true; });
v->registerViewEventListener (&listener);
MouseExitEvent event;
v->dispatchEvent (event);
EXPECT_FALSE (v->eventCalled (EventType::MouseExit));
v->unregisterViewEventListener (&listener);
event.consumed.reset ();
v->dispatchEvent (event);
EXPECT_TRUE (v->eventCalled (EventType::MouseExit));
}
TEST_CASE (CViewTest, ViewEventListenerMouseWheelEvent)
{
auto v = makeOwned<TestView> ();
TestViewEventHandler listener ([] (CView*, Event& event) { event.consumed = true; });
v->registerViewEventListener (&listener);
MouseWheelEvent event;
v->dispatchEvent (event);
EXPECT_FALSE (v->eventCalled (EventType::MouseWheel));
v->unregisterViewEventListener (&listener);
event.consumed.reset ();
v->dispatchEvent (event);
EXPECT_TRUE (v->eventCalled (EventType::MouseWheel));
}
TEST_CASE (CViewTest, ViewEventListenerZoomGestureEvent)
{
auto v = makeOwned<TestView> ();
TestViewEventHandler listener ([] (CView*, Event& event) { event.consumed = true; });
v->registerViewEventListener (&listener);
ZoomGestureEvent event;
v->dispatchEvent (event);
EXPECT_FALSE (v->eventCalled (EventType::ZoomGesture));
v->unregisterViewEventListener (&listener);
event.consumed.reset ();
v->dispatchEvent (event);
EXPECT_TRUE (v->eventCalled (EventType::ZoomGesture));
}
TEST_CASE (CViewTest, ViewEventListenerKeyEvent)
{
auto v = makeOwned<TestView> ();
TestViewEventHandler listener ([] (CView*, Event& event) { event.consumed = true; });
v->registerViewEventListener (&listener);
KeyboardEvent event;
v->dispatchEvent (event);
EXPECT_FALSE (v->eventCalled (EventType::KeyUp));
v->unregisterViewEventListener (&listener);
event.consumed.reset ();
v->dispatchEvent (event);
EXPECT_TRUE (v->eventCalled (EventType::KeyUp));
}
#if MAC // TODO: Make test work on other platforms too.
TEST_CASE (CViewTest, IdleAfterAttached)
{
auto parent = owned (new CViewContainer (CRect (0, 0, 100, 100)));
auto container = owned (new CViewContainer (CRect (50, 50, 100, 100)));
container->attached (parent);
auto v = new View ();
container->addView (v);
v->setWantsIdle (true);
CFRunLoopRunInMode (kCFRunLoopDefaultMode, 0.2, false);
EXPECT (v->onIdleCalled == true);
v->setWantsIdle (false);
v->onIdleCalled = false;
CFRunLoopRunInMode (kCFRunLoopDefaultMode, 0.2, false);
EXPECT (v->onIdleCalled == false);
container->removeView (v);
container->removed (parent);
}
TEST_CASE (CViewTest, IdleBeforeAttached)
{
auto parent = owned (new CViewContainer (CRect (0, 0, 100, 100)));
auto container = owned (new CViewContainer (CRect (50, 50, 100, 100)));
auto v = new View ();
container->addView (v);
v->setWantsIdle (true);
container->attached (parent);
CFRunLoopRunInMode (kCFRunLoopDefaultMode, 0.2, true);
EXPECT (v->onIdleCalled == true);
container->removeView (v);
container->removed (parent);
}
#endif
struct DataPackage : IDataPackage
{
UTF8String str;
UTF8String path;
int8_t binary[3];
uint32_t getCount () const override { return 3; }
uint32_t getDataSize (uint32_t index) const override
{
if (index == 0)
return static_cast<uint32_t> (str.length ());
else if (index == 1)
return static_cast<uint32_t> (path.length ());
else if (index == 2)
return 3;
return 0;
}
Type getDataType (uint32_t index) const override
{
if (index == 0)
return kText;
else if (index == 1)
return kFilePath;
else if (index == 2)
return kBinary;
return kError;
}
uint32_t getData (uint32_t index, const void*& buffer, Type& type) const override
{
type = kError;
if (index == 0)
{
buffer = str.data ();
type = kText;
}
else if (index == 1)
{
buffer = path.data ();
type = kFilePath;
}
else if (index == 2)
{
buffer = binary;
type = kBinary;
}
return getDataSize (index);
}
};
TEST_CASE (CDragContainerHelperTest, Count)
{
DataPackage package;
CDragContainerHelper helper (&package);
EXPECT (helper.getCount () == 3);
}
TEST_CASE (CDragContainerHelper, GetType)
{
DataPackage package;
CDragContainerHelper helper (&package);
EXPECT (helper.getType (0) == CDragContainerHelper::kUnicodeText);
EXPECT (helper.getType (1) == CDragContainerHelper::kFile);
EXPECT (helper.getType (2) == CDragContainerHelper::kUnknown);
EXPECT (helper.getType (3) == CDragContainerHelper::kError);
}
TEST_CASE (CDragContainerHelper, Iteration)
{
DataPackage package;
package.str = "Test";
package.path = "/var/tmp/test";
CDragContainerHelper helper (&package);
int32_t size;
int32_t type;
auto res = helper.first (size, type);
EXPECT (res == package.str.data ());
EXPECT (size == static_cast<int32_t> (package.str.length ()));
EXPECT (type == CDragContainerHelper::kUnicodeText);
res = helper.next (size, type);
EXPECT (res == package.path.data ());
EXPECT (size == static_cast<int32_t> (package.path.length ()));
EXPECT (type == CDragContainerHelper::kFile);
res = helper.next (size, type);
EXPECT (res == package.binary);
EXPECT (size == 3);
EXPECT (type == CDragContainerHelper::kUnknown);
res = helper.next (size, type);
EXPECT (res == nullptr);
EXPECT (size == 0);
EXPECT (type == CDragContainerHelper::kError);
}
} // VSTGUI
@@ -0,0 +1,641 @@
// This file is part of VSTGUI. It is subject to the license terms
// in the LICENSE file found in the top-level directory of this
// distribution and at http://github.com/steinbergmedia/vstgui/LICENSE
#include "../../../lib/cframe.h"
#include "../../../lib/iviewlistener.h"
#include "../../../lib/ccolor.h"
#include "../../../lib/dragging.h"
#include "../../../lib/events.h"
#include "../unittests.h"
#include "eventhelpers.h"
#include <vector>
namespace VSTGUI {
namespace {
class TestViewContainerListener : public IViewContainerListener
{
public:
void viewContainerViewAdded (CViewContainer* container, CView* view) override
{ viewAddedCalled = true; }
void viewContainerViewRemoved (CViewContainer* container, CView* view) override
{ viewRemovedCalled = true; }
void viewContainerViewZOrderChanged (CViewContainer* container, CView* view) override
{ viewZOrderChangedCalled = true; }
void viewContainerTransformChanged (CViewContainer* container) override
{ transformChangedCalled = true; }
bool viewAddedCalled {false};
bool viewRemovedCalled {false};
bool viewZOrderChangedCalled {false};
bool transformChangedCalled {false};
};
class TestView1 : public CView
{
public:
TestView1 () : CView (CRect (0, 0, 10, 10)) {}
};
class TestView2 : public CView
{
public:
TestView2 () : CView (CRect (10, 10, 20, 20)) {}
};
class MouseEventCheckView : public CView, public DropTargetAdapter
{
public:
MouseEventCheckView () : CView (CRect ()) {}
bool mouseDownCalled {false};
bool mouseMovedCalled {false};
bool mouseUpCalled {false};
bool mouseCancelCalled {false};
bool onDragEnterCalled {false};
bool onDragLeaveCalled {false};
bool onDragMoveCalled {false};
bool onWheelCalled {false};
CMouseEventResult onMouseDown (CPoint& where, const CButtonState& buttons) override
{
mouseDownCalled = true;
return kMouseEventHandled;
}
CMouseEventResult onMouseMoved (CPoint& where, const CButtonState& buttons) override
{
mouseMovedCalled = true;
return kMouseEventHandled;
}
CMouseEventResult onMouseUp (CPoint& where, const CButtonState& buttons) override
{
mouseUpCalled = true;
return kMouseEventHandled;
}
CMouseEventResult onMouseCancel () override
{
mouseCancelCalled = true;
return kMouseEventHandled;
}
SharedPointer<IDropTarget> getDropTarget () override { return this; }
DragOperation onDragEnter (DragEventData data) override
{
onDragEnterCalled = true;
return DragOperation::None;
}
void onDragLeave (DragEventData data) override
{
onDragLeaveCalled = true;
}
DragOperation onDragMove (DragEventData data) override
{
onDragMoveCalled = true;
return DragOperation::None;
}
void onMouseWheelEvent (MouseWheelEvent& event) override
{
onWheelCalled = true;
event.consumed = true;
}
};
} // anonymous
TEST_SUITE_SETUP (CViewContainerTest)
{
SharedPointer<CViewContainer> container = makeOwned<CViewContainer> (CRect (0, 0, 200, 200));
TEST_SUITE_SET_STORAGE (SharedPointer<CViewContainer>, container);
}
TEST_SUITE_TEARDOWN (CViewContainerTest)
{
TEST_SUITE_GET_STORAGE (SharedPointer<CViewContainer>) = nullptr;
}
TEST_CASE (CViewContainerTest, ChangeViewZOrder)
{
auto& container = TEST_SUITE_GET_STORAGE (SharedPointer<CViewContainer>);
CView* view1 = new CView (CRect (0, 0, 10, 10));
CView* view2 = new CView (CRect (0, 0, 10, 10));
CView* view3 = new CView (CRect (0, 0, 10, 10));
container->addView (view1);
container->addView (view2);
container->addView (view3);
EXPECT(container->changeViewZOrder (view3, 0));
EXPECT(container->getView (0) == view3);
EXPECT(container->getView (1) == view1);
EXPECT(container->getView (2) == view2);
EXPECT(container->getView (3) == nullptr);
EXPECT(container->changeViewZOrder (view3, 4) == false);
EXPECT(container->changeViewZOrder (view3, 0));
EXPECT(container->changeViewZOrder (view3, 1));
EXPECT(container->getView (0) == view1);
EXPECT(container->getView (1) == view3);
EXPECT(container->getView (2) == view2);
}
TEST_CASE (CViewContainerTest, AddView)
{
auto& container = TEST_SUITE_GET_STORAGE (SharedPointer<CViewContainer>);
CView* view = new CView (CRect (0, 0, 10, 10));
CView* view2 = new CView (CRect (0, 0, 10, 10));
EXPECT(container->addView (view));
EXPECT(container->addView (view2));
EXPECT(container->isChild (view));
EXPECT(container->isChild (view2));
}
TEST_CASE (CViewContainerTest, AddView2)
{
auto& container = TEST_SUITE_GET_STORAGE (SharedPointer<CViewContainer>);
auto v = new TestView1 ();
CRect r (30, 40, 50, 60);
EXPECT(container->addView (v, r, false));
EXPECT(v->getMouseEnabled () == false);
EXPECT(v->getMouseableArea () == r);
}
TEST_CASE (CViewContainerTest, AddViewTwice)
{
auto& container = TEST_SUITE_GET_STORAGE (SharedPointer<CViewContainer>);
CView* view = new CView (CRect (0, 0, 10, 10));
EXPECT (container->addView (view));
EXPECT_EXCEPTION (container->addView (view), "view is already added to a container view");
}
TEST_CASE (CViewContainerTest, AddViewToTwoContainer)
{
auto& container = TEST_SUITE_GET_STORAGE (SharedPointer<CViewContainer>);
CView* view = new CView (CRect (0, 0, 10, 10));
EXPECT (container->addView (view));
auto c2 = owned (new CViewContainer (CRect ()));
EXPECT_EXCEPTION (c2->addView (view), "view is already added to a container view");
}
TEST_CASE (CViewContainerTest, AddViewBeforeOtherView)
{
auto& container = TEST_SUITE_GET_STORAGE (SharedPointer<CViewContainer>);
CView* view = new CView (CRect (0, 0, 10, 10));
CView* view2 = new CView (CRect (0, 0, 10, 10));
EXPECT (container->addView (view));
EXPECT (container->addView (view2, view));
EXPECT (container->getView (0) == view2)
EXPECT (container->getView (1) == view)
}
TEST_CASE (CViewContainerTest, RemoveView)
{
auto& container = TEST_SUITE_GET_STORAGE (SharedPointer<CViewContainer>);
auto view = makeOwned<CView> (CRect (0, 0, 10, 10));
CView* view2 = new CView (CRect (0, 0, 10, 10));
container->addView (view);
container->addView (view2);
container->removeView (view, false);
EXPECT (container->isChild (view) == false)
EXPECT (container->isChild (view2))
}
TEST_CASE (CViewContainerTest, RemoveAllViews)
{
auto& container = TEST_SUITE_GET_STORAGE (SharedPointer<CViewContainer>);
auto view = makeOwned<CView> (CRect (0, 0, 10, 10));
auto view2 = makeOwned<CView> (CRect (0, 0, 10, 10));
container->addView (view);
container->addView (view2);
container->removeAll (false);
EXPECT (container->isChild (view) == false)
EXPECT (container->isChild (view2) == false)
EXPECT (container->hasChildren () == false)
}
TEST_CASE (CViewContainerTest, AdvanceNextFocusView)
{
auto& container = TEST_SUITE_GET_STORAGE (SharedPointer<CViewContainer>);
CFrame* frame = new CFrame (CRect (0, 0, 10, 10), nullptr);
frame->onActivate (true);
CView* view1 = new CView (CRect (0, 0, 10, 10));
CView* view2 = new CView (CRect (0, 0, 10, 10));
CView* view3 = new CView (CRect (0, 0, 10, 10));
view1->setWantsFocus (true);
view2->setWantsFocus (true);
view3->setWantsFocus (true);
container->addView (view1);
container->addView (view2);
container->addView (view3);
frame->addView (container);
container->remember ();
frame->attached (frame);
EXPECT (container->advanceNextFocusView (nullptr, true) == true)
EXPECT (frame->getFocusView () == view3)
EXPECT (container->advanceNextFocusView (view3) == false)
frame->setFocusView (nullptr);
EXPECT (container->advanceNextFocusView (nullptr) == true)
EXPECT (frame->getFocusView () == view1)
frame->close ();
}
TEST_CASE (CViewContainerTest, AutoSizeAll)
{
auto& container = TEST_SUITE_GET_STORAGE (SharedPointer<CViewContainer>);
CView* view = new CView (container->getViewSize ());
view->setAutosizeFlags (kAutosizeAll);
container->addView (view);
container->setAutosizingEnabled (true);
EXPECT (container->getAutosizingEnabled ());
container->setViewSize (CRect (0, 0, 500, 500));
EXPECT (view->getViewSize ().left == 0)
EXPECT (view->getViewSize ().top == 0)
EXPECT (view->getViewSize ().right == 500)
EXPECT (view->getViewSize ().bottom == 500)
container->setAutosizingEnabled (false);
EXPECT (container->getAutosizingEnabled () == false);
}
TEST_CASE (CViewContainerTest, SizeToFit)
{
auto& container = TEST_SUITE_GET_STORAGE (SharedPointer<CViewContainer>);
CRect r (10, 10, 20, 20);
CView* view = new CView (r);
container->addView (view);
container->sizeToFit ();
EXPECT (container->getViewSize ().right == 30)
EXPECT (container->getViewSize ().bottom == 30)
}
TEST_CASE (CViewContainerTest, GetViewAt)
{
auto& container = TEST_SUITE_GET_STORAGE (SharedPointer<CViewContainer>);
CRect r (10, 10, 20, 20);
CView* view = new CView (r);
container->addView (view);
EXPECT (view == container->getViewAt (r.getTopLeft ()));
EXPECT (nullptr == container->getViewAt (CPoint (0, 0)));
}
TEST_CASE (CViewContainerTest, GetViewAtDeep)
{
auto& container = TEST_SUITE_GET_STORAGE (SharedPointer<CViewContainer>);
CRect r (10, 10, 20, 20);
CViewContainer* container2 = new CViewContainer (r);
container->addView (container2);
CRect r2 (2, 2, 4, 4);
CView* view = new CView (r2);
container2->addView (view);
EXPECT (container->getViewAt (CPoint (12, 12)) == nullptr);
EXPECT (container->getViewAt (CPoint (12, 12), GetViewOptions (GetViewOptions::kDeep)) == view);
EXPECT (container->getViewAt (CPoint (11, 11), GetViewOptions (GetViewOptions::kDeep)) ==
nullptr);
EXPECT (container->getViewAt (
CPoint (11, 11),
GetViewOptions (GetViewOptions::kDeep | GetViewOptions::kIncludeViewContainer)) ==
container2);
}
TEST_CASE (CViewContainerTest, Listener)
{
auto& container = TEST_SUITE_GET_STORAGE (SharedPointer<CViewContainer>);
TestViewContainerListener listener;
container->registerViewContainerListener (&listener);
auto view = new CView (CRect (0, 0, 0, 0));
container->addView (view);
EXPECT (listener.viewAddedCalled == true);
container->removeView (view, false);
EXPECT (listener.viewRemovedCalled == true);
auto view2 = new CView (CRect (0, 0, 0, 0));
container->addView (view);
container->addView (view2);
container->changeViewZOrder (view2, 0);
EXPECT (listener.viewZOrderChangedCalled == true);
container->setTransform (CGraphicsTransform ().translate (1., 1.));
EXPECT (listener.transformChangedCalled == true);
container->unregisterViewContainerListener (&listener);
}
TEST_CASE (CViewContainerTest, BackgroundColor)
{
auto& container = TEST_SUITE_GET_STORAGE (SharedPointer<CViewContainer>);
container->setBackgroundColor (kGreenCColor);
EXPECT (container->getBackgroundColor () == kGreenCColor);
container->setBackgroundColorDrawStyle (kDrawFilledAndStroked);
EXPECT (container->getBackgroundColorDrawStyle () == kDrawFilledAndStroked);
container->setBackgroundColorDrawStyle (kDrawFilled);
EXPECT (container->getBackgroundColorDrawStyle () == kDrawFilled);
container->setBackgroundColorDrawStyle (kDrawStroked);
EXPECT (container->getBackgroundColorDrawStyle () == kDrawStroked);
}
TEST_CASE (CViewContainerTest, BackgroundOffset)
{
auto& container = TEST_SUITE_GET_STORAGE (SharedPointer<CViewContainer>);
container->setBackgroundOffset (CPoint (10, 10));
EXPECT (container->getBackgroundOffset () == CPoint (10, 10));
}
TEST_CASE (CViewContainerTest, GetChildViewsOfType)
{
auto& container = TEST_SUITE_GET_STORAGE (SharedPointer<CViewContainer>);
container->addView (new TestView1 ());
container->addView (new TestView2 ());
std::vector<TestView1*> r;
container->getChildViewsOfType<TestView1> (r);
EXPECT (r.size () == 1);
EXPECT (r[0] == container->getView (0));
std::vector<TestView2*> r2;
container->getChildViewsOfType<TestView2> (r2);
EXPECT (r2.size () == 1);
EXPECT (r2[0] == container->getView (1));
auto c2 = owned (new CViewContainer (CRect (0, 0, 100, 100)));
c2->addView (container);
r.clear ();
c2->getChildViewsOfType<TestView1> (r);
EXPECT (r.size () == 0);
c2->getChildViewsOfType<TestView1> (r, true);
EXPECT (r.size () == 1);
c2->removeView (container, false);
}
TEST_CASE (CViewContainerTest, Iterator)
{
auto& container = TEST_SUITE_GET_STORAGE (SharedPointer<CViewContainer>);
auto v1 = new TestView1 ();
auto v2 = new TestView2 ();
container->addView (v1);
container->addView (v2);
ViewIterator it (container);
EXPECT (*it == v1);
++it;
EXPECT (*it == v2);
--it;
EXPECT (*it == v1);
auto it2 = it++;
EXPECT (*it2 == v1);
EXPECT (*it == v2);
}
TEST_CASE (CViewContainerTest, ReverseIterator)
{
auto& container = TEST_SUITE_GET_STORAGE (SharedPointer<CViewContainer>);
auto v1 = new TestView1 ();
auto v2 = new TestView2 ();
container->addView (v1);
container->addView (v2);
ReverseViewIterator it (container);
EXPECT (*it == v2);
++it;
EXPECT (*it == v1);
--it;
EXPECT (*it == v2);
auto it2 = it++;
EXPECT (*it2 == v2);
EXPECT (*it == v1);
++it;
EXPECT (*it == nullptr);
}
TEST_CASE (CViewContainerTest, MouseEventsInEmptyContainer)
{
auto& container = TEST_SUITE_GET_STORAGE (SharedPointer<CViewContainer>);
EXPECT_EQ (dispatchMouseEvent<MouseDownEvent> (container, {}), EventConsumeState::NotHandled);
EXPECT_EQ (dispatchMouseEvent<MouseMoveEvent> (container, {}), EventConsumeState::NotHandled);
EXPECT_EQ (dispatchMouseEvent<MouseUpEvent> (container, {}), EventConsumeState::NotHandled);
EXPECT_EQ (dispatchMouseCancelEvent (container), EventConsumeState::NotHandled);
EXPECT_EQ (dispatchMouseWheelEvent (container, {}, 1., 0.), EventConsumeState::NotHandled);
}
TEST_CASE (CViewContainerTest, MouseEvents)
{
auto& container = TEST_SUITE_GET_STORAGE (SharedPointer<CViewContainer>);
auto v1 = new MouseEventCheckView ();
auto v2 = new MouseEventCheckView ();
CRect r1 (0, 0, 50, 50);
CRect r2 (50, 0, 100, 50);
v1->setViewSize (r1);
v1->setMouseableArea (r1);
v2->setViewSize (r2);
v2->setMouseableArea (r2);
container->addView (v1);
container->addView (v2);
EXPECT_EQ (dispatchMouseEvent<MouseDownEvent> (container, {10., 10.}, MouseButton::Left),
EventConsumeState::Handled);
EXPECT_TRUE (v1->mouseDownCalled);
EXPECT_FALSE (v2->mouseDownCalled);
EXPECT_EQ (dispatchMouseEvent<MouseMoveEvent> (container, {10., 10.}, MouseButton::Left),
EventConsumeState::Handled);
EXPECT_TRUE (v1->mouseMovedCalled);
EXPECT_FALSE (v2->mouseMovedCalled);
EXPECT_EQ (dispatchMouseEvent<MouseUpEvent> (container, {10., 10.}, MouseButton::Left),
EventConsumeState::Handled);
EXPECT_TRUE (v1->mouseUpCalled);
EXPECT_FALSE (v2->mouseUpCalled);
EXPECT_EQ (dispatchMouseWheelEvent (container, {60., 10.}, 0.5, 0.),
EventConsumeState::Handled);
EXPECT_FALSE (v1->onWheelCalled);
EXPECT_TRUE (v2->onWheelCalled);
}
TEST_CASE (CViewContainerTest, MouseCancel)
{
auto& container = TEST_SUITE_GET_STORAGE (SharedPointer<CViewContainer>);
auto v1 = new MouseEventCheckView ();
CRect r1 (0, 0, 50, 50);
v1->setViewSize (r1);
v1->setMouseableArea (r1);
container->addView (v1);
EXPECT_EQ (dispatchMouseEvent<MouseDownEvent> (container, {10., 10.}, MouseButton::Left),
EventConsumeState::Handled);
EXPECT_TRUE (v1->mouseDownCalled);
EXPECT_EQ (dispatchMouseCancelEvent (container), EventConsumeState::Handled);
EXPECT_TRUE (v1->mouseCancelCalled);
}
TEST_CASE (CViewContainerTest, DragEvents)
{
auto& container = TEST_SUITE_GET_STORAGE (SharedPointer<CViewContainer>);
auto v1 = new MouseEventCheckView ();
auto v2 = new MouseEventCheckView ();
CRect r1 (0, 0, 50, 50);
CRect r2 (50, 0, 100, 50);
v1->setViewSize (r1);
v1->setMouseableArea (r1);
v2->setViewSize (r2);
v2->setMouseableArea (r2);
container->addView (v1);
container->addView (v2);
DragEventData data;
data.drag = nullptr;
data.pos = CPoint (10, 10);
data.modifiers.clear ();
auto dropTarget = container->getDropTarget ();
dropTarget->onDragEnter (data);
EXPECT (v1->onDragEnterCalled);
EXPECT (v2->onDragEnterCalled == false);
dropTarget->onDragMove (data);
EXPECT (v1->onDragMoveCalled);
EXPECT (v2->onDragMoveCalled == false);
dropTarget->onDragLeave (data);
EXPECT (v1->onDragLeaveCalled);
EXPECT (v2->onDragLeaveCalled == false);
}
TEST_CASE (CViewContainerTest, DragMoveBetweenTwoViews)
{
auto& container = TEST_SUITE_GET_STORAGE (SharedPointer<CViewContainer>);
auto v1 = new MouseEventCheckView ();
auto v2 = new MouseEventCheckView ();
CRect r1 (0, 0, 50, 50);
CRect r2 (50, 0, 100, 50);
v1->setViewSize (r1);
v1->setMouseableArea (r1);
v2->setViewSize (r2);
v2->setMouseableArea (r2);
container->addView (v1);
container->addView (v2);
DragEventData data;
data.drag = nullptr;
data.pos = CPoint (10, 10);
data.modifiers.clear ();
auto dropTarget = container->getDropTarget ();
dropTarget->onDragEnter (data);
EXPECT (v1->onDragEnterCalled);
EXPECT (v2->onDragEnterCalled == false);
data.pos (60, 10);
dropTarget->onDragMove (data);
EXPECT (v1->onDragLeaveCalled);
EXPECT (v2->onDragEnterCalled);
}
TEST_CASE (CViewContainerTest,
MouseDownOnTransparentViewWithoutMouseSupportHidingSubviewWithMouseSupport)
{
auto& container = TEST_SUITE_GET_STORAGE (SharedPointer<CViewContainer>);
CRect r1 (0, 0, 50, 50);
auto v1 = new MouseEventCheckView ();
auto v2 = new CView (r1);
v2->setTransparency (false);
v1->setViewSize (r1);
v1->setMouseableArea (r1);
container->addView (v1);
container->addView (v2);
EXPECT_EQ (dispatchMouseEvent<MouseDownEvent> (container, {10., 10.}, MouseButton::Left),
EventConsumeState::NotHandled);
EXPECT_FALSE (v1->mouseDownCalled);
EXPECT_EQ (dispatchMouseEvent<MouseMoveEvent> (container, {10., 10.}, MouseButton::Left),
EventConsumeState::NotHandled);
EXPECT_FALSE (v1->mouseMovedCalled);
EXPECT_EQ (dispatchMouseEvent<MouseUpEvent> (container, {10., 10.}, MouseButton::Left),
EventConsumeState::NotHandled);
EXPECT_FALSE (v1->mouseUpCalled);
}
TEST_CASE (CViewContainerTest, GetViewsAt)
{
auto& container = TEST_SUITE_GET_STORAGE (SharedPointer<CViewContainer>);
auto v1 = new TestView1 ();
auto v2 = new TestView1 ();
auto c1 = new CViewContainer (CRect (0, 0, 10, 10));
auto v1c1 = new TestView1 ();
v1c1->setVisible (false);
auto v2c1 = new TestView1 ();
c1->addView (v1c1);
c1->addView (v2c1);
v2->setMouseEnabled (false);
container->addView (v1);
container->addView (v2);
container->addView (c1);
CViewContainer::ViewList views;
container->getViewsAt (CPoint (0, 0), views, GetViewOptions (GetViewOptions::kNone));
EXPECT (views.size () == 2);
views.clear ();
container->getViewsAt (CPoint (0, 0), views, GetViewOptions (GetViewOptions::kMouseEnabled));
EXPECT (views.size () == 1);
views.clear ();
container->getViewsAt (CPoint (0, 0), views,
GetViewOptions (GetViewOptions::kIncludeViewContainer));
EXPECT (views.size () == 3);
views.clear ();
container->getViewsAt (CPoint (0, 0), views, GetViewOptions (GetViewOptions::kDeep));
EXPECT (views.size () == 3);
views.clear ();
container->getViewsAt (
CPoint (0, 0), views,
GetViewOptions (GetViewOptions::kDeep | GetViewOptions::kIncludeInvisible));
EXPECT (views.size () == 4);
}
TEST_CASE (CViewContainerTest, GetContainerAt)
{
auto& container = TEST_SUITE_GET_STORAGE (SharedPointer<CViewContainer>);
auto c1 = new CViewContainer (CRect (0, 0, 10, 10));
auto c2 = new CViewContainer (CRect (0, 0, 10, 10));
auto c3 = new CViewContainer (CRect (0, 0, 10, 10));
c2->setMouseEnabled (false);
c3->setVisible (false);
c2->addView (c3);
container->addView (c1);
container->addView (c2);
auto res = container->getContainerAt (CPoint (0, 0), GetViewOptions (GetViewOptions::kNone));
EXPECT (res == container);
res = container->getContainerAt (CPoint (0, 0), GetViewOptions (GetViewOptions::kDeep));
EXPECT (res == c2);
res = container->getContainerAt (
CPoint (0, 0), GetViewOptions (GetViewOptions::kDeep | GetViewOptions::kIncludeInvisible));
EXPECT (res == c3);
res = container->getContainerAt (
CPoint (0, 0), GetViewOptions (GetViewOptions::kDeep | GetViewOptions::kMouseEnabled));
EXPECT (res == c1);
}
} // namespaces
@@ -0,0 +1,205 @@
// This file is part of VSTGUI. It is subject to the license terms
// in the LICENSE file found in the top-level directory of this
// distribution and at http://github.com/steinbergmedia/vstgui/LICENSE
#include "../../../lib/enumbitset.h"
#include "../unittests.h"
//------------------------------------------------------------------------
namespace VSTGUI {
//------------------------------------------------------------------------
enum class Flag
{
One,
Two,
Three,
};
using Flags = EnumBitset<Flag>;
//------------------------------------------------------------------------
enum class FlagMask : uint8_t
{
One = 1 << 0,
Two = 1 << 1,
Three = 1 << 2,
};
using FlagMasks = EnumBitset<FlagMask, true>;
//------------------------------------------------------------------------
TEST_CASE (EnumBitsetTest, InitTest)
{
{
Flags f;
EXPECT_EQ (f.value (), 0);
}
{
Flags f (Flag::Two);
EXPECT_EQ (f.value (), 2);
}
{
Flags f ({Flag::One, Flag::Two});
EXPECT_EQ (f.value (), 3);
}
{
FlagMasks f;
EXPECT_EQ (f.value (), 0);
}
{
FlagMasks f (FlagMask::Two);
EXPECT_EQ (f.value (), 2);
}
{
FlagMasks f ({FlagMask::One, FlagMask::Two});
EXPECT_EQ (f.value (), 3);
}
}
//------------------------------------------------------------------------
TEST_CASE (EnumBitsetTest, AssignmentTest)
{
{
Flags f;
f = Flag::One;
EXPECT_EQ (f.value (), 1);
Flags f2 = Flag::Two;
EXPECT_EQ (f2.value (), 2);
f = f2;
EXPECT_EQ (f.value (), f2.value ());
f2.exlusive (Flag::Three);
EXPECT_EQ (f2.value (), 4);
}
{
FlagMasks f;
f = FlagMask::One;
EXPECT_EQ (f.value (), 1);
FlagMasks f2 = FlagMask::Two;
EXPECT_EQ (f2.value (), 2);
f = f2;
EXPECT_EQ (f.value (), f2.value ());
f2.exlusive (FlagMask::Three);
EXPECT_EQ (f2.value (), 4);
}
}
//------------------------------------------------------------------------
TEST_CASE (EnumBitsetTest, AddRemoveTest)
{
{
Flags f;
f.add (Flag::One);
EXPECT_EQ (f.value (), 1);
f.add (Flag::Two);
EXPECT_EQ (f.value (), 3);
f.remove (Flag::One);
EXPECT_EQ (f.value (), 2);
f.clear ();
f |= Flag::One;
EXPECT_EQ (f.value (), 1);
f |= Flag::Two;
EXPECT_EQ (f.value (), 3);
f ^= Flag::One;
EXPECT_EQ (f.value (), 2);
f.clear ();
f << Flag::One;
EXPECT_EQ (f.value (), 1);
f << Flag::Two;
EXPECT_EQ (f.value (), 3);
f >> Flag::One;
EXPECT_EQ (f.value (), 2);
}
{
FlagMasks f;
f.add (FlagMask::One);
EXPECT_EQ (f.value (), 1);
f.add (FlagMask::Two);
EXPECT_EQ (f.value (), 3);
f.remove (FlagMask::One);
EXPECT_EQ (f.value (), 2);
f.clear ();
f |= FlagMask::One;
EXPECT_EQ (f.value (), 1);
f |= FlagMask::Two;
EXPECT_EQ (f.value (), 3);
f ^= FlagMask::One;
EXPECT_EQ (f.value (), 2);
f.clear ();
f << FlagMask::One;
EXPECT_EQ (f.value (), 1);
f << FlagMask::Two;
EXPECT_EQ (f.value (), 3);
f >> FlagMask::One;
EXPECT_EQ (f.value (), 2);
}
}
//------------------------------------------------------------------------
TEST_CASE (EnumBitsetTest, OperatorTest)
{
{
Flags f1 = Flag::One;
Flags f2 ({Flag::Two, Flag::Three});
auto f3 = f1 | Flag::Two;
EXPECT_EQ (f3.value (), 3);
EXPECT_TRUE (f3 & Flag::One);
EXPECT_TRUE (f3 & Flag::Two);
}
{
FlagMasks f1 = FlagMask::One;
FlagMasks f2 ({FlagMask::Two, FlagMask::Three});
auto f3 = f1 | FlagMask::Two;
EXPECT_EQ (f3.value (), 3);
EXPECT_TRUE (f3 & FlagMask::One);
EXPECT_TRUE (f3 & FlagMask::Two);
}
}
//------------------------------------------------------------------------
TEST_CASE (EnumBitsetTest, EqualityTest)
{
{
Flags f1 ({Flag::One, Flag::Three});
Flags f2 ({Flag::Two, Flag::Three});
Flags f3 ({Flag::Three, Flag::One});
EXPECT_TRUE (f1 != f2);
EXPECT_TRUE (f1 == f3);
EXPECT_TRUE (f1.test (Flag::One));
EXPECT_FALSE (f1.test (Flag::Two));
}
{
FlagMasks f1 ({FlagMask::One, FlagMask::Three});
FlagMasks f2 ({FlagMask::Two, FlagMask::Three});
FlagMasks f3 ({FlagMask::Three, FlagMask::One});
EXPECT_TRUE (f1 != f2);
EXPECT_TRUE (f1 == f3);
EXPECT_TRUE (f1.test (FlagMask::One));
EXPECT_FALSE (f1.test (FlagMask::Two));
}
}
//------------------------------------------------------------------------
} // VSTGUI
@@ -0,0 +1,213 @@
// This file is part of VSTGUI. It is subject to the license terms
// in the LICENSE file found in the top-level directory of this
// distribution and at http://github.com/steinbergmedia/vstgui/LICENSE
#include "../../../lib/events.h"
#include "../unittests.h"
//------------------------------------------------------------------------
namespace VSTGUI {
TEST_CASE (EventTest, UniqueIDTest)
{
Event e1;
Event e2;
EXPECT_NE (e1.id, e2.id);
}
TEST_CASE (EventTest, DefaultConstructorTypeTest)
{
MouseEnterEvent enterEvent;
EXPECT_EQ (enterEvent.type, EventType::MouseEnter);
MouseExitEvent exitEvent;
EXPECT_EQ (exitEvent.type, EventType::MouseExit);
MouseDownEvent downEvent;
EXPECT_EQ (downEvent.type, EventType::MouseDown);
MouseMoveEvent moveEvent;
EXPECT_EQ (moveEvent.type, EventType::MouseMove);
MouseUpEvent upEvent;
EXPECT_EQ (upEvent.type, EventType::MouseUp);
MouseCancelEvent cancelEvent;
EXPECT_EQ (cancelEvent.type, EventType::MouseCancel);
MouseWheelEvent wheelEvent;
EXPECT_EQ (wheelEvent.type, EventType::MouseWheel);
ZoomGestureEvent zoomGestureEvent;
EXPECT_EQ (zoomGestureEvent.type, EventType::ZoomGesture);
KeyboardEvent keyEvent;
EXPECT_EQ (keyEvent.type, EventType::KeyDown);
}
TEST_CASE (EventTest, NoEventTest)
{
auto& event = noEvent ();
EXPECT_EQ (event.type, EventType::Unknown);
}
TEST_CASE (EventTest, ConsumedTest)
{
EventConsumeState consumed;
EXPECT_FALSE (consumed);
consumed = true;
EXPECT_TRUE (consumed);
consumed = false;
EXPECT_FALSE (consumed);
consumed = true;
EXPECT_TRUE (consumed);
consumed.reset ();
EXPECT_FALSE (consumed);
}
TEST_CASE (EventTest, CastMouseEnterEventTest)
{
MouseEnterEvent event;
Event& e = event;
EXPECT_EQ (asMousePositionEvent (e), &e);
EXPECT_EQ (asMouseEvent (e), &e);
EXPECT_EQ (asMouseDownEvent (e), nullptr);
EXPECT_EQ (asModifierEvent (e), &e);
EXPECT_EQ (asKeyboardEvent (e), nullptr);
}
TEST_CASE (EventTest, CastMouseExitEventTest)
{
MouseExitEvent event;
Event& e = event;
EXPECT_EQ (asMousePositionEvent (e), &e);
EXPECT_EQ (asMouseEvent (e), &e);
EXPECT_EQ (asMouseDownEvent (e), nullptr);
EXPECT_EQ (asModifierEvent (e), &e);
EXPECT_EQ (asKeyboardEvent (e), nullptr);
}
TEST_CASE (EventTest, CastMouseDownEventTest)
{
MouseDownEvent event;
Event& e = event;
EXPECT_EQ (asMousePositionEvent (e), &e);
EXPECT_EQ (asMouseEvent (e), &e);
EXPECT_EQ (asMouseDownEvent (e), &e);
EXPECT_EQ (asModifierEvent (e), &e);
EXPECT_EQ (asKeyboardEvent (e), nullptr);
}
TEST_CASE (EventTest, CastMouseMoveEventTest)
{
MouseMoveEvent event;
Event& e = event;
EXPECT_EQ (asMousePositionEvent (e), &e);
EXPECT_EQ (asMouseEvent (e), &e);
EXPECT_EQ (asMouseDownEvent (e), &e);
EXPECT_EQ (asModifierEvent (e), &e);
EXPECT_EQ (asKeyboardEvent (e), nullptr);
}
TEST_CASE (EventTest, CastMouseUpEventTest)
{
MouseUpEvent event;
Event& e = event;
EXPECT_EQ (asMousePositionEvent (e), &e);
EXPECT_EQ (asMouseEvent (e), &e);
EXPECT_EQ (asMouseDownEvent (e), &e);
EXPECT_EQ (asModifierEvent (e), &e);
EXPECT_EQ (asKeyboardEvent (e), nullptr);
}
TEST_CASE (EventTest, CastMouseCancelEventTest)
{
MouseCancelEvent event;
Event& e = event;
EXPECT_EQ (asMousePositionEvent (e), nullptr);
EXPECT_EQ (asMouseEvent (e), nullptr);
EXPECT_EQ (asMouseDownEvent (e), nullptr);
EXPECT_EQ (asModifierEvent (e), nullptr);
EXPECT_EQ (asKeyboardEvent (e), nullptr);
}
TEST_CASE (EventTest, CastMouseWheelEventTest)
{
MouseWheelEvent event;
Event& e = event;
EXPECT_EQ (asMousePositionEvent (e), &e);
EXPECT_EQ (asMouseEvent (e), nullptr);
EXPECT_EQ (asMouseDownEvent (e), nullptr);
EXPECT_EQ (asModifierEvent (e), &e);
EXPECT_EQ (asKeyboardEvent (e), nullptr);
}
TEST_CASE (EventTest, CastZoomGestureEventTest)
{
ZoomGestureEvent event;
Event& e = event;
EXPECT_EQ (asMousePositionEvent (e), &e);
EXPECT_EQ (asMouseEvent (e), nullptr);
EXPECT_EQ (asMouseDownEvent (e), nullptr);
EXPECT_EQ (asModifierEvent (e), nullptr);
EXPECT_EQ (asKeyboardEvent (e), nullptr);
}
TEST_CASE (EventTest, CastKeyboardEventTest)
{
KeyboardEvent event;
Event& e = event;
EXPECT_EQ (asMousePositionEvent (e), nullptr);
EXPECT_EQ (asMouseEvent (e), nullptr);
EXPECT_EQ (asMouseDownEvent (e), nullptr);
EXPECT_EQ (asModifierEvent (e), &e);
EXPECT_EQ (asKeyboardEvent (e), &e);
}
TEST_CASE (EventTest, ButtonStateFromEventModifierTest)
{
Modifiers mods;
EXPECT_EQ (buttonStateFromEventModifiers (mods), 0);
mods.add (ModifierKey::Control);
EXPECT_EQ (buttonStateFromEventModifiers (mods), kControl);
mods.add (ModifierKey::Shift);
EXPECT_EQ (buttonStateFromEventModifiers (mods), kControl | kShift);
mods.add (ModifierKey::Alt);
EXPECT_EQ (buttonStateFromEventModifiers (mods), kControl | kShift | kAlt);
}
TEST_CASE (EventTest, ButtonStateFromMouseEventTest)
{
MouseDownEvent event;
EXPECT_EQ (buttonStateFromMouseEvent (event), 0);
event.buttonState.set (MouseButton::Left);
EXPECT_EQ (buttonStateFromMouseEvent (event), kLButton);
event.buttonState.set (MouseButton::Right);
EXPECT_EQ (buttonStateFromMouseEvent (event), kRButton);
event.buttonState.set (MouseButton::Middle);
EXPECT_EQ (buttonStateFromMouseEvent (event), kMButton);
event.buttonState.set (MouseButton::Fourth);
EXPECT_EQ (buttonStateFromMouseEvent (event), kButton4);
event.buttonState.set (MouseButton::Fifth);
EXPECT_EQ (buttonStateFromMouseEvent (event), kButton5);
event.clickCount = 2;
event.buttonState.set (MouseButton::Left);
EXPECT_EQ (buttonStateFromMouseEvent (event), kLButton | kDoubleClick);
event.modifiers.add (ModifierKey::Shift);
EXPECT_EQ (buttonStateFromMouseEvent (event), kLButton | kDoubleClick | kShift);
}
TEST_CASE (EventTest, IgnoreFollowUpEvent)
{
MouseDownEvent e;
EXPECT_FALSE (e.ignoreFollowUpMoveAndUpEvents ());
e.ignoreFollowUpMoveAndUpEvents (true);
EXPECT_TRUE (e.ignoreFollowUpMoveAndUpEvents ());
EXPECT_FALSE (e.consumed);
e.consumed = true;
EXPECT_TRUE (e.ignoreFollowUpMoveAndUpEvents ());
EXPECT_TRUE (e.consumed);
}
TEST_CASE (EventTest, ModifiersEquality)
{
Modifiers altMod (ModifierKey::Alt);
Modifiers ctrlMod (ModifierKey::Control);
EXPECT_FALSE ((altMod == ctrlMod));
EXPECT_TRUE ((altMod != ctrlMod));
}
//------------------------------------------------------------------------
} // VSTGUI
@@ -0,0 +1,45 @@
// This file is part of VSTGUI. It is subject to the license terms
// in the LICENSE file found in the top-level directory of this
// distribution and at http://github.com/steinbergmedia/vstgui/LICENSE
#include "../../../lib/events.h"
//------------------------------------------------------------------------
namespace VSTGUI {
//------------------------------------------------------------------------
template <typename EventType>
inline uint32_t dispatchMouseEvent (CView* view, CPoint pos, MouseEventButtonState buttons = {},
Modifiers mods = {})
{
EventType event;
event.mousePosition = pos;
event.buttonState = buttons;
event.modifiers = mods;
view->dispatchEvent (event);
return event.consumed.data;
}
//------------------------------------------------------------------------
inline uint32_t dispatchMouseCancelEvent (CView* view)
{
MouseCancelEvent event;
view->dispatchEvent (event);
return event.consumed.data;
}
//------------------------------------------------------------------------
inline uint32_t dispatchMouseWheelEvent (CView* view, CPoint pos, double deltaX, double deltaY,
Modifiers mods = {})
{
MouseWheelEvent event;
event.mousePosition = pos;
event.deltaX = deltaX;
event.deltaY = deltaY;
event.modifiers = mods;
view->dispatchEvent (event);
return event.consumed.data;
}
//------------------------------------------------------------------------
} // VSTGUI
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,76 @@
// This file is part of VSTGUI. It is subject to the license terms
// in the LICENSE file found in the top-level directory of this
// distribution and at http://github.com/steinbergmedia/vstgui/LICENSE
#include "../unittests.h"
#if VSTGUI_ENABLE_DEPRECATED_METHODS
#include "../../../lib/private/disabledeprecatedmessage.h"
#include "../../../lib/idependency.h"
namespace VSTGUI {
class DependentObject : public CBaseObject, public IDependency
{
public:
DependentObject () : notifyCalledCount (0) {}
CMessageResult notify (CBaseObject* sender, IdStringPtr message) override
{
notifyCalledCount++;
return kMessageNotified;
}
int32_t notifyCalledCount;
};
class TestObject : public CBaseObject, public IDependency
{
public:
TestObject () {}
};
TEST_CASE (IDependencyTest, SimpleDependency)
{
DependentObject dObj;
TestObject tObj;
tObj.addDependency (&dObj);
tObj.changed ("Test");
EXPECT (dObj.notifyCalledCount == 1)
tObj.removeDependency (&dObj);
}
TEST_CASE (IDependencyTest, SimpleDeferedDependency)
{
DependentObject dObj;
TestObject tObj;
tObj.addDependency (&dObj);
tObj.deferChanges (true);
tObj.changed ("Test");
EXPECT (dObj.notifyCalledCount == 0)
tObj.deferChanges (false);
EXPECT (dObj.notifyCalledCount == 1)
tObj.removeDependency (&dObj);
}
TEST_CASE (IDependencyTest, SimpleDeferChanges)
{
DependentObject dObj;
TestObject tObj;
tObj.addDependency (&dObj);
{
IDependency::DeferChanges df (&tObj);
IdStringPtr messageID = "Test";
tObj.changed (messageID);
tObj.changed (messageID);
EXPECT (dObj.notifyCalledCount == 0)
}
EXPECT (dObj.notifyCalledCount == 1)
tObj.removeDependency (&dObj);
}
} // VSTGUI
#include "../../../lib/private/enabledeprecatedmessage.h"
#endif // VSTGUI_ENABLE_DEPRECATED_METHODS
@@ -0,0 +1,95 @@
// This file is part of VSTGUI. It is subject to the license terms
// in the LICENSE file found in the top-level directory of this
// distribution and at http://github.com/steinbergmedia/vstgui/LICENSE
#include "../../../lib/pixelbuffer.h"
#include "../unittests.h"
namespace VSTGUI {
using namespace PixelBuffer;
TEST_CASE (PixelBufferTest, ARGB_2_RGBA)
{
uint32_t pixel = 0x11223344;
convert (Format::ARGB, Format::RGBA, reinterpret_cast<uint8_t*> (&pixel), 4, 1, 1);
EXPECT (pixel == 0x22334411);
}
TEST_CASE (PixelBufferTest, ARGB_2_BGRA)
{
uint32_t pixel = 0x11223344;
convert (Format::ARGB, Format::BGRA, reinterpret_cast<uint8_t*> (&pixel), 4, 1, 1);
EXPECT (pixel == 0x44332211);
}
TEST_CASE (PixelBufferTest, ARGB_2_ABGR)
{
uint32_t pixel = 0x11223344;
convert (Format::ARGB, Format::ABGR, reinterpret_cast<uint8_t*> (&pixel), 4, 1, 1);
EXPECT (pixel == 0x11443322);
}
TEST_CASE (PixelBufferTest, ABGR_2_ARGB)
{
uint32_t pixel = 0x11223344;
convert (Format::ABGR, Format::ARGB, reinterpret_cast<uint8_t*> (&pixel), 4, 1, 1);
EXPECT (pixel == 0x11443322);
}
TEST_CASE (PixelBufferTest, ABGR_2_RGBA)
{
uint32_t pixel = 0x11223344;
convert (Format::ABGR, Format::RGBA, reinterpret_cast<uint8_t*> (&pixel), 4, 1, 1);
EXPECT (pixel == 0x44332211);
}
TEST_CASE (PixelBufferTest, ABGR_2_BGRA)
{
uint32_t pixel = 0x11223344;
convert (Format::ABGR, Format::BGRA, reinterpret_cast<uint8_t*> (&pixel), 4, 1, 1);
EXPECT (pixel == 0x22334411);
}
TEST_CASE (PixelBufferTest, RGBA_2_ARGB)
{
uint32_t pixel = 0x11223344;
convert (Format::RGBA, Format::ARGB, reinterpret_cast<uint8_t*> (&pixel), 4, 1, 1);
EXPECT (pixel == 0x22334411);
}
TEST_CASE (PixelBufferTest, RGBA_2_ABGR)
{
uint32_t pixel = 0x11223344;
convert (Format::RGBA, Format::ABGR, reinterpret_cast<uint8_t*> (&pixel), 4, 1, 1);
EXPECT (pixel == 0x44332211);
}
TEST_CASE (PixelBufferTest, RGBA_2_BGRA)
{
uint32_t pixel = 0x11223344;
convert (Format::RGBA, Format::BGRA, reinterpret_cast<uint8_t*> (&pixel), 4, 1, 1);
EXPECT (pixel == 0x11443322);
}
TEST_CASE (PixelBufferTest, BGRA_2_RGBA)
{
uint32_t pixel = 0x11223344;
convert (Format::BGRA, Format::RGBA, reinterpret_cast<uint8_t*> (&pixel), 4, 1, 1);
EXPECT (pixel == 0x33221144);
}
TEST_CASE (PixelBufferTest, BGRA_2_ABGR)
{
uint32_t pixel = 0x11223344;
convert (Format::BGRA, Format::ABGR, reinterpret_cast<uint8_t*> (&pixel), 4, 1, 1);
EXPECT (pixel == 0x22334411);
}
TEST_CASE (PixelBufferTest, BGRA_2_ARGB)
{
uint32_t pixel = 0x11223344;
convert (Format::BGRA, Format::ARGB, reinterpret_cast<uint8_t*> (&pixel), 4, 1, 1);
EXPECT (pixel == 0x44332211);
}
} // namespace VSTGUI
@@ -0,0 +1,22 @@
// This file is part of VSTGUI. It is subject to the license terms
// in the LICENSE file found in the top-level directory of this
// distribution and at http://github.com/steinbergmedia/vstgui/LICENSE
#include "../../../lib/vstguibase.h"
#include "../../../lib/platform/iplatformframe.h"
namespace VSTGUI {
namespace UnitTest {
struct PlatformParentHandle : public CBaseObject
{
static SharedPointer<PlatformParentHandle> create ();
virtual PlatformType getType () const = 0;
virtual void* getHandle () const = 0;
virtual void forceRedraw () = 0;
};
} // UnitTest
} // VSTGUI
@@ -0,0 +1,32 @@
// This file is part of VSTGUI. It is subject to the license terms
// in the LICENSE file found in the top-level directory of this
// distribution and at http://github.com/steinbergmedia/vstgui/LICENSE
#include "platform_helper.h"
namespace VSTGUI {
namespace UnitTest {
SharedPointer<PlatformParentHandle> PlatformParentHandle::create ()
{
return nullptr;
}
PlatformType PlatformParentHandle::getType () const
{
return PlatformType::kX11EmbedWindowID;
}
void* PlatformParentHandle::getHandle () const
{
return nullptr;
}
void PlatformParentHandle::forceRedraw ()
{
}
} // UnitTest
} // VSTGUI
@@ -0,0 +1,58 @@
// This file is part of VSTGUI. It is subject to the license terms
// in the LICENSE file found in the top-level directory of this
// distribution and at http://github.com/steinbergmedia/vstgui/LICENSE
#include "platform_helper.h"
#import <Cocoa/Cocoa.h>
namespace VSTGUI {
namespace UnitTest {
struct MacParentHandle : PlatformParentHandle
{
NSWindow* window {nil};
MacParentHandle ()
{
NSWindowStyleMask style;
#if MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_12
style = NSWindowStyleMaskTitled;
#else
style = NSTitledWindowMask;
#endif
window = [[NSWindow alloc] initWithContentRect:NSMakeRect (0, 0, 100, 100)
styleMask:style
backing:NSBackingStoreBuffered
defer:NO];
}
~MacParentHandle () override
{
[window release];
}
PlatformType getType () const override
{
return PlatformType::kNSView;
}
void* getHandle () const override
{
return window.contentView;
}
void forceRedraw () override
{
[window displayIfNeeded];
}
};
SharedPointer<PlatformParentHandle> PlatformParentHandle::create ()
{
return owned (dynamic_cast<PlatformParentHandle*> (new MacParentHandle ()));
}
} // UnitTest
} // VSTGUI
@@ -0,0 +1,85 @@
// This file is part of VSTGUI. It is subject to the license terms
// in the LICENSE file found in the top-level directory of this
// distribution and at http://github.com/steinbergmedia/vstgui/LICENSE
#include "platform_helper.h"
#include "../../../lib/platform/win32/win32support.h"
#include <windows.h>
namespace VSTGUI {
namespace UnitTest {
static LRESULT CALLBACK MainWndProc (HWND h, UINT m , WPARAM w, LPARAM l)
{
return DefWindowProc (h, m, w, l);
}
BOOL InitApplication(HINSTANCE hinstance)
{
WNDCLASSEX wcx;
// Fill in the window class structure with parameters
// that describe the main window.
wcx.cbSize = sizeof(wcx); // size of structure
wcx.style = CS_HREDRAW |
CS_VREDRAW; // redraw if size changes
wcx.lpfnWndProc = MainWndProc; // points to window procedure
wcx.cbClsExtra = 0; // no extra class memory
wcx.cbWndExtra = 0; // no extra window memory
wcx.hInstance = hinstance; // handle to instance
wcx.hIcon = LoadIcon(NULL,
IDI_APPLICATION); // predefined app. icon
wcx.hCursor = LoadCursor(NULL,
IDC_ARROW); // predefined arrow
wcx.hbrBackground = nullptr; // white background brush
wcx.lpszMenuName = nullptr; // name of menu resource
wcx.lpszClassName = L"MainWClass"; // name of window class
wcx.hIconSm = nullptr;
// Register the window class.
return RegisterClassEx(&wcx);
}
struct Initializer
{
static Initializer& instance ()
{
static Initializer gInstance;
return gInstance;
}
Initializer ()
{
InitApplication (GetInstance ());
}
};
struct WinPlatformHandle : PlatformParentHandle
{
HWND window{ nullptr };
WinPlatformHandle ()
{
Initializer::instance ();
window = CreateWindow (L"MainWClass", L"Test", WS_OVERLAPPEDWINDOW, 0, 0, 100, 100, nullptr, nullptr, GetInstance (), 0);
}
~WinPlatformHandle ()
{
DestroyWindow (window);
}
PlatformType getType () const override { return PlatformType::kHWND; }
void* getHandle () const override { return window; };
void forceRedraw () override {};
};
SharedPointer<PlatformParentHandle> PlatformParentHandle::create()
{
return owned (dynamic_cast<PlatformParentHandle*> (new WinPlatformHandle ()));
}
} // UnitTest
} // VSTGUI
@@ -0,0 +1,68 @@
// This file is part of VSTGUI. It is subject to the license terms
// in the LICENSE file found in the top-level directory of this
// distribution and at http://github.com/steinbergmedia/vstgui/LICENSE
#include "../../../lib/tasks.h"
#include "../unittests.h"
#include <atomic>
#include <thread>
//------------------------------------------------------------------------
namespace VSTGUI {
//------------------------------------------------------------------------
TEST_SUITE_SETUP (SerialQueueTest)
{
TEST_SUITE_SET_STORAGE (Tasks::Queue, Tasks::makeSerialQueue ("Test Serial Queue"));
}
//------------------------------------------------------------------------
TEST_SUITE_TEARDOWN (SerialQueueTest)
{
Tasks::releaseSerialQueue (TEST_SUITE_GET_STORAGE (Tasks::Queue));
}
//------------------------------------------------------------------------
TEST_CASE (SerialQueueTest, Validation)
{
const auto& serialQueue = TEST_SUITE_GET_STORAGE (Tasks::Queue);
EXPECT_NE (serialQueue, Tasks::InvalidQueue);
}
//------------------------------------------------------------------------
TEST_CASE (SerialQueueTest, SimpleTasks)
{
uint32_t numIterations = 1000u;
uint32_t counter {0u};
const auto& serialQueue = TEST_SUITE_GET_STORAGE (Tasks::Queue);
auto increaseCounterFunc = [&] () {
++counter;
std::this_thread::yield ();
};
for (auto i = 0u; i < numIterations; ++i)
Tasks::schedule (serialQueue, increaseCounterFunc);
Tasks::waitAllTasksExecuted (serialQueue);
EXPECT_EQ (counter, numIterations)
}
//------------------------------------------------------------------------
TEST_CASE (SerialQueueTest, scheduleSerialTasksOnBackgroundQueue)
{
uint32_t numIterations = 1000u;
uint32_t counter {0u};
const auto& serialQueue = TEST_SUITE_GET_STORAGE (Tasks::Queue);
auto increaseCounterFunc = [&] () {
++counter;
};
for (auto i = 0u; i < numIterations; ++i)
{
Tasks::schedule (Tasks::backgroundQueue (),
[&] () { Tasks::schedule (serialQueue, increaseCounterFunc); });
}
Tasks::waitAllTasksExecuted (Tasks::backgroundQueue ());
Tasks::waitAllTasksExecuted (serialQueue);
EXPECT_EQ (counter, numIterations)
}
//------------------------------------------------------------------------
} // VSTGUI
@@ -0,0 +1,124 @@
// This file is part of VSTGUI. It is subject to the license terms
// in the LICENSE file found in the top-level directory of this
// distribution and at http://github.com/steinbergmedia/vstgui/LICENSE
#include "../../../lib/cstring.h"
#include "../unittests.h"
#if MAC
#include "../../../lib/platform/mac/macstring.h"
#endif
namespace VSTGUI {
TEST_CASE (UTF8StringTest, Empty)
{
UTF8String str;
EXPECT (str.empty ());
EXPECT (str.length () == 0);
}
TEST_CASE (UTF8StringTest, Set)
{
UTF8String str;
EXPECT (str.empty ());
str.assign ("Test");
EXPECT (str.empty () == false);
EXPECT (str.data () == std::string ("Test"));
}
TEST_CASE (UTF8StringTest, EqualOperator)
{
EXPECT (UTF8String ("bla") == "bla");
EXPECT (UTF8String ("bla") != "uhh");
std::string str ("bla");
std::string str2 ("uhh");
EXPECT (UTF8String ("bla") == str);
EXPECT (UTF8String ("bla") != str2);
}
TEST_CASE (UTF8StringTest, SetOperator)
{
UTF8String str;
str = "Test";
EXPECT (str == "Test");
}
TEST_CASE (UTF8StringTest, GetOperator)
{
UTF8String str ("Test");
UTF8StringPtr cstr = str;
EXPECT (cstr == std::string ("Test"));
}
TEST_CASE (UTF8StringTest, CopyOperator)
{
UTF8String str1 ("str");
UTF8String str2 (str1);
EXPECT (str1 == str2);
}
TEST_CASE (UTF8StringTest, MoveOperator)
{
UTF8String str1 ("str");
UTF8String str2 (std::move (str1));
EXPECT (str1 != str2);
}
TEST_CASE (UTF8StringTest, AddOperator)
{
UTF8String str1 ("str");
str1 += "ing";
EXPECT (str1 == "string");
auto str2 = str1 + "1";
EXPECT (str2 == "string1");
EXPECT (str1 == "string");
}
TEST_CASE (UTF8StringTest, Clear)
{
UTF8String str1 ("string");
EXPECT (str1 == "string");
str1.clear ();
EXPECT (str1 == "");
}
TEST_CASE (UTF8StringTest, Copy)
{
UTF8String str1 ("string");
char buffer[3] {1};
str1.copy (buffer, sizeof (buffer));
EXPECT (buffer[0] == 's');
EXPECT (buffer[1] == 't');
EXPECT (buffer[2] == 0);
}
TEST_CASE (UTF8StringTest, CodePointIterator)
{
UTF8String str ("\xc3\x84\xe0\xa5\xb4\xf0\xaa\x80\x9a\0"); // u8"Äॴ𪀚"
auto charCount = 0;
for (auto it = str.begin (); it != str.end (); ++it)
{
charCount++;
}
EXPECT (charCount == 3);
}
#if MAC
TEST_CASE (UTF8StringTest, MacPlatformString)
{
UTF8String str1 ("Test");
auto platformStr = str1.getPlatformString ();
auto macStr = dynamic_cast<MacString*> (platformStr);
EXPECT (macStr);
auto cfStr = macStr->getCFString ();
auto cfStr2 = CFStringCreateWithCString (kCFAllocatorDefault, "Test", kCFStringEncodingUTF8);
EXPECT (CFStringCompare (cfStr, cfStr2, 0) == kCFCompareEqualTo);
CFRelease (cfStr2);
}
#endif
} // VSTGUI
@@ -0,0 +1,128 @@
// This file is part of VSTGUI. It is subject to the license terms
// in the LICENSE file found in the top-level directory of this
// distribution and at http://github.com/steinbergmedia/vstgui/LICENSE
#include "../../../lib/cstring.h"
#include "../unittests.h"
namespace VSTGUI {
static UTF8StringPtr asciiStr = "This is a simple ASCII String";
static UTF8StringPtr utf8Str =
"\xe3\x82\xa4\xe3\x83\xb3\xe3\x82\xbf\xe3\x83\xbc\xe3\x83\x8d\xe3\x83\x83\xe3\x83\x88\xe3\x82\x92\xe3\x82\x82\xe3\x81\xa3\xe3\x81\xa8\xe5\xbf\xab\xe9\x81\xa9\xe3\x81\xab\xe3\x80\x82\0"; // u8"インターネットをもっと快適に。";
TEST_CASE (UTF8StringViewTest, CalculateASCIICharacterCount)
{
UTF8StringView str (asciiStr);
EXPECT (str.calculateCharacterCount () == 29);
}
TEST_CASE (UTF8StringViewTest, CalculateUTF8CharacterCount)
{
UTF8StringView str (utf8Str);
EXPECT (str.calculateCharacterCount () == 15);
UTF8StringView str2 ("\xc3\x84\xe0\xa5\xb4\xf0\xaa\x80\x9a\0"); // u8"Äॴ𪀚"
EXPECT (str2.calculateCharacterCount () == 3);
EXPECT (str2.calculateByteCount () == 10);
}
TEST_CASE (UTF8StringViewTest, CalculateEmptyCharacterCount)
{
UTF8StringView str (nullptr);
EXPECT (str.calculateCharacterCount () == 0);
}
TEST_CASE (UTF8StringViewTest, calculateASCIIByteCount)
{
UTF8StringView str (asciiStr);
EXPECT (str.calculateByteCount () == 30);
}
TEST_CASE (UTF8StringViewTest, calculateUTF8ByteCount)
{
UTF8StringView str (utf8Str);
EXPECT (str.calculateByteCount () == 46);
}
TEST_CASE (UTF8StringViewTest, Contains)
{
UTF8StringView str (asciiStr);
EXPECT (str.contains ("simple") == true);
EXPECT (str.contains ("not") == false);
}
TEST_CASE (UTF8StringViewTest, EndsWith)
{
UTF8StringView str (asciiStr);
EXPECT (str.endsWith ("String") == true);
EXPECT (str.endsWith ("This") == false);
EXPECT (str.endsWith ("This is a simple ASCII String which is longer") == false);
}
TEST_CASE (UTF8StringViewTest, DoubleConversion)
{
UTF8StringView str ("32.56789");
double value = str.toDouble ();
EXPECT (value == 32.56789);
}
TEST_CASE (UTF8StringViewTest, FloatConversion)
{
UTF8StringView str ("32.56789");
float value = str.toFloat ();
EXPECT (value == 32.56789f);
}
TEST_CASE (UTF8StringViewTest, Compare)
{
std::string test ("This is a simple ASCII String");
UTF8StringView str1 (test.data ());
UTF8StringView str2 (asciiStr);
EXPECT (str1 == str2);
UTF8StringView str3 (utf8Str);
EXPECT (str1 != str3);
}
TEST_CASE (UTF8StringViewTest, ContainsCheckCase)
{
UTF8StringView str (asciiStr);
EXPECT (str.contains ("simple"));
EXPECT (str.contains ("Simple") == false);
EXPECT (str.contains ("SiMpLe", true));
}
TEST_CASE (UTF8StringViewTest, StartsWith)
{
UTF8StringView str (asciiStr);
EXPECT (str.startsWith ("This"));
}
TEST_CASE (UTF8StringViewTest, ToDouble)
{
UTF8StringView str ("5.1");
EXPECT (str.toDouble () == 5.1);
}
TEST_CASE (UTF8StringViewTest, ToFloat)
{
UTF8StringView str ("5.1");
EXPECT (str.toFloat () == 5.1f);
}
TEST_CASE (UTF8StringViewTest, toInteger)
{
UTF8StringView str ("5");
EXPECT (str.toInteger () == 5);
}
TEST_CASE (UTF8StringViewTest, toNumber)
{
UTF8StringView str ("300");
auto res = str.toNumber<int32_t> ();
EXPECT (res);
EXPECT (*res == 300);
auto res2 = str.toNumber<uint8_t> ();
EXPECT(!res2);
}
} // VSTGUI
@@ -0,0 +1,75 @@
// This file is part of VSTGUI. It is subject to the license terms
// in the LICENSE file found in the top-level directory of this
// distribution and at http://github.com/steinbergmedia/vstgui/LICENSE
#include "../../../uidescription/base64codec.h"
#include "../unittests.h"
#include <string>
namespace VSTGUI {
TEST_CASE (Base64CodecTest, EncodeAscii)
{
std::string test ("ABCD");
auto result = Base64Codec::encode (test.data (), test.size ());
EXPECT (result.dataSize == 8);
uint8_t* ptr = result.data.get ();
EXPECT (ptr[0] == 'Q');
EXPECT (ptr[1] == 'U');
EXPECT (ptr[2] == 'J');
EXPECT (ptr[3] == 'D');
EXPECT (ptr[4] == 'R');
EXPECT (ptr[5] == 'A');
EXPECT (ptr[6] == '=');
EXPECT (ptr[7] == '=');
}
TEST_CASE (Base64CodecTest, EncodeBinary)
{
uint8_t binary[6];
binary[0] = 0x89;
binary[1] = 0x50;
binary[2] = 0x4E;
binary[3] = 0x47;
binary[4] = 0x0D;
binary[5] = 0x0A;
auto result = Base64Codec::encode (binary, 6);
EXPECT (result.dataSize == 8);
uint8_t* ptr = result.data.get ();
EXPECT (ptr[0] == 'i');
EXPECT (ptr[1] == 'V');
EXPECT (ptr[2] == 'B');
EXPECT (ptr[3] == 'O');
EXPECT (ptr[4] == 'R');
EXPECT (ptr[5] == 'w');
EXPECT (ptr[6] == '0');
EXPECT (ptr[7] == 'K');
}
TEST_CASE (Base64CodecTest, DecodeAscii)
{
std::string test ("QUJDRA");
auto result = Base64Codec::decode (test);
EXPECT (result.dataSize == 4);
uint8_t* ptr = result.data.get ();
EXPECT (ptr[0] == 'A');
EXPECT (ptr[1] == 'B');
EXPECT (ptr[2] == 'C');
EXPECT (ptr[3] == 'D');
}
TEST_CASE (Base64CodecTest, DecodeBinary)
{
std::string test ("iVBORw0K");
auto result = Base64Codec::decode (test);
EXPECT (result.dataSize == 6);
uint8_t* ptr = result.data.get ();
EXPECT (ptr[0] == 0x89);
EXPECT (ptr[1] == 0x50);
EXPECT (ptr[2] == 0x4E);
EXPECT (ptr[3] == 0x47);
EXPECT (ptr[4] == 0x0D);
EXPECT (ptr[5] == 0x0A);
}
}
@@ -0,0 +1,140 @@
// This file is part of VSTGUI. It is subject to the license terms
// in the LICENSE file found in the top-level directory of this
// distribution and at http://github.com/steinbergmedia/vstgui/LICENSE
#include "../../../uidescription/cstream.h"
#include "../unittests.h"
namespace VSTGUI {
TEST_CASE (CMemoryStreamTest, ReadWrite)
{
CMemoryStream s;
uint64_t value = 1;
uint32_t size = sizeof (value);
EXPECT (s.writeRaw (&value, size) == size);
EXPECT (s.tell () == size);
s.rewind ();
value = 20;
EXPECT (s.readRaw (&value, size) == size);
EXPECT (value == 1);
}
TEST_CASE (CMemoryStreamTest, Overread)
{
CMemoryStream s;
uint32_t value = 1;
EXPECT (s.writeRaw (&value, sizeof (value)) == sizeof (value));
s.rewind ();
uint64_t value2;
EXPECT (s.readRaw (&value2, sizeof (value2)) < sizeof (value2));
}
TEST_CASE (CMemoryStreamTest, Seek)
{
constexpr uint32_t bufferSize = 32;
int8_t buffer[bufferSize];
CMemoryStream s (buffer, bufferSize);
EXPECT (s.seek (33, CMemoryStream::kSeekEnd) == kStreamSeekError);
EXPECT (s.seek (0, CMemoryStream::kSeekEnd) == 32);
EXPECT (s.seek (-2, CMemoryStream::kSeekCurrent) == 30);
EXPECT (s.seek (15, CMemoryStream::kSeekSet) == 15);
}
TEST_CASE (CMemoryStreamTest, ReadWriteValueLittleEndian)
{
CMemoryStream s;
OutputStream& os = s;
os.setByteOrder (kLittleEndianByteOrder);
os << static_cast<int8_t> (1);
os << static_cast<uint8_t> (2);
os << static_cast<int16_t> (3);
os << static_cast<uint16_t> (4);
os << static_cast<int32_t> (5);
os << static_cast<uint32_t> (6);
os << static_cast<int64_t> (7);
os << static_cast<uint64_t> (8);
os << static_cast<double> (9);
s.rewind ();
InputStream& is = s;
is.setByteOrder (kLittleEndianByteOrder);
int8_t v1;
EXPECT (is >> v1);
EXPECT (v1 == 1);
uint8_t v2;
EXPECT (is >> v2);
EXPECT (v2 == 2);
int16_t v3;
EXPECT (is >> v3);
EXPECT (v3 == 3);
uint16_t v4;
EXPECT (is >> v4);
EXPECT (v4 == 4);
int32_t v5;
EXPECT (is >> v5);
EXPECT (v5 == 5);
uint32_t v6;
EXPECT (is >> v6);
EXPECT (v6 == 6);
int64_t v7;
EXPECT (is >> v7);
EXPECT (v7 == 7);
uint64_t v8;
EXPECT (is >> v8);
EXPECT (v8 == 8);
double v9;
EXPECT (is >> v9);
EXPECT (v9 == 9.0);
}
TEST_CASE (CMemoryStreamTest, ReadWriteValueBigEndian)
{
CMemoryStream s;
OutputStream& os = s;
os.setByteOrder (kBigEndianByteOrder);
os << static_cast<int8_t> (1);
os << static_cast<uint8_t> (2);
os << static_cast<int16_t> (3);
os << static_cast<uint16_t> (4);
os << static_cast<int32_t> (5);
os << static_cast<uint32_t> (6);
os << static_cast<int64_t> (7);
os << static_cast<uint64_t> (8);
os << static_cast<double> (9);
os << std::string ("Test");
s.rewind ();
InputStream& is = s;
is.setByteOrder (kBigEndianByteOrder);
int8_t v1;
EXPECT (is >> v1);
EXPECT (v1 == 1);
uint8_t v2;
EXPECT (is >> v2);
EXPECT (v2 == 2);
int16_t v3;
EXPECT (is >> v3);
EXPECT (v3 == 3);
uint16_t v4;
EXPECT (is >> v4);
EXPECT (v4 == 4);
int32_t v5;
EXPECT (is >> v5);
EXPECT (v5 == 5);
uint32_t v6;
EXPECT (is >> v6);
EXPECT (v6 == 6);
int64_t v7;
EXPECT (is >> v7);
EXPECT (v7 == 7);
uint64_t v8;
EXPECT (is >> v8);
EXPECT (v8 == 8);
double v9;
EXPECT (is >> v9);
EXPECT (v9 == 9.0);
std::string str;
EXPECT (is >> str);
EXPECT (str == "Test");
}
} // VSTGUI
@@ -0,0 +1,159 @@
// This file is part of VSTGUI. It is subject to the license terms
// in the LICENSE file found in the top-level directory of this
// distribution and at http://github.com/steinbergmedia/vstgui/LICENSE
#include "../../../uidescription/delegationcontroller.h"
#include "../../../uidescription/uiattributes.h"
#include "../unittests.h"
namespace VSTGUI {
namespace {
class Controller : public IController
{
public:
mutable bool funcCalled {false};
void valueChanged (CControl* pControl) override { funcCalled = true; }
int32_t controlModifierClicked (CControl* pControl, CButtonState button) override
{
funcCalled = true;
return 0;
}
void controlBeginEdit (CControl* pControl) override { funcCalled = true; }
void controlEndEdit (CControl* pControl) override { funcCalled = true; }
void controlTagWillChange (CControl* pControl) override { funcCalled = true; }
void controlTagDidChange (CControl* pControl) override { funcCalled = true; }
int32_t getTagForName (UTF8StringPtr name, int32_t registeredTag) const override
{
funcCalled = true;
return registeredTag;
}
IControlListener* getControlListener (UTF8StringPtr controlTagName) override
{
funcCalled = true;
return this;
}
CView* createView (const UIAttributes& attributes, const IUIDescription* description) override
{
funcCalled = true;
return nullptr;
}
CView* verifyView (CView* view, const UIAttributes& attributes,
const IUIDescription* description) override
{
funcCalled = true;
return view;
}
IController* createSubController (UTF8StringPtr name,
const IUIDescription* description) override
{
funcCalled = true;
return nullptr;
}
};
} // anonymous
TEST_CASE (DelegationControllerTest, ValueChanged)
{
Controller myController;
DelegationController dc (&myController);
dc.valueChanged (nullptr);
EXPECT (myController.funcCalled);
}
TEST_CASE (DelegationControllerTest, ControlModifierClicked)
{
Controller myController;
DelegationController dc (&myController);
dc.controlModifierClicked (nullptr, kLButton);
EXPECT (myController.funcCalled);
}
TEST_CASE (DelegationControllerTest, ControlBeginEdit)
{
Controller myController;
DelegationController dc (&myController);
dc.controlBeginEdit (nullptr);
EXPECT (myController.funcCalled);
}
TEST_CASE (DelegationControllerTest, ControlEndEdit)
{
Controller myController;
DelegationController dc (&myController);
dc.controlEndEdit (nullptr);
EXPECT (myController.funcCalled);
}
TEST_CASE (DelegationControllerTest, ControlTagWillChange)
{
Controller myController;
DelegationController dc (&myController);
dc.controlTagWillChange (nullptr);
EXPECT (myController.funcCalled);
}
TEST_CASE (DelegationControllerTest, ControlTagDidChange)
{
Controller myController;
DelegationController dc (&myController);
dc.controlTagDidChange (nullptr);
EXPECT (myController.funcCalled);
}
TEST_CASE (DelegationControllerTest, GetTagForName)
{
Controller myController;
DelegationController dc (&myController);
dc.getTagForName ("", 0);
EXPECT (myController.funcCalled);
}
TEST_CASE (DelegationControllerTest, GetControlListener)
{
Controller myController;
DelegationController dc (&myController);
dc.getControlListener ("");
EXPECT (myController.funcCalled);
}
TEST_CASE (DelegationControllerTest, CreateView)
{
Controller myController;
DelegationController dc (&myController);
UIAttributes a;
dc.createView (a, nullptr);
EXPECT (myController.funcCalled);
}
TEST_CASE (DelegationControllerTest, VerifyView)
{
Controller myController;
DelegationController dc (&myController);
UIAttributes a;
dc.verifyView (nullptr, a, nullptr);
EXPECT (myController.funcCalled);
}
TEST_CASE (DelegationControllerTest, CreateSubController)
{
Controller myController;
DelegationController dc (&myController);
dc.createSubController ("", nullptr);
EXPECT (myController.funcCalled);
}
} // VSTGUI
@@ -0,0 +1,218 @@
// This file is part of VSTGUI. It is subject to the license terms
// in the LICENSE file found in the top-level directory of this
// distribution and at http://github.com/steinbergmedia/vstgui/LICENSE
#include "../../../lib/cpoint.h"
#include "../../../lib/crect.h"
#include "../../../uidescription/cstream.h"
#include "../../../uidescription/uiattributes.h"
#include "../unittests.h"
namespace VSTGUI {
static UTF8StringPtr attributes[] = {"K1", "V1", "K2", "V2", nullptr};
TEST_CASE (UIAttributesTest, ArrayConstructor)
{
UIAttributes a (attributes);
EXPECT (a.hasAttribute ("K1"));
EXPECT (a.hasAttribute ("K2"));
EXPECT (*a.getAttributeValue ("K1") == "V1");
EXPECT (*a.getAttributeValue ("K2") == "V2");
}
TEST_CASE (UIAttributesTest, SetGetStringValue)
{
UIAttributes a;
a.setAttribute ("Key", "Value");
EXPECT (a.hasAttribute ("Key"));
EXPECT (*a.getAttributeValue ("Key") == "Value");
}
TEST_CASE (UIAttributesTest, RemoveAttribute)
{
UIAttributes a;
a.setAttribute ("Key", "Value");
a.removeAttribute ("Key");
EXPECT (a.hasAttribute ("Key") == false);
}
TEST_CASE (UIAttributesTest, BoolAttribute)
{
UIAttributes a;
bool value = false;
EXPECT (a.getBooleanAttribute ("Key", value) == false);
a.setBooleanAttribute ("Key", true);
EXPECT (a.getBooleanAttribute ("Key", value));
EXPECT (value == true);
a.setBooleanAttribute ("Key", false);
EXPECT (a.getBooleanAttribute ("Key", value));
EXPECT (value == false);
}
TEST_CASE (UIAttributesTest, IntegerAttribute)
{
UIAttributes a;
int32_t value = 0;
EXPECT (a.getIntegerAttribute ("Key", value) == false);
a.setIntegerAttribute ("Key", 10);
EXPECT (a.getIntegerAttribute ("Key", value));
EXPECT (value == 10);
}
TEST_CASE (UIAttributesTest, DoubleAttribute)
{
UIAttributes a;
double value = 0.;
EXPECT (a.getDoubleAttribute ("Key", value) == false);
a.setDoubleAttribute ("Key", 3.45);
EXPECT (a.getDoubleAttribute ("Key", value));
EXPECT (value == 3.45);
}
TEST_CASE (UIAttributesTest, PointAttribute)
{
UIAttributes a;
CPoint value;
EXPECT (a.getPointAttribute ("Key", value) == false);
a.setPointAttribute ("Key", CPoint (5, 5));
EXPECT (a.getPointAttribute ("Key", value));
EXPECT (value == CPoint (5, 5));
}
TEST_CASE (UIAttributesTest, RectAttribute)
{
UIAttributes a;
CRect value;
EXPECT (a.getRectAttribute ("Key", value) == false);
a.setRectAttribute ("Key", CRect (10, 20, 30, 40));
EXPECT (a.getRectAttribute ("Key", value));
EXPECT (value == CRect (10, 20, 30, 40));
}
TEST_CASE (UIAttributesTest, StringArrayAttribute)
{
UIAttributes a;
UIAttributes::StringArray array;
array.push_back ("1");
array.push_back ("2");
array.push_back ("3");
UIAttributes::StringArray array2;
EXPECT (a.getStringArrayAttribute ("Key", array2) == false);
a.setStringArrayAttribute ("Key", array);
EXPECT (a.getStringArrayAttribute ("Key", array2));
EXPECT (array == array2);
}
TEST_CASE (UIAttributesTest, RemoveAll)
{
UIAttributes a;
a.setRectAttribute ("Key1", CRect (10, 20, 30, 40));
a.setDoubleAttribute ("Key2", 3.45);
a.removeAll ();
EXPECT (a.begin () == a.end ());
}
TEST_CASE (UIAttributesTest, StoreRestore)
{
UIAttributes a;
CMemoryStream s2;
EXPECT (a.restore (s2) == false);
a.setAttribute ("Key1", "Value");
a.setBooleanAttribute ("Key2", true);
a.setIntegerAttribute ("Key3", 10);
a.setDoubleAttribute ("Key4", 3.45);
a.setPointAttribute ("Key5", CPoint (5, 5));
a.setRectAttribute ("Key6", CRect (10, 20, 30, 40));
a.setDoubleAttribute ("Key7", 3.45);
CMemoryStream s;
a.store (s);
s.rewind ();
UIAttributes a2;
a2.restore (s);
for (auto& v : a)
{
auto value = a2.getAttributeValue (v.first);
EXPECT (value);
EXPECT_EQ (*value, v.second);
}
}
TEST_CASE (UIAttributesTest, RestoreFromInvalidStream)
{
CMemoryStream s;
UIAttributes a;
EXPECT (a.restore (s) == false);
s.rewind ();
uint32_t someValue = 0;
s.writeRaw (&someValue, sizeof (someValue));
s.rewind ();
EXPECT (a.restore (s) == false);
}
TEST_CASE (UIAttributesTest, StringToBool)
{
bool b;
EXPECT (UIAttributes::stringToBool ("hola", b) == false)
EXPECT (UIAttributes::stringToBool ("true 5", b) == false)
EXPECT (UIAttributes::stringToBool ("true", b) && b == true)
EXPECT (UIAttributes::stringToBool ("false", b) && b == false)
}
TEST_CASE (UIAttributesTest, StringToInteger)
{
int32_t i;
EXPECT (UIAttributes::stringToInteger ("s5s5", i) == false)
EXPECT (UIAttributes::stringToInteger ("5s5", i) == false)
EXPECT (UIAttributes::stringToInteger ("1.0", i) == false)
EXPECT (UIAttributes::stringToInteger ("hola", i) == false)
EXPECT (UIAttributes::stringToInteger ("151515", i) && i == 151515)
}
TEST_CASE (UIAttributesTest, StringToDouble)
{
double d;
EXPECT (UIAttributes::stringToDouble ("as5.5", d) == false)
EXPECT (UIAttributes::stringToDouble ("5.5sa", d) == false)
EXPECT (UIAttributes::stringToDouble ("5.567.5", d) == false)
EXPECT (UIAttributes::stringToDouble ("hola", d) == false)
EXPECT (UIAttributes::stringToDouble ("25.5", d) && d == 25.5)
EXPECT (UIAttributes::stringToDouble (".5", d) && d == 0.5)
EXPECT (UIAttributes::stringToDouble (" -0.5", d) && d == -0.5)
}
TEST_CASE (UIAttributesTest, StringToPoint)
{
CPoint p;
EXPECT (UIAttributes::stringToPoint ("30, 20, 50", p) == false)
EXPECT (UIAttributes::stringToPoint ("30, 20a", p) == false)
EXPECT (UIAttributes::stringToPoint ("a, b", p) == false)
EXPECT (UIAttributes::stringToPoint ("20", p) == false)
EXPECT (UIAttributes::stringToPoint ("15, 25", p) && p == CPoint (15, 25))
EXPECT (UIAttributes::stringToPoint ("1.768, 25", p) && p == CPoint (1.768, 25))
}
TEST_CASE (UIAttributesTest, StringToRect)
{
CRect r;
EXPECT (UIAttributes::stringToRect ("30, 20, 50", r) == false)
EXPECT (UIAttributes::stringToRect ("30, 20, 50, 60, 80", r) == false)
EXPECT (UIAttributes::stringToRect ("30, 20, 50, 60a", r) == false)
EXPECT (UIAttributes::stringToRect ("a, b, c, d", r) == false)
EXPECT (UIAttributes::stringToRect ("0, 12.5, 5, 8", r) && r == CRect (0, 12.5, 5, 8))
}
TEST_CASE (UIAttributesTest, StringArrayToStringWithEmptyStringArray)
{
const UIAttributes::StringArray strings;
const auto s = UIAttributes::stringArrayToString (strings);
EXPECT (s.empty ())
}
} // VSTGUI
@@ -0,0 +1,99 @@
// This file is part of VSTGUI. It is subject to the license terms
// in the LICENSE file found in the top-level directory of this
// distribution and at http://github.com/steinbergmedia/vstgui/LICENSE
#include "../../../uidescription/uidescriptionaddonregistry.h"
#include "../../../uidescription/uidescription.h"
#include "../../../uidescription/uicontentprovider.h"
#include "../../../lib/cview.h"
#include "../unittests.h"
//------------------------------------------------------------------------
namespace VSTGUI {
namespace {
//------------------------------------------------------------------------
constexpr auto createViewUIDesc = R"(
{
"vstgui-ui-description": {
"version": "1",
"templates": {
"view": {
"attributes": {
"background-color": "~ TransparentCColor",
"background-color-draw-style": "filled and stroked",
"class": "CViewContainer",
"mouse-enabled": "true",
"opacity": "1",
"origin": "0, 0",
"size": "400, 235",
"transparent": "false"
},
"children": {
"CView": {
"attributes": {
"class": "CView",
"mouse-enabled": "true",
"opacity": "1",
"origin": "4, 10",
"size": "392, 40",
"transparent": "false"
}
}
}
}
}
}
}
)";
} // anonymous
//------------------------------------------------------------------------
TEST_CASE (UIDescriptionAddOnTest, BasicFunctionality)
{
struct BaseAddOn : UIDescriptionAddOnAdapter
{
void afterParsing (IUIDescription* desc) override { afterParsingCalled = true; }
void beforeSaving (IUIDescription* desc) override { beforeSavingCalled = true; }
void onDestroy (IUIDescription* desc) override { onDestroyCalled = true; }
CreateTemplateViewFunc onCreateTemplateView (const IUIDescription* desc,
const CreateTemplateViewFunc& f) override
{
onCreateTemplateViewCalled = true;
return f;
}
IViewFactory* getViewFactory (IUIDescription* desc, IViewFactory* of) override
{
getViewFactoryCalled = true;
return of;
};
bool afterParsingCalled {false};
bool beforeSavingCalled {false};
bool onDestroyCalled {false};
bool onCreateTemplateViewCalled {false};
bool getViewFactoryCalled {false};
};
auto myAddOn = std::make_unique<BaseAddOn> ();
auto myAddOnPtr = myAddOn.get ();
auto token = UIDescriptionAddOnRegistry::add (std::move (myAddOn));
{
MemoryContentProvider provider (createViewUIDesc,
static_cast<uint32_t> (strlen (createViewUIDesc)));
UIDescription desc (&provider);
EXPECT_TRUE (myAddOnPtr->getViewFactoryCalled);
EXPECT_TRUE (desc.parse ());
EXPECT_TRUE (myAddOnPtr->afterParsingCalled);
auto view = desc.createView ("view", nullptr);
EXPECT_NE (view, nullptr);
EXPECT_TRUE (myAddOnPtr->onCreateTemplateViewCalled);
view->forget ();
}
EXPECT_TRUE (myAddOnPtr->onDestroyCalled);
UIDescriptionAddOnRegistry::remove (token);
}
//------------------------------------------------------------------------
} // VSTGUI
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,118 @@
// This file is part of VSTGUI. It is subject to the license terms
// in the LICENSE file found in the top-level directory of this
// distribution and at http://github.com/steinbergmedia/vstgui/LICENSE
#pragma once
#include "../../../uidescription/icontroller.h"
#include "../../../uidescription/uidescription.h"
#include "../../../uidescription/uidescriptionlistener.h"
#include "../unittests.h"
namespace VSTGUI {
namespace UIDescriptionTesting {
struct SaveUIDescription : public UIDescription
{
SaveUIDescription (IContentProvider* xmlContentProvider) : UIDescription (xmlContentProvider) {}
using UIDescription::saveToStream;
};
struct Controller : public IController
{
void valueChanged (CControl* pControl) override {};
int32_t getTagForName (UTF8StringPtr name, int32_t registeredTag) const override
{
return registeredTag;
}
IControlListener* getControlListener (UTF8StringPtr controlTagName) override { return this; }
CView* createView (const UIAttributes& attributes, const IUIDescription* description) override
{
return nullptr;
}
CView* verifyView (CView* view, const UIAttributes& attributes,
const IUIDescription* description) override
{
return view;
}
IController* createSubController (UTF8StringPtr name,
const IUIDescription* description) override
{
return nullptr;
}
};
enum class UIDescTestCase
{
TagChanged,
ColorChanged,
FontChanged,
BitmapChanged,
TemplateChanged,
GradientChanged,
BeforeSave
};
//-----------------------------------------------------------------------------
class DescriptionListenerMock : public UIDescriptionListenerAdapter
{
public:
DescriptionListenerMock (UIDescTestCase tc) { setTestCase (tc); }
void setTestCase (UIDescTestCase tc)
{
testCase = tc;
called = 0u;
}
uint32_t callCount () const { return called; }
bool doUIDescTemplateUpdate (UIDescription* desc, UTF8StringPtr name) override
{
EXPECT (false);
return true;
}
void onUIDescTagChanged (UIDescription* desc) override
{
++called;
EXPECT (testCase == UIDescTestCase::TagChanged)
}
void onUIDescColorChanged (UIDescription* desc) override
{
++called;
EXPECT (testCase == UIDescTestCase::ColorChanged)
}
void onUIDescFontChanged (UIDescription* desc) override
{
++called;
EXPECT (testCase == UIDescTestCase::FontChanged)
}
void onUIDescBitmapChanged (UIDescription* desc) override
{
++called;
EXPECT (testCase == UIDescTestCase::BitmapChanged)
}
void onUIDescTemplateChanged (UIDescription* desc) override
{
++called;
EXPECT (testCase == UIDescTestCase::TemplateChanged)
}
void onUIDescGradientChanged (UIDescription* desc) override
{
++called;
EXPECT (testCase == UIDescTestCase::GradientChanged)
}
void beforeUIDescSave (UIDescription* desc) override
{
++called;
EXPECT (testCase == UIDescTestCase::BeforeSave)
}
private:
UIDescTestCase testCase;
uint32_t called;
};
} // UIDescriptionTesting
} // VSTGUI
@@ -0,0 +1,902 @@
// This file is part of VSTGUI. It is subject to the license terms
// in the LICENSE file found in the top-level directory of this
// distribution and at http://github.com/steinbergmedia/vstgui/LICENSE
#include "../../../lib/cbitmap.h"
#include "../../../lib/ccolor.h"
#include "../../../lib/cgradient.h"
#include "../../../lib/cviewcontainer.h"
#include "../../../uidescription/detail/uiviewcreatorattributes.h"
#include "../../../uidescription/uiattributes.h"
#include "../../../uidescription/uicontentprovider.h"
#include "../../../uidescription/xmlparser.h"
#include "uidescription_test_helper.h"
#if VSTGUI_ENABLE_XML_PARSER
namespace VSTGUI {
using namespace UIDescriptionTesting;
namespace {
static constexpr auto defaultSafeFlags =
UIDescription::kWriteImagesIntoUIDescFile | UIDescription::kWriteAsXML;
constexpr auto emptyUIDesc = R"(
<vstgui-ui-description version="1">
</vstgui-ui-description>
)";
constexpr auto colorNodesUIDesc = R"(
<vstgui-ui-description version="1">
<colors>
<color name="c1" rgba="#000000ff"/>
<color name="c2" rgb="#ffffff"/>
<color name="c3" red="255" green="0" blue="0" alpha="100"/>
<color name="c4" red="0" green="255" blue="0" alpha="150"/>
<color name="c5" red="255" green="0" blue="255" alpha="100"/>
</colors>
</vstgui-ui-description>
)";
constexpr auto fontNodesUIDesc = R"(
<vstgui-ui-description version="1">
<fonts>
<font font-name="Arial" name="f1" size="8"/>
<font font-name="Arial" name="f2" size="8" bold="true"/>
<font font-name="Arial" name="f3" size="8" italic="true"/>
<font font-name="Arial" name="f4" size="8" underline="true"/>
<font font-name="Arial" name="f5" size="8" strike-through="true"/>
<font font-name="bla" name="f6" size="8" alternative-font-names="Arial, Courier"/>
</fonts>
</vstgui-ui-description>
)";
constexpr auto bitmapNodesUIDesc = R"(
<vstgui-ui-description version="1">
<bitmaps>
<bitmap name="b1" path="b1.png"/>
<bitmap name="b1#2.0x" path="b1#2.0x.png" scale-factor="2"/>
</bitmaps>
</vstgui-ui-description>
)";
constexpr auto tagNodesUIDesc = R"(
<vstgui-ui-description version="1">
<control-tags>
<control-tag name="t1" tag="1234"/>
<control-tag name="t2" tag="4321"/>
<control-tag name="t3" tag="'mytg'"/>
</control-tags>
</vstgui-ui-description>
)";
constexpr auto calculateTagNodesUIDesc = R"(
<vstgui-ui-description version="1">
<control-tags>
<control-tag name="t1" tag="1+2"/>
</control-tags>
</vstgui-ui-description>
)";
constexpr auto gradientNodesUIDesc = R"(
<vstgui-ui-description version="1">
<gradients>
<gradient name="g1">
<color-stop rgba="#000000ff" start="0"/>
<color-stop rgba="#ff0000ff" start="0.5"/>
<color-stop rgba="#ffffffff" start="1"/>
</gradient>
</gradients>
</vstgui-ui-description>
)";
constexpr auto variableNodesUIDesc = R"(
<vstgui-ui-description version="1">
<variables>
<var name="v1" type="number" value="10"/>
<var name="v2" type="string" value="string"/>
<var name="v3" value="string"/>
<var name="v4" value="20.5"/>
<var name="v5" type="string" value="2*var.v1"/>
<var name="v6"/>
</variables>
</vstgui-ui-description>
)";
constexpr auto withAllNodesUIDesc = R"(<?xml version="1.0" encoding="UTF-8"?>
<vstgui-ui-description version="1">
<colors>
<color name="c1" rgba="#000000ff"/>
<color name="c2" rgb="#ffffff"/>
<color alpha="100" blue="0" green="0" name="c3" red="255"/>
</colors>
<fonts>
<font font-name="Arial" name="f1" size="8"/>
<font bold="true" font-name="Arial" name="f2" size="8"/>
</fonts>
<!-- a comment -->
<bitmaps>
<bitmap name="b1" path="b1.png">
<data encoding="base64">
iVBORw0KGgoAAAANSUhEUgAAAAwAAAAMCAYAAABWdVznAAABe2lDQ1BJQ0MgUHJvZmlsZQAAKJF9kE0rRF
EYx38zXjNkwcLC4jaG1RCjvGyUmYSaxTRGedvcueZFmXG7c4VsLJTtFCU23hZ8AjYWylopRUrKVyA20vUc
Q+OlPHXO+Z3nPM+/5/zB7ddNc7a0HTJZ24oOBrWx8Qmt4gEX5XjQ8OpGzuyPRMJIfJ0/4+VaqiWuWpXW3/
d/wzOdyBngqhTuM0zLFh4SblqwTcVKr96SoYRXFKcKvKE4XuCjj5pYNCR8KqwZaX1a+E7Yb6StDLiVvi/+
rSb1jTOz88bnPOon1Yns6IicXlmN5IgySFC8GGaAEF100Ct7F60EaJMbdmLRVs2hOXPJmkmlba1fnEhow1
mjza8F2ju6Qfn6269ibm4Xep6hJF/MxTfhZA0abos53w7UrsLxualb+keqRJY7mYTHQ6gZh7pLqJrMJTsD
hR9VB6Hs3nGemqFiHd7yjvO65zhv+9IsHp1lCx59anFwA7FlCF/A1ja0iHbt1Dv7WWccXX/QZQAAAExJRE
FUKBVjZEAALSAzDMFFYa0C8q6BRJhQhBEcUSAThIkGDUCVIIwBcNmAoRAmMKoBFhL4aEagJLYYhkXaazTN
q1jQBGBcdIUwcQYAOGIGVqwWW9EAAAAASUVORK5CYII=
</data>
</bitmap>
<bitmap name="b1#2.0x" path="b1#2.0x.png" scale-factor="2"/>
<bitmap name="dataBitmap" path="dataBitmap.png"/>
</bitmaps>
<control-tags>
<control-tag name="t1" tag="1234"/>
<control-tag name="t2" tag="4321"/>
</control-tags>
<gradients>
<gradient name="g1">
<color-stop rgba="#000000ff" start="0"/>
<color-stop rgba="#ff0000ff" start="0.5"/>
<color-stop rgba="#ffffffff" start="1"/>
</gradient>
</gradients>
<variables>
<var name="test" type="number" value="10"/>
<var name="test" type="string" value="this is a string"/>
</variables>
</vstgui-ui-description>
)";
constexpr auto createViewUIDesc = R"(
<vstgui-ui-description version="1">
<template background-color="~ TransparentCColor" background-color-draw-style="filled and stroked" class="CViewContainer" mouse-enabled="true" name="view" opacity="1" origin="0, 0" size="400, 235" transparent="false">
<view class="CView" mouse-enabled="true" opacity="1" origin="4, 10" size="392, 40" transparent="false"/>
</template>
</vstgui-ui-description>
)";
constexpr auto restoreViewUIDesc = R"(
<vstgui-ui-description version="1">
<template background-color="~ TransparentCColor" background-color-draw-style="filled and stroked" class="CViewContainer" mouse-enabled="true" name="view" opacity="1" origin="0, 0" size="400, 235" transparent="false">
<view class="CViewContainer" mouse-enabled="true" opacity="1" origin="4, 10" size="392, 40" transparent="false"/>
<view class="CViewContainer" mouse-enabled="true" opacity="1" origin="4, 10" size="392, 40" transparent="false">
<view class="CView" mouse-enabled="true" opacity="1" origin="4, 10" size="392, 40" transparent="false"/>
</view>
</template>
</vstgui-ui-description>
)";
constexpr auto completeExample = R"(
<vstgui-ui-description version="1">
<colors>
</colors>
<custom>
<attributes name="UIViewInspector" windowSize="71, 194, 471, 709"/>
<attributes name="UIViewHierarchyBrowser" windowSize="513, 194, 813, 694"/>
<attributes name="FocusDrawing"/>
<attributes name="UIGridController"/>
<attributes SelectedTemplate="tab1" name="UITemplateController"/>
<attributes EditViewScale="1" EditorSize="0, 0, 1244, 755" SplitViewSize_0_0="0.8228882833787466433150825650955084711313" SplitViewSize_0_1="0.1498637602179836436633308949240017682314" SplitViewSize_1_0="0.480926430517711167578198683258960954845" SplitViewSize_1_1="0.5122615803814714041664046817459166049957" SplitViewSize_2_0="0.7033762057877813722583937305898871272802" SplitViewSize_2_1="0.2926045016077170601853651987767079845071" Version="1" name="UIEditController"/>
<attributes name="UIAttributesController"/>
<attributes SelectedRow="20" name="UIViewCreatorDataSource"/>
</custom>
<bitmaps>
<bitmap name="animation_knob" path="animation_knob.png"/>
<bitmap name="FrameBackground" nineparttiled-offsets="10, 20, 10, 10" path="FrameBackground.png"/>
<bitmap name="TabController" path="TabController.png"/>
<bitmap name="horizontal_slider_back" path="horizontal_slider_back.bmp"/>
<bitmap name="onoff_button" path="onoff_button.bmp"/>
<bitmap name="rocker_switch" path="rocker_switch.bmp"/>
<bitmap name="slider_handle" path="slider_handle.bmp"/>
<bitmap name="switch_horizontal" path="switch_horizontal.bmp"/>
<bitmap name="switch_vertical" path="switch_vertical.bmp"/>
<bitmap name="vertical_slider_back" path="vertical_slider_back.bmp"/>
<bitmap name="vumeter_back" path="vumeter_back.bmp"/>
<bitmap name="vumeter_front" path="vumeter_front.bmp"/>
</bitmaps>
<fonts>
</fonts>
<control-tags>
<control-tag name="Switch" tag="20000"/>
</control-tags>
<variables/>
<template autosize="left right top bottom " background-color="~ WhiteCColor" background-color-draw-style="filled and stroked" class="CViewContainer" maxSize="300, 500" minSize="150, 300" mouse-enabled="true" name="view" opacity="1" origin="0, 0" size="300, 500" transparent="false">
<view animation-style="fade" animation-time="120" background-color="~ BlackCColor" background-color-draw-style="filled and stroked" class="UIViewSwitchContainer" mouse-enabled="true" opacity="1" origin="10, 10" size="280, 480" transparent="false"/>
</template>
<template autosize="left right top bottom " background-color="~ BlackCColor" background-color-draw-style="filled and stroked" class="CViewContainer" mouse-enabled="true" name="tab1" opacity="1" origin="0, 0" size="280, 480" transparent="true">
<view background-color="~ BlackCColor" background-color-draw-style="filled and stroked" class="CLayeredViewContainer" mouse-enabled="true" opacity="1" origin="10, 20" size="100, 100" transparent="false" z-index="0"/>
<view background-color="~ BlackCColor" background-color-draw-style="filled and stroked" bitmap="0" class="CShadowViewContainer" mouse-enabled="true" opacity="1" origin="130, 20" shadow-blur-size="4" shadow-intensity="0.3" shadow-offset="0, 0" size="200, 200" transparent="false"/>
<view auto-drag-scrolling="false" auto-hide-scrollbars="false" background-color="~ BlackCColor" background-color-draw-style="filled and stroked" bordered="true" class="CScrollView" container-size="200, 200" follow-focus-view="false" horizontal-scrollbar="true" mouse-enabled="true" opacity="1" origin="40, 240" overlay-scrollbars="false" scrollbar-background-color="#ffffffc8" scrollbar-frame-color="~ BlackCColor" scrollbar-scroller-color="~ BlueCColor" scrollbar-width="16" size="100, 100" transparent="false" vertical-scrollbar="true"/>
<view animate-view-resizing="false" background-color="~ BlackCColor" background-color-draw-style="filled and stroked" class="CRowColumnView" equal-size-layout="left-top" margin="0,0,0,0" mouse-enabled="true" opacity="1" origin="60, 360" row-style="true" size="100, 100" spacing="0" transparent="false" view-resize-animation-time="200"/>
<view background-color="~ BlackCColor" background-color-draw-style="filled and stroked" class="CSplitView" mouse-enabled="true" opacity="1" orientation="horizontal" origin="160, 280" resize-method="last" separator-width="10" size="100, 100" transparent="false"/>
</template>
<template autosize="left right top bottom row " background-color="~ BlackCColor" background-color-draw-style="filled and stroked" class="CViewContainer" mouse-enabled="true" name="tab2" opacity="1" origin="0, 0" size="280, 480" transparent="true">
<view angle-range="270" angle-start="135" background-offset="0, 0" circle-drawing="false" class="CAnimKnob" corona-color="~ WhiteCColor" corona-dash-dot="false" corona-drawing="false" corona-from-center="false" corona-inset="0" corona-inverted="false" corona-outline="false" default-value="0.5" handle-color="~ WhiteCColor" handle-line-width="1" handle-shadow-color="~ GreyCColor" height-of-one-image="0" max-value="1" min-value="0" mouse-enabled="true" opacity="1" origin="10, 10" size="20, 20" sub-pixmaps="0" transparent="false" value-inset="0" wheel-inc-value="0.1" zoom-factor="1.5"/>
<view animation-index="0" animation-time="500" background-offset="0, 0" class="CAnimationSplashScreen" default-value="0.5" max-value="1" min-value="0" mouse-enabled="true" opacity="1" origin="50, 10" size="20, 20" splash-origin="0, 0" splash-size="0, 0" transparent="false" wheel-inc-value="0.1"/>
<view autosize-to-fit="false" background-offset="0, 0" boxfill-color="~ WhiteCColor" boxframe-color="~ BlackCColor" checkmark-color="~ RedCColor" class="CCheckBox" default-value="0.5" draw-crossbox="false" font="~ SystemFont" font-color="~ WhiteCColor" max-value="1" min-value="0" mouse-enabled="true" opacity="1" origin="110, 10" size="100, 20" title="Title" transparent="false" wheel-inc-value="0.1"/>
<view background-offset="0, 0" class="CControl" default-value="0.5" max-value="1" min-value="0" mouse-enabled="true" opacity="1" origin="20, 50" size="20, 20" transparent="false" wheel-inc-value="0.1"/>
<view class="CGradientView" draw-antialiased="true" frame-color="~ BlackCColor" frame-width="1" gradient-angle="0" gradient-style="linear" mouse-enabled="true" opacity="1" origin="70, 50" radial-center="0.5, 0.5" radial-radius="1" round-rect-radius="5" size="100, 100" transparent="false"/>
<view background-offset="0, 0" class="CHorizontalSwitch" default-value="0" height-of-one-image="0" max-value="1" min-value="0" mouse-enabled="true" opacity="1" origin="20, 160" size="20, 20" sub-pixmaps="0" transparent="false" wheel-inc-value="0.1"/>
<view background-offset="0, 0" class="CKickButton" default-value="0.5" height-of-one-image="0" max-value="1" min-value="0" mouse-enabled="true" opacity="1" origin="70, 150" size="20, 20" sub-pixmaps="0" transparent="false" wheel-inc-value="0.1"/>
<view angle-range="270" angle-start="135" background-offset="0, 0" circle-drawing="false" class="CKnob" corona-color="~ WhiteCColor" corona-dash-dot="false" corona-drawing="false" corona-from-center="false" corona-inset="0" corona-inverted="false" corona-outline="false" default-value="0.5" handle-color="~ WhiteCColor" handle-line-width="1" handle-shadow-color="~ GreyCColor" max-value="1" min-value="0" mouse-enabled="true" opacity="1" origin="120, 150" size="20, 20" transparent="false" value-inset="3" wheel-inc-value="0.1" zoom-factor="1.5"/>
<view background-offset="0, 0" class="CMovieBitmap" default-value="0.5" height-of-one-image="0" max-value="1" min-value="0" mouse-enabled="true" opacity="1" origin="170, 160" size="20, 20" sub-pixmaps="0" transparent="false" wheel-inc-value="0.1"/>
<view background-offset="0, 0" class="CMovieButton" default-value="0.5" height-of-one-image="0" max-value="1" min-value="0" mouse-enabled="true" opacity="1" origin="30, 200" size="20, 20" sub-pixmaps="0" transparent="false" wheel-inc-value="0.1"/>
<view background-offset="0, 0" class="COnOffButton" default-value="0.5" max-value="1" min-value="0" mouse-enabled="true" opacity="1" origin="80, 190" size="20, 20" transparent="false" wheel-inc-value="0.1"/>
<view back-color="~ BlackCColor" background-offset="0, 0" class="COptionMenu" default-value="0.5" font="~ NormalFont" font-antialias="true" font-color="~ WhiteCColor" frame-color="~ BlackCColor" frame-width="1" max-value="1.84467e+19" menu-check-style="false" menu-popup-style="false" min-value="0" mouse-enabled="true" opacity="1" origin="140, 190" round-rect-radius="6" shadow-color="~ RedCColor" size="20, 20" style-3D-in="false" style-3D-out="false" style-no-draw="false" style-no-frame="false" style-no-text="false" style-round-rect="false" style-shadow-text="false" text-alignment="center" text-inset="0, 0" text-rotation="0" transparent="false" value-precision="2" wheel-inc-value="0.1"/>
<view back-color="~ BlackCColor" background-offset="0, 0" class="CParamDisplay" default-value="0.5" font="~ NormalFont" font-antialias="true" font-color="~ WhiteCColor" frame-color="~ BlackCColor" frame-width="1" max-value="1" min-value="0" mouse-enabled="true" opacity="1" origin="30, 230" round-rect-radius="6" shadow-color="~ RedCColor" size="20, 20" style-3D-in="false" style-3D-out="false" style-no-draw="false" style-no-frame="false" style-no-text="false" style-round-rect="false" style-shadow-text="false" text-alignment="center" text-inset="0, 0" text-rotation="0" transparent="false" value-precision="2" wheel-inc-value="0.1"/>
<view background-offset="0, 0" class="CRockerSwitch" default-value="0.5" height-of-one-image="0" max-value="1" min-value="-1" mouse-enabled="true" opacity="1" origin="70, 230" size="20, 20" sub-pixmaps="3" transparent="false" wheel-inc-value="0.1"/>
<view background-offset="0, 0" class="CSegmentButton" default-value="0.5" font="~ NormalFont" frame-color="~ BlackCColor" frame-width="1" icon-text-margin="0" max-value="1" min-value="0" mouse-enabled="true" opacity="1" origin="120, 230" round-radius="5" segment-names="Segment 1,Segment 2,Segment 3,Segment 4" size="200, 20" style="horizontal" text-alignment="center" text-color="~ BlackCColor" text-color-highlighted="~ WhiteCColor" transparent="false" wheel-inc-value="0.1"/>
<view background-offset="0, 0" bitmap-offset="0, 0" class="CSlider" default-value="0.5" draw-back="false" draw-back-color="~ WhiteCColor" draw-frame="false" draw-frame-color="~ WhiteCColor" draw-value="false" draw-value-color="~ WhiteCColor" draw-value-from-center="false" draw-value-inverted="false" handle-offset="0, 0" max-value="1" min-value="0" mode="free click" mouse-enabled="true" opacity="1" orientation="horizontal" origin="20, 270" reverse-orientation="false" size="20, 20" transparent="false" transparent-handle="true" wheel-inc-value="0.1" zoom-factor="10"/>
<view background-offset="0, 0" class="CTextButton" default-value="0.5" font="~ SystemFont" frame-color="~ BlackCColor" frame-color-highlighted="~ BlackCColor" frame-width="1" gradient="Default TextButton Gradient" gradient-highlighted="Default TextButton Gradient Highlighted" icon-position="left" icon-text-margin="0" kick-style="true" max-value="1" min-value="0" mouse-enabled="true" opacity="1" origin="60, 270" round-radius="6" size="100, 20" text-alignment="center" text-color="~ BlackCColor" text-color-highlighted="~ WhiteCColor" transparent="false" wheel-inc-value="0.1"/>
<view back-color="~ BlackCColor" background-offset="0, 0" class="CTextEdit" default-value="0.5" font="~ NormalFont" font-antialias="true" font-color="~ WhiteCColor" frame-color="~ BlackCColor" frame-width="1" immediate-text-change="false" max-value="1" min-value="0" mouse-enabled="true" opacity="1" origin="180, 270" round-rect-radius="6" shadow-color="~ RedCColor" size="100, 20" style-3D-in="false" style-3D-out="false" style-doubleclick="false" style-no-draw="false" style-no-frame="false" style-no-text="false" style-round-rect="false" style-shadow-text="false" text-alignment="center" text-inset="0, 0" text-rotation="0" transparent="false" value-precision="2" wheel-inc-value="0.1"/>
<view back-color="~ BlackCColor" background-offset="0, 0" class="CTextLabel" default-value="0.5" font="~ NormalFont" font-antialias="true" font-color="~ WhiteCColor" frame-color="~ BlackCColor" frame-width="1" max-value="1" min-value="0" mouse-enabled="true" opacity="1" origin="20, 300" round-rect-radius="6" shadow-color="~ RedCColor" size="100, 20" style-3D-in="false" style-3D-out="false" style-no-draw="false" style-no-frame="false" style-no-text="false" style-round-rect="false" style-shadow-text="false" text-alignment="center" text-inset="0, 0" text-rotation="0" transparent="false" value-precision="2" wheel-inc-value="0.1"/>
<view background-offset="0, 0" class="CVerticalSwitch" default-value="0" height-of-one-image="0" max-value="1" min-value="0" mouse-enabled="true" opacity="1" origin="20, 330" size="20, 20" sub-pixmaps="0" transparent="false" wheel-inc-value="0.1"/>
<view class="CView" mouse-enabled="true" opacity="1" origin="50, 330" size="20, 20" transparent="false"/>
<view background-offset="0, 0" class="CVuMeter" decrease-step-value="0.1" default-value="0.5" max-value="1" min-value="0" mouse-enabled="true" num-led="100" opacity="1" orientation="vertical" origin="90, 330" size="20, 20" transparent="false" wheel-inc-value="0.1"/>
<view back-color="~ BlackCColor" background-offset="0, 0" class="CXYPad" default-value="0.5" font="~ NormalFont" font-antialias="true" font-color="~ WhiteCColor" frame-color="~ BlackCColor" frame-width="1" max-value="2" min-value="0" mouse-enabled="true" opacity="1" origin="140, 330" round-rect-radius="6" shadow-color="~ RedCColor" size="100, 20" style-3D-in="false" style-3D-out="false" style-no-draw="false" style-no-frame="false" style-no-text="false" style-round-rect="false" style-shadow-text="false" text-alignment="center" text-inset="0, 0" text-rotation="0" transparent="false" value-precision="2" wheel-inc-value="0.1"/>
</template>
<gradients>
<gradient name="Default TextButton Gradient">
<color-stop rgba="#dcdcdcff" start="0"/>
<color-stop rgba="#b4b4b4ff" start="1"/>
</gradient>
<gradient name="Default TextButton Gradient Highlighted">
<color-stop rgba="#b4b4b4ff" start="0"/>
<color-stop rgba="#646464ff" start="1"/>
</gradient>
</gradients>
</vstgui-ui-description>
)";
constexpr auto sharedResourcesUIDesc = R"(<?xml version="1.0" encoding="UTF-8"?>
<vstgui-ui-description version="1">
<colors>
<color name="c1" rgba="#000000ff"/>
</colors>
<fonts>
<font font-name="Arial" name="f1" size="8"/>
</fonts>
<bitmaps>
<bitmap name="b1" path="b1.png">
<data encoding="base64">
iVBORw0KGgoAAAANSUhEUgAAAAwAAAAMCAYAAABWdVznAAABe2lDQ1BJQ0MgUHJvZmlsZQAAKJF9kE0rRF
EYx38zXjNkwcLC4jaG1RCjvGyUmYSaxTRGedvcueZFmXG7c4VsLJTtFCU23hZ8AjYWylopRUrKVyA20vUc
Q+OlPHXO+Z3nPM+/5/zB7ddNc7a0HTJZ24oOBrWx8Qmt4gEX5XjQ8OpGzuyPRMJIfJ0/4+VaqiWuWpXW3/
d/wzOdyBngqhTuM0zLFh4SblqwTcVKr96SoYRXFKcKvKE4XuCjj5pYNCR8KqwZaX1a+E7Yb6StDLiVvi/+
rSb1jTOz88bnPOon1Yns6IicXlmN5IgySFC8GGaAEF100Ct7F60EaJMbdmLRVs2hOXPJmkmlba1fnEhow1
mjza8F2ju6Qfn6269ibm4Xep6hJF/MxTfhZA0abos53w7UrsLxualb+keqRJY7mYTHQ6gZh7pLqJrMJTsD
hR9VB6Hs3nGemqFiHd7yjvO65zhv+9IsHp1lCx59anFwA7FlCF/A1ja0iHbt1Dv7WWccXX/QZQAAAExJRE
FUKBVjZEAALSAzDMFFYa0C8q6BRJhQhBEcUSAThIkGDUCVIIwBcNmAoRAmMKoBFhL4aEagJLYYhkXaazTN
q1jQBGBcdIUwcQYAOGIGVqwWW9EAAAAASUVORK5CYII=
</data>
</bitmap>
</bitmaps>
<gradients>
<gradient name="g1">
<color-stop rgba="#000000ff" start="0"/>
<color-stop rgba="#ff0000ff" start="0.5"/>
<color-stop rgba="#ffffffff" start="1"/>
</gradient>
</gradients>
</vstgui-ui-description>
)";
} // anonymous
using StringPtrList = std::list<const std::string*>;
TEST_CASE (UIDescriptionXMLTests, ParseEmpty)
{
MemoryContentProvider provider (emptyUIDesc, static_cast<uint32_t> (strlen (emptyUIDesc)));
UIDescription desc (&provider);
EXPECT (desc.parse () == true);
EXPECT (desc.getGradient ("t") == nullptr);
EXPECT (desc.getBitmap ("b") == nullptr);
EXPECT (desc.getFont ("f") == nullptr);
EXPECT (desc.getTagForName ("t") == -1);
CColor c;
EXPECT (desc.getColor ("c", c) == false);
EXPECT (desc.getControlListener ("t") == nullptr);
EXPECT (desc.getController () == nullptr);
}
TEST_CASE (UIDescriptionXMLTests, Colors)
{
MemoryContentProvider provider (colorNodesUIDesc,
static_cast<uint32_t> (strlen (colorNodesUIDesc)));
UIDescription desc (&provider);
EXPECT (desc.parse () == true);
CColor c;
EXPECT (desc.getColor ("c1", c));
EXPECT (c == CColor (0, 0, 0, 255));
EXPECT (desc.getColor ("c2", c));
EXPECT (c == CColor (255, 255, 255, 255));
EXPECT (desc.getColor ("c3", c));
EXPECT (c == CColor (255, 0, 0, 100));
EXPECT (desc.getColor ("c4", c));
EXPECT (c == CColor (0, 255, 0, 150));
EXPECT (desc.getColor ("c5", c));
EXPECT (c == CColor (255, 0, 255, 100));
StringPtrList names;
desc.collectColorNames (names);
uint32_t numNames = 0;
for (auto& name : names)
{
if (name->at (0) != '~')
numNames++;
}
EXPECT (numNames == 5);
desc.changeColor ("c5", CColor (0, 255, 0, 255));
EXPECT (desc.getColor ("c5", c));
EXPECT (c == CColor (0, 255, 0, 255));
desc.changeColor ("added color node", CColor (1, 2, 3, 4));
EXPECT (desc.hasColorName ("added color node"));
auto name = desc.lookupColorName (CColor (0, 255, 0, 255));
EXPECT (name == std::string ("c5"));
desc.changeColorName ("c5", "new color");
EXPECT (desc.hasColorName ("new color"));
desc.removeColor ("new color");
EXPECT (desc.getColor ("new color", c) == false);
}
TEST_CASE (UIDescriptionXMLTests, Fonts)
{
MemoryContentProvider provider (fontNodesUIDesc,
static_cast<uint32_t> (strlen (fontNodesUIDesc)));
UIDescription desc (&provider);
EXPECT (desc.parse () == true);
EXPECT (desc.hasFontName ("f1"));
auto font = desc.getFont ("f1");
EXPECT (font->getName () == std::string ("Arial"));
EXPECT (font->getSize () == 8);
EXPECT (font->getStyle () == kNormalFace);
font = desc.getFont ("f2");
EXPECT (font->getName () == std::string ("Arial"));
EXPECT (font->getSize () == 8);
EXPECT (font->getStyle () == kBoldFace);
font = desc.getFont ("f3");
EXPECT (font->getName () == std::string ("Arial"));
EXPECT (font->getSize () == 8);
EXPECT (font->getStyle () == kItalicFace);
font = desc.getFont ("f4");
EXPECT (font->getName () == std::string ("Arial"));
EXPECT (font->getSize () == 8);
EXPECT (font->getStyle () == kUnderlineFace);
font = desc.getFont ("f5");
EXPECT (font->getName () == std::string ("Arial"));
EXPECT (font->getSize () == 8);
EXPECT (font->getStyle () == kStrikethroughFace);
font = desc.getFont ("f6");
EXPECT (font->getName () == std::string ("Arial"));
EXPECT (font->getSize () == 8);
std::string altFontNames;
EXPECT (desc.getAlternativeFontNames ("f5", altFontNames) == false);
EXPECT (desc.getAlternativeFontNames ("f6", altFontNames));
EXPECT (altFontNames == "Arial, Courier");
desc.changeAlternativeFontNames ("f6", "Courier");
desc.getAlternativeFontNames ("f6", altFontNames);
EXPECT (altFontNames == "Courier");
auto name = desc.lookupFontName (font);
EXPECT (name == std::string ("f6"));
StringPtrList names;
desc.collectFontNames (names);
uint32_t numNames = 0;
for (auto& n : names)
{
if (n->at (0) != '~')
numNames++;
}
EXPECT (numNames == 6);
desc.changeFontName ("f1", "font");
EXPECT (desc.hasFontName ("font"));
auto newFont = owned (new CFontDesc (*font));
desc.changeFont ("font", newFont);
desc.changeFont ("font2", newFont);
EXPECT (desc.getFont ("font") == newFont);
EXPECT (desc.getFont ("font2") == newFont);
desc.removeFont ("font");
EXPECT (desc.hasFontName ("font") == false);
}
TEST_CASE (UIDescriptionXMLTests, Bitmaps)
{
MemoryContentProvider provider (bitmapNodesUIDesc,
static_cast<uint32_t> (strlen (bitmapNodesUIDesc)));
UIDescription desc (&provider);
EXPECT (desc.parse () == true);
EXPECT (desc.hasBitmapName ("b1"));
auto bitmap = desc.getBitmap ("b1");
EXPECT (bitmap);
auto name = desc.lookupBitmapName (bitmap);
EXPECT (name == std::string ("b1"));
StringPtrList names;
desc.collectBitmapNames (names);
EXPECT (names.size () == 2);
desc.changeBitmapName ("b1", "new bitmap");
EXPECT (desc.hasBitmapName ("new bitmap"));
desc.removeBitmap ("new bitmap");
EXPECT (desc.hasBitmapName ("new bitmap") == false);
CRect ninePartTiledOffset (10, 10, 10, 10);
desc.changeBitmap ("added bitmap node", "path to bitmap", &ninePartTiledOffset);
EXPECT (desc.hasBitmapName ("added bitmap node"));
bitmap = desc.getBitmap ("added bitmap node");
EXPECT (dynamic_cast<CNinePartTiledBitmap*> (bitmap));
auto& offsets = dynamic_cast<CNinePartTiledBitmap*> (bitmap)->getPartOffsets ();
EXPECT (offsets.left == 10 && offsets.top == 10 && offsets.right == 10 && offsets.bottom == 10);
desc.changeBitmap ("added bitmap node", "added bitmap node", nullptr);
bitmap = desc.getBitmap ("added bitmap node");
EXPECT (dynamic_cast<CNinePartTiledBitmap*> (bitmap) == nullptr);
}
TEST_CASE (UIDescriptionXMLTests, Tags)
{
MemoryContentProvider provider (tagNodesUIDesc,
static_cast<uint32_t> (strlen (tagNodesUIDesc)));
UIDescription desc (&provider);
EXPECT (desc.parse () == true);
EXPECT (desc.hasTagName ("t1"));
EXPECT (desc.getTagForName ("t1") == 1234);
EXPECT (desc.getTagForName ("t3") == 1836676199);
auto name = desc.lookupControlTagName (1234);
EXPECT (name == std::string ("t1"));
StringPtrList names;
desc.collectControlTagNames (names);
EXPECT (names.size () == 3);
desc.changeTagName ("t1", "control tag");
EXPECT (desc.hasTagName ("control tag"));
desc.changeControlTagString ("control tag", "4567 - 5");
EXPECT (desc.getTagForName ("control tag") == 4562);
std::string tagString;
EXPECT (desc.getControlTagString ("control not existing", tagString) == false);
EXPECT (desc.getControlTagString ("control tag", tagString));
EXPECT (tagString == "4567 - 5");
desc.removeTag ("control tag");
EXPECT (desc.hasTagName ("control tag") == false);
desc.changeControlTagString ("new control tag", "2*2", true);
EXPECT (desc.getTagForName ("new control tag") == 4);
}
TEST_CASE (UIDescriptionXMLTests, LookupTagsCalculateTag)
{
MemoryContentProvider provider (calculateTagNodesUIDesc,
static_cast<uint32_t> (strlen (calculateTagNodesUIDesc)));
UIDescription desc (&provider);
EXPECT (desc.parse () == true);
auto name = desc.lookupControlTagName (3);
EXPECT (name);
EXPECT (std::string (name) == "t1");
}
TEST_CASE (UIDescriptionXMLTests, Gradient)
{
MemoryContentProvider provider (gradientNodesUIDesc,
static_cast<uint32_t> (strlen (gradientNodesUIDesc)));
UIDescription desc (&provider);
EXPECT (desc.parse () == true);
EXPECT (desc.hasGradientName ("g1"));
auto gradient = desc.getGradient ("g1");
const auto& colorStops = gradient->getColorStops ();
EXPECT (colorStops.size () == 3);
auto it = colorStops.find (0.);
EXPECT (it != colorStops.end ());
EXPECT (it->second == CColor (0, 0, 0, 255));
it = colorStops.find (0.5);
EXPECT (it != colorStops.end ());
EXPECT (it->second == CColor (255, 0, 0, 255));
it = colorStops.find (1.);
EXPECT (it != colorStops.end ());
EXPECT (it->second == CColor (255, 255, 255, 255));
auto name = desc.lookupGradientName (gradient);
EXPECT (name == std::string ("g1"));
StringPtrList names;
desc.collectGradientNames (names);
EXPECT (names.size () == 1);
desc.changeGradientName ("g1", "gradient");
EXPECT (desc.hasGradientName ("gradient"));
EXPECT (desc.hasGradientName ("g1") == false);
auto newGradient = owned (CGradient::create (0., 1., kWhiteCColor, kBlackCColor));
desc.changeGradient ("gradient", newGradient);
EXPECT (desc.getGradient ("gradient") == newGradient);
desc.changeGradient ("gradientnew", newGradient);
EXPECT (desc.hasGradientName ("gradientnew"));
desc.removeGradient ("gradientnew");
EXPECT (desc.hasGradientName ("gradientnew") == false);
}
TEST_CASE (UIDescriptionXMLTests, Variables)
{
MemoryContentProvider provider (variableNodesUIDesc,
static_cast<uint32_t> (strlen (variableNodesUIDesc)));
UIDescription desc (&provider);
EXPECT (desc.parse () == true);
double value;
EXPECT (desc.getVariable ("v1", value));
EXPECT (value == 10.);
std::string strValue;
EXPECT (desc.getVariable ("v2", strValue));
EXPECT (strValue == "string");
EXPECT (desc.getVariable ("v3", strValue));
EXPECT (strValue == "string");
EXPECT (desc.getVariable ("v4", value));
EXPECT (value == 20.5);
EXPECT (desc.getVariable ("v5", value));
EXPECT (value == 20.);
EXPECT (desc.getVariable ("v6", strValue));
EXPECT (strValue == "");
}
TEST_CASE (UIDescriptionXMLTests, Calculations)
{
MemoryContentProvider provider (tagNodesUIDesc,
static_cast<uint32_t> (strlen (tagNodesUIDesc)));
UIDescription desc (&provider);
EXPECT (desc.parse () == true);
double value;
EXPECT (desc.calculateStringValue ("1", value));
EXPECT (value == 1.);
EXPECT (desc.calculateStringValue ("1+1", value));
EXPECT (value == 2.);
EXPECT (desc.calculateStringValue ("(1+1)*2", value));
EXPECT (value == 4.);
EXPECT (desc.calculateStringValue ("(1+1)*2-(3/3 + (0.5+0.5))", value));
EXPECT (value == 2.);
EXPECT (desc.calculateStringValue ("tag.t1 - 4", value));
EXPECT (value == 1230.);
EXPECT (desc.calculateStringValue ("(1+5*3", value) == false);
EXPECT (desc.calculateStringValue ("tag.unknown - 4", value) == false);
EXPECT (desc.calculateStringValue ("var.unknown", value) == false);
EXPECT (desc.calculateStringValue ("unknown", value) == false);
}
TEST_CASE (UIDescriptionXMLTests, WriteToStream)
{
std::string str (withAllNodesUIDesc);
MemoryContentProvider provider (str.data (), static_cast<uint32_t> (str.size ()));
SaveUIDescription desc (&provider);
EXPECT (desc.parse () == true);
CMemoryStream outputStream (1024, 1024, false);
EXPECT (desc.saveToStream (outputStream, defaultSafeFlags, nullptr));
outputStream.end ();
std::string result (reinterpret_cast<const char*> (outputStream.getBuffer ()));
EXPECT (result.size () == str.size ());
EXPECT (result == str);
}
TEST_CASE (UIDescriptionXMLTests, GetViewAttributes)
{
MemoryContentProvider provider (createViewUIDesc,
static_cast<uint32_t> (strlen (createViewUIDesc)));
UIDescription desc (&provider);
EXPECT (desc.parse () == true);
auto attributes = desc.getViewAttributes ("view");
EXPECT (attributes);
auto classAttr = attributes->getAttributeValue (UIViewCreator::kAttrClass);
EXPECT (classAttr);
EXPECT (*classAttr == "CViewContainer");
attributes = desc.getViewAttributes ("view not existing");
EXPECT (attributes == nullptr);
}
TEST_CASE (UIDescriptionXMLTests, CollectTemplateViewNames)
{
MemoryContentProvider provider (createViewUIDesc,
static_cast<uint32_t> (strlen (createViewUIDesc)));
UIDescription desc (&provider);
EXPECT (desc.parse () == true);
StringPtrList names;
desc.collectTemplateViewNames (names);
EXPECT (names.size () == 1);
EXPECT (*names.front () == std::string ("view"));
}
TEST_CASE (UIDescriptionXMLTests, DuplicateTemplate)
{
MemoryContentProvider provider (createViewUIDesc,
static_cast<uint32_t> (strlen (createViewUIDesc)));
UIDescription desc (&provider);
EXPECT (desc.parse () == true);
StringPtrList names;
desc.collectTemplateViewNames (names);
EXPECT (desc.duplicateTemplate ("view not existing", "viewcopy") == false);
EXPECT (desc.duplicateTemplate ("view", "viewcopy"));
EXPECT (desc.addNewTemplate ("view", nullptr) == false);
names.clear ();
desc.collectTemplateViewNames (names);
EXPECT (names.size () == 2);
EXPECT (*names.front () == std::string ("view"));
EXPECT (*names.back () == std::string ("viewcopy"));
}
TEST_CASE (UIDescriptionXMLTests, ChangeTemplateName)
{
MemoryContentProvider provider (createViewUIDesc,
static_cast<uint32_t> (strlen (createViewUIDesc)));
UIDescription desc (&provider);
EXPECT (desc.parse () == true);
EXPECT (desc.duplicateTemplate ("view", "viewcopy"));
EXPECT (desc.changeTemplateName ("viewcopy", "copyOfView"));
StringPtrList names;
desc.collectTemplateViewNames (names);
EXPECT (*names.back () == std::string ("copyOfView"));
}
TEST_CASE (UIDescriptionXMLTests, GetTemplateNameFromView)
{
MemoryContentProvider provider (createViewUIDesc,
static_cast<uint32_t> (strlen (createViewUIDesc)));
UIDescription desc (&provider);
EXPECT (desc.parse () == true);
Controller controller;
auto view = owned (desc.createView ("view", &controller));
std::string name;
desc.getTemplateNameFromView (view, name);
EXPECT (name == "view");
}
TEST_CASE (UIDescriptionXMLTests, RemoveTemplate)
{
MemoryContentProvider provider (createViewUIDesc,
static_cast<uint32_t> (strlen (createViewUIDesc)));
UIDescription desc (&provider);
EXPECT (desc.parse () == true);
EXPECT (desc.removeTemplate ("view which does not exist") == false);
EXPECT (desc.removeTemplate ("view"));
}
TEST_CASE (UIDescriptionXMLTests, AddNewTemplate)
{
MemoryContentProvider provider (createViewUIDesc,
static_cast<uint32_t> (strlen (createViewUIDesc)));
UIDescription desc (&provider);
EXPECT (desc.parse () == true);
auto a = makeOwned<UIAttributes> ();
a->setAttribute (UIViewCreator::kAttrClass, "CViewContainer");
EXPECT (desc.addNewTemplate ("addNewTemplate", a));
StringPtrList names;
desc.collectTemplateViewNames (names);
EXPECT (*names.back () == std::string ("addNewTemplate"));
}
TEST_CASE (UIDescriptionXMLTests, StoreRestoreViews)
{
MemoryContentProvider provider (createViewUIDesc,
static_cast<uint32_t> (strlen (createViewUIDesc)));
UIDescription desc (&provider);
EXPECT (desc.parse () == true);
Controller controller;
auto view = owned (desc.createView ("view", &controller));
EXPECT (view);
CMemoryStream memoryStream (1024, 1024, false);
std::list<SharedPointer<CView>> restoredView;
UIAttributes customAttributes;
customAttributes.setAttribute ("Test", "Value");
EXPECT (desc.storeViews ({view.cast<CViewContainer> ()->getView (0)}, memoryStream,
&customAttributes));
memoryStream.rewind ();
UIAttributes* customAttributesRestored = nullptr;
EXPECT (desc.restoreViews (memoryStream, restoredView, &customAttributesRestored));
EXPECT (customAttributesRestored);
EXPECT (*customAttributesRestored->getAttributeValue ("Test") == "Value");
}
TEST_CASE (UIDescriptionXMLTests, StoreRestoreViewsAttached)
{
MemoryContentProvider provider (restoreViewUIDesc,
static_cast<uint32_t> (strlen (restoreViewUIDesc)));
UIDescription desc (&provider);
EXPECT (desc.parse () == true);
Controller controller;
auto view = owned (desc.createView ("view", &controller));
EXPECT (view);
CMemoryStream memoryStream (1024, 1024, false);
std::list<SharedPointer<CView>> restoredView;
auto parentContainer = owned (new CViewContainer (CRect (0, 0, 10, 10)));
view->attached (parentContainer);
auto viewToRestore = SharedPointer<CView> (view.cast<CViewContainer> ()->getView (1));
viewToRestore = viewToRestore.cast<CViewContainer> ()->getView (0);
memoryStream.rewind ();
EXPECT (desc.storeViews ({viewToRestore}, memoryStream));
memoryStream.rewind ();
restoredView.clear ();
EXPECT (desc.restoreViews (memoryStream, restoredView));
view->removed (parentContainer);
}
TEST_CASE (UIDescriptionXMLTests, UpdateViewDescription)
{
MemoryContentProvider provider (createViewUIDesc,
static_cast<uint32_t> (strlen (createViewUIDesc)));
UIDescription desc (&provider);
EXPECT (desc.parse () == true);
Controller controller;
auto view = owned (desc.createView ("view", &controller));
EXPECT (view);
EXPECT (view->getTransparency () == false);
view->setTransparency (true);
desc.updateViewDescription ("view", view);
auto attr = desc.getViewAttributes ("view");
bool value;
EXPECT (attr->getBooleanAttribute ("transparent", value));
EXPECT (value == true);
}
TEST_CASE (UIDescriptionXMLTests, CustomAttributes)
{
MemoryContentProvider provider (createViewUIDesc,
static_cast<uint32_t> (strlen (createViewUIDesc)));
UIDescription desc (&provider);
EXPECT (desc.parse () == true);
auto attr = desc.getCustomAttributes ("Test", false);
EXPECT (attr == nullptr);
attr = desc.getCustomAttributes ("Test", true);
EXPECT (attr);
EXPECT (desc.getCustomAttributes ("Test", false) == attr);
EXPECT (desc.setCustomAttributes ("Test", nullptr) == false);
}
TEST_CASE (UIDescriptionXMLTests, Listeners)
{
MemoryContentProvider provider (completeExample,
static_cast<uint32_t> (strlen (completeExample)));
UIDescription desc (&provider);
EXPECT (desc.parse () == true);
DescriptionListenerMock mok (UIDescTestCase::TagChanged);
desc.registerListener (&mok);
desc.changeControlTagString ("NewTag", "5", true);
EXPECT (mok.callCount () == 1);
desc.changeControlTagString ("NewTag", "5", false);
EXPECT (mok.callCount () == 2);
desc.changeTagName ("NewTag", "NewTagNew");
EXPECT (mok.callCount () == 3);
desc.removeTag ("NewTagNew");
EXPECT (mok.callCount () == 4);
mok.setTestCase (UIDescTestCase::ColorChanged);
EXPECT (mok.callCount () == 0);
CColor newColor;
desc.changeColor ("NewColor", newColor);
EXPECT (mok.callCount () == 1);
desc.changeColor ("NewColor", newColor);
EXPECT (mok.callCount () == 2);
desc.changeColorName ("NewColor", "NewColorNew");
EXPECT (mok.callCount () == 3);
desc.removeColor ("NewColorNew");
EXPECT (mok.callCount () == 4);
mok.setTestCase (UIDescTestCase::FontChanged);
EXPECT (mok.callCount () == 0);
auto font = makeOwned<CFontDesc> ();
desc.changeFont ("NewFont", font);
EXPECT (mok.callCount () == 1);
desc.changeFont ("NewFont", font);
EXPECT (mok.callCount () == 2);
desc.changeFontName ("NewFont", "NewFontNew");
EXPECT (mok.callCount () == 3);
desc.changeAlternativeFontNames ("NewFontNew", "Hack, Menlo");
EXPECT (mok.callCount () == 4);
desc.removeFont ("NewFontNew");
EXPECT (mok.callCount () == 5);
mok.setTestCase (UIDescTestCase::BitmapChanged);
EXPECT (mok.callCount () == 0);
auto bitmap = makeOwned<CBitmap> (CPoint (10, 10));
desc.changeBitmap ("NewBitmap", "bitmappath");
EXPECT (mok.callCount () == 1);
desc.changeBitmap ("NewBitmap", "bitmappath");
EXPECT (mok.callCount () == 2);
desc.changeBitmapName ("NewBitmap", "NewBitmapNew");
EXPECT (mok.callCount () == 3);
desc.removeBitmap ("NewBitmapNew");
EXPECT (mok.callCount () == 4);
mok.setTestCase (UIDescTestCase::GradientChanged);
EXPECT (mok.callCount () == 0);
auto gradient = owned (CGradient::create (0., 0., newColor, newColor));
desc.changeGradient ("NewGradient", gradient);
EXPECT (mok.callCount () == 1);
desc.changeGradient ("NewGradient", gradient);
EXPECT (mok.callCount () == 2);
desc.changeGradientName ("NewGradient", "NewGradientNew");
EXPECT (mok.callCount () == 3);
desc.removeGradient ("NewGradientNew");
EXPECT (mok.callCount () == 4);
mok.setTestCase (UIDescTestCase::TemplateChanged);
EXPECT (mok.callCount () == 0);
desc.addNewTemplate ("NewTemplate", makeOwned<UIAttributes> ());
EXPECT (mok.callCount () == 1);
desc.changeTemplateName ("NewTemplate", "NewTemplateNew");
EXPECT (mok.callCount () == 2);
desc.duplicateTemplate ("NewTemplateNew", "NewTemplateNewDup");
EXPECT (mok.callCount () == 3);
desc.removeTemplate ("NewTemplateNew");
EXPECT (mok.callCount () == 4);
desc.removeTemplate ("NewTemplateNewDup");
EXPECT (mok.callCount () == 5);
desc.unregisterListener (&mok);
}
TEST_CASE (UIDescriptionXMLTests, FocusSettings)
{
MemoryContentProvider provider (emptyUIDesc, static_cast<uint32_t> (strlen (emptyUIDesc)));
UIDescription desc (&provider);
EXPECT (desc.parse () == true);
FocusDrawingSettings fd;
fd.enabled = true;
fd.width = 1.5;
fd.colorName = "FocusColor";
desc.setFocusDrawingSettings (fd);
auto fd2 = desc.getFocusDrawingSettings ();
EXPECT (!(fd != fd2));
}
TEST_CASE (UIDescriptionXMLTests, SharedResources)
{
MemoryContentProvider provider (emptyUIDesc, static_cast<uint32_t> (strlen (emptyUIDesc)));
UIDescription desc (&provider);
EXPECT (desc.parse () == true);
CColor color1;
CColor color2;
EXPECT (desc.getColor ("c1", color1) == false);
EXPECT (desc.getFont ("f1") == nullptr);
EXPECT (desc.getGradient ("g1") == nullptr);
EXPECT (desc.getBitmap ("b1") == nullptr);
MemoryContentProvider resProvider (sharedResourcesUIDesc,
static_cast<uint32_t> (strlen (sharedResourcesUIDesc)));
UIDescription resDesc (&resProvider);
EXPECT (resDesc.parse () == true);
desc.setSharedResources (&resDesc);
EXPECT (desc.getSharedResources () == &resDesc);
EXPECT (desc.getColor ("c1", color1) == true);
EXPECT (resDesc.getColor ("c1", color2) == true);
EXPECT (color1 == color2);
EXPECT (desc.getFont ("f1") != nullptr);
EXPECT (desc.getFont ("f1") == resDesc.getFont ("f1"));
EXPECT (desc.getGradient ("g1") != nullptr);
EXPECT (desc.getGradient ("g1") == resDesc.getGradient ("g1"));
EXPECT (desc.getBitmap ("b1") != nullptr);
EXPECT (desc.getBitmap ("b1") == resDesc.getBitmap ("b1"));
desc.setSharedResources (nullptr);
}
} // VSTGUI
#endif
@@ -0,0 +1,52 @@
// This file is part of VSTGUI. It is subject to the license terms
// in the LICENSE file found in the top-level directory of this
// distribution and at http://github.com/steinbergmedia/vstgui/LICENSE
#pragma once
#include "../../../uidescription/iuidescription.h"
#include "../../../uidescription/uiattributes.h"
namespace VSTGUI {
class UIDescriptionAdapter : public IUIDescription
{
public:
CView* createView (UTF8StringPtr name, IController* controller) const override { return nullptr; }
CBitmap* getBitmap (UTF8StringPtr name) const override { return nullptr; }
CFontRef getFont (UTF8StringPtr name) const override { return nullptr; }
bool getColor (UTF8StringPtr name, CColor& color) const override { return false; }
CGradient* getGradient (UTF8StringPtr name) const override { return nullptr; }
int32_t getTagForName (UTF8StringPtr name) const override { return -1; }
IControlListener* getControlListener (UTF8StringPtr name) const override { return nullptr; }
IController* getController () const override { return nullptr; }
UTF8StringPtr lookupColorName (const CColor& color) const override { return nullptr; }
UTF8StringPtr lookupFontName (const CFontRef font) const override { return nullptr; }
UTF8StringPtr lookupBitmapName (const CBitmap* bitmap) const override { return nullptr; }
UTF8StringPtr lookupGradientName (const CGradient* gradient) const override { return nullptr; }
UTF8StringPtr lookupControlTagName (const int32_t tag) const override { return nullptr; }
bool getVariable (UTF8StringPtr name, double& value) const override { return false; }
bool getVariable (UTF8StringPtr name, std::string& value) const override { return false; }
void collectTemplateViewNames (std::list<const std::string*>& names) const override {}
void collectColorNames (std::list<const std::string*>& names) const override {}
void collectFontNames (std::list<const std::string*>& names) const override {}
void collectBitmapNames (std::list<const std::string*>& names) const override {}
void collectGradientNames (std::list<const std::string*>& names) const override {}
void collectControlTagNames (std::list<const std::string*>& names) const override {}
const IViewFactory* getViewFactory () const override { return nullptr; }
bool setCustomAttributes (UTF8StringPtr name, const SharedPointer<UIAttributes>& attr) override
{
return false;
}
SharedPointer<UIAttributes> getCustomAttributes (UTF8StringPtr name) const override
{
return {};
}
};
}
@@ -0,0 +1,58 @@
// This file is part of VSTGUI. It is subject to the license terms
// in the LICENSE file found in the top-level directory of this
// distribution and at http://github.com/steinbergmedia/vstgui/LICENSE
#include "../../../../lib/controls/csplashscreen.h"
#include "../../../../lib/cstring.h"
#include "../../../../uidescription/detail/uiviewcreatorattributes.h"
#include "../../../../uidescription/uiattributes.h"
#include "../../../../uidescription/uiviewfactory.h"
#include "../../unittests.h"
#include "helpers.h"
namespace VSTGUI {
using namespace UIViewCreator;
TEST_CASE (CAnimationSplashScreenCreatorTest, SplashBitmap)
{
DummyUIDescription uidesc;
testAttribute<CAnimationSplashScreen> (
kCAnimationSplashScreen, kAttrSplashBitmap, kBitmapName, &uidesc,
[&] (CAnimationSplashScreen* v) { return v->getSplashBitmap () == uidesc.bitmap; });
}
TEST_CASE (CAnimationSplashScreenCreatorTest, SplashOrigin)
{
DummyUIDescription uidesc;
CPoint p (20, 20);
testAttribute<CAnimationSplashScreen> (
kCAnimationSplashScreen, kAttrSplashOrigin, p, &uidesc,
[&] (CAnimationSplashScreen* v) { return v->getSplashRect ().getTopLeft () == p; });
}
TEST_CASE (CAnimationSplashScreenCreatorTest, SplashSize)
{
DummyUIDescription uidesc;
CPoint p (20, 20);
testAttribute<CAnimationSplashScreen> (
kCAnimationSplashScreen, kAttrSplashSize, p, &uidesc,
[&] (CAnimationSplashScreen* v) { return v->getSplashRect ().getSize () == p; });
}
TEST_CASE (CAnimationSplashScreenCreatorTest, AnimationIndex)
{
DummyUIDescription uidesc;
testAttribute<CAnimationSplashScreen> (
kCAnimationSplashScreen, kAttrAnimationIndex, 1, &uidesc,
[&] (CAnimationSplashScreen* v) { return v->getAnimationIndex () == 1; });
}
TEST_CASE (CAnimationSplashScreenCreatorTest, AnimationTime)
{
DummyUIDescription uidesc;
testAttribute<CAnimationSplashScreen> (
kCAnimationSplashScreen, kAttrAnimationTime, 222, &uidesc,
[&] (CAnimationSplashScreen* v) { return v->getAnimationTime () == 222; });
}
} // VSTGUI
@@ -0,0 +1,43 @@
// This file is part of VSTGUI. It is subject to the license terms
// in the LICENSE file found in the top-level directory of this
// distribution and at http://github.com/steinbergmedia/vstgui/LICENSE
#include "../../../../lib/controls/cknob.h"
#include "../../../../lib/cstring.h"
#include "../../../../uidescription/detail/uiviewcreatorattributes.h"
#include "../../../../uidescription/uiattributes.h"
#include "../../../../uidescription/uiviewfactory.h"
#include "../../unittests.h"
#include "helpers.h"
namespace VSTGUI {
using namespace UIViewCreator;
#if VSTGUI_ENABLE_DEPRECATED_METHODS
TEST_CASE (CAnimKnobCreatorTest, HeightOfOneImage)
{
DummyUIDescription uidesc;
testAttribute<CAnimKnob> (kCAnimKnob, kAttrHeightOfOneImage, 10, &uidesc,
[] (CAnimKnob* v) { return v->getHeightOfOneImage () == 10; });
}
TEST_CASE (CAnimKnobCreatorTest, SubPixmaps)
{
DummyUIDescription uidesc;
testAttribute<CAnimKnob> (kCAnimKnob, kAttrSubPixmaps, 11, &uidesc,
[] (CAnimKnob* v) { return v->getNumSubPixmaps () == 11; });
}
#endif
TEST_CASE (CAnimKnobCreatorTest, InverseBitmap)
{
DummyUIDescription uidesc;
testAttribute<CAnimKnob> (kCAnimKnob, kAttrInverseBitmap, true, &uidesc,
[] (CAnimKnob* v) { return v->getInverseBitmap () == true; });
testAttribute<CAnimKnob> (kCAnimKnob, kAttrInverseBitmap, false, &uidesc,
[] (CAnimKnob* v) { return v->getInverseBitmap () == false; });
}
} // VSTGUI
@@ -0,0 +1,90 @@
// This file is part of VSTGUI. It is subject to the license terms
// in the LICENSE file found in the top-level directory of this
// distribution and at http://github.com/steinbergmedia/vstgui/LICENSE
#include "../../../../lib/controls/cbuttons.h"
#include "../../../../lib/cstring.h"
#include "../../../../uidescription/detail/uiviewcreatorattributes.h"
#include "../../../../uidescription/uiattributes.h"
#include "../../../../uidescription/uiviewfactory.h"
#include "../../unittests.h"
#include "helpers.h"
namespace VSTGUI {
using namespace UIViewCreator;
TEST_CASE (CCheckBoxCreatorTest, Title)
{
DummyUIDescription uidesc;
testAttribute<CCheckBox> (kCCheckBox, kAttrTitle, "title", &uidesc,
[] (CCheckBox* b) { return b->getTitle () == "title"; });
}
TEST_CASE (CCheckBoxCreatorTest, Font)
{
DummyUIDescription uidesc;
testAttribute<CCheckBox> (kCCheckBox, kAttrFont, kFontName, &uidesc,
[&] (CCheckBox* b) { return uidesc.font == b->getFont (); }, true);
}
TEST_CASE (CCheckBoxCreatorTest, FontColor)
{
DummyUIDescription uidesc;
testAttribute<CCheckBox> (kCCheckBox, kAttrFontColor, kColorName, &uidesc,
[&] (CCheckBox* b) { return b->getFontColor () == uidesc.color; });
}
TEST_CASE (CCheckBoxCreatorTest, BoxFrameColor)
{
DummyUIDescription uidesc;
testAttribute<CCheckBox> (
kCCheckBox, kAttrBoxframeColor, kColorName, &uidesc,
[&] (CCheckBox* b) { return b->getBoxFrameColor () == uidesc.color; });
}
TEST_CASE (CCheckBoxCreatorTest, BoxFillColor)
{
DummyUIDescription uidesc;
testAttribute<CCheckBox> (kCCheckBox, kAttrBoxfillColor, kColorName, &uidesc,
[&] (CCheckBox* b) { return b->getBoxFillColor () == uidesc.color; });
}
TEST_CASE (CCheckBoxCreatorTest, CheckmarkColor)
{
DummyUIDescription uidesc;
testAttribute<CCheckBox> (
kCCheckBox, kAttrCheckmarkColor, kColorName, &uidesc,
[&] (CCheckBox* b) { return b->getCheckMarkColor () == uidesc.color; });
}
TEST_CASE (CCheckBoxCreatorTest, DrawCrossbox)
{
DummyUIDescription uidesc;
testAttribute<CCheckBox> (kCCheckBox, kAttrDrawCrossbox, true, &uidesc, [&] (CCheckBox* b) {
return b->getStyle () & CCheckBox::kDrawCrossBox;
});
}
TEST_CASE (CCheckBoxCreatorTest, AutoSizeToFit)
{
DummyUIDescription uidesc;
testAttribute<CCheckBox> (kCCheckBox, kAttrAutosizeToFit, true, &uidesc, [&] (CCheckBox* b) {
return b->getStyle () & CCheckBox::kAutoSizeToFit;
});
}
TEST_CASE (CCheckBoxCreatorTest, FrameWidth)
{
DummyUIDescription uidesc;
testAttribute<CCheckBox> (kCCheckBox, kAttrFrameWidth, 15., &uidesc,
[&] (CCheckBox* b) { return b->getFrameWidth () == 15.; });
}
TEST_CASE (CCheckBoxCreatorTest, RoundRectRadius)
{
DummyUIDescription uidesc;
testAttribute<CCheckBox> (kCCheckBox, kAttrRoundRectRadius, 12., &uidesc,
[&] (CCheckBox* b) { return b->getRoundRectRadius () == 12.; });
}
} // VSTGUI
@@ -0,0 +1,94 @@
// This file is part of VSTGUI. It is subject to the license terms
// in the LICENSE file found in the top-level directory of this
// distribution and at http://github.com/steinbergmedia/vstgui/LICENSE
#include "../../../../lib/controls/ccontrol.h"
#include "../../../../lib/controls/icontrollistener.h"
#include "../../../../lib/cstring.h"
#include "../../../../uidescription/detail/uiviewcreatorattributes.h"
#include "../../../../uidescription/uiattributes.h"
#include "../../../../uidescription/uiviewfactory.h"
#include "../../unittests.h"
#include "helpers.h"
namespace VSTGUI {
using namespace UIViewCreator;
namespace {
struct DummyListener : public IControlListener
{
void valueChanged (CControl* pControl) override {}
};
} // anonymous
TEST_CASE (CControlCreatorTest, DefaultValue)
{
testAttribute<CControl> (kCControl, kAttrDefaultValue, 1., nullptr,
[] (CControl* v) { return v->getDefaultValue () == 1.; });
}
TEST_CASE (CControlCreatorTest, MinValue)
{
testAttribute<CControl> (kCControl, kAttrMinValue, 0.5, nullptr,
[] (CControl* v) { return v->getMin () == 0.5; });
}
TEST_CASE (CControlCreatorTest, MaxValue)
{
testAttribute<CControl> (kCControl, kAttrMaxValue, 0.5, nullptr,
[] (CControl* v) { return v->getMax () == 0.5; });
}
TEST_CASE (CControlCreatorTest, WheelIncValue)
{
testAttribute<CControl> (kCControl, kAttrWheelIncValue, 0.5, nullptr,
[] (CControl* v) { return v->getWheelInc () == 0.5; });
}
TEST_CASE (CControlCreatorTest, TagUnknown)
{
DummyUIDescription uidesc;
testAttribute<CControl> (kCControl, kAttrControlTag, kTagName, &uidesc, [&] (CControl* v) {
return v->getTag () == -1 && v->getListener () == nullptr;
});
}
TEST_CASE (CControlCreatorTest, TagStrEmpty)
{
DummyUIDescription uidesc;
testAttribute<CControl> (kCControl, kAttrControlTag, "", &uidesc, [&] (CControl* v) {
return v->getTag () == -1 && v->getListener () == nullptr;
});
}
TEST_CASE (CControlCreatorTest, TagWithNumber)
{
DummyUIDescription uidesc;
testAttribute<CControl> (kCControl, kAttrControlTag, "5", &uidesc, [&] (CControl* v) {
return v->getTag () == 5 && v->getListener () == nullptr;
});
}
TEST_CASE (CControlCreatorTest, TagNoListener)
{
DummyUIDescription uidesc;
uidesc.tag = 5;
testAttribute<CControl> (
kCControl, kAttrControlTag, kTagName, &uidesc,
[&] (CControl* v) { return v->getTag () == 5 && v->getListener () == nullptr; }, true);
}
TEST_CASE (CControlCreatorTest, TagWithListener)
{
DummyUIDescription uidesc;
DummyListener listener;
uidesc.tag = 5;
uidesc.listener = &listener;
testAttribute<CControl> (
kCControl, kAttrControlTag, kTagName, &uidesc,
[&] (CControl* v) { return v->getTag () == 5 && v->getListener () == &listener; }, true);
}
} // VSTGUI
@@ -0,0 +1,139 @@
// This file is part of VSTGUI. It is subject to the license terms
// in the LICENSE file found in the top-level directory of this
// distribution and at http://github.com/steinbergmedia/vstgui/LICENSE
#include "../../../../lib/cgradientview.h"
#include "../../../../lib/cstring.h"
#include "../../../../uidescription/detail/uiviewcreatorattributes.h"
#include "../../../../uidescription/uiattributes.h"
#include "../../../../uidescription/uiviewfactory.h"
#include "../../unittests.h"
#include "helpers.h"
namespace VSTGUI {
using namespace UIViewCreator;
TEST_CASE (CGradientViewCreatorTest, FrameColor)
{
DummyUIDescription uidesc;
testAttribute<CGradientView> (
kCGradientView, kAttrFrameColor, kColorName, &uidesc,
[&] (CGradientView* v) { return v->getFrameColor () == uidesc.color; });
}
TEST_CASE (CGradientViewCreatorTest, GradientAngle)
{
DummyUIDescription uidesc;
testAttribute<CGradientView> (kCGradientView, kAttrGradientAngle, 5., &uidesc,
[&] (CGradientView* v) { return v->getGradientAngle () == 5.; });
}
TEST_CASE (CGradientViewCreatorTest, RoundRectRadius)
{
DummyUIDescription uidesc;
testAttribute<CGradientView> (
kCGradientView, kAttrRoundRectRadius, 35., &uidesc,
[&] (CGradientView* v) { return v->getRoundRectRadius () == 35.; });
}
TEST_CASE (CGradientViewCreatorTest, FrameWidth)
{
DummyUIDescription uidesc;
testAttribute<CGradientView> (kCGradientView, kAttrFrameWidth, 5., &uidesc,
[&] (CGradientView* v) { return v->getFrameWidth () == 5.; });
}
TEST_CASE (CGradientViewCreatorTest, DrawAntialiased)
{
DummyUIDescription uidesc;
testAttribute<CGradientView> (kCGradientView, kAttrDrawAntialiased, true, &uidesc,
[&] (CGradientView* v) { return v->getDrawAntialised (); });
testAttribute<CGradientView> (
kCGradientView, kAttrDrawAntialiased, false, &uidesc,
[&] (CGradientView* v) { return v->getDrawAntialised () == false; });
}
TEST_CASE (CGradientViewCreatorTest, GradientStyle)
{
DummyUIDescription uidesc;
testAttribute<CGradientView> (
kCGradientView, kAttrGradientStyle, "radial", &uidesc, [&] (CGradientView* v) {
return v->getGradientStyle () == CGradientView::kRadialGradient;
});
testAttribute<CGradientView> (
kCGradientView, kAttrGradientStyle, "linear", &uidesc, [&] (CGradientView* v) {
return v->getGradientStyle () == CGradientView::kLinearGradient;
});
}
TEST_CASE (CGradientViewCreatorTest, RadialCenter)
{
DummyUIDescription uidesc;
CPoint p (20, 20);
testAttribute<CGradientView> (kCGradientView, kAttrRadialCenter, p, &uidesc,
[&] (CGradientView* v) { return v->getRadialCenter () == p; });
}
TEST_CASE (CGradientViewCreatorTest, RadialRadius)
{
DummyUIDescription uidesc;
testAttribute<CGradientView> (kCGradientView, kAttrRadialRadius, 25., &uidesc,
[&] (CGradientView* v) { return v->getRadialRadius () == 25.; });
}
TEST_CASE (CGradientViewCreatorTest, Gradient)
{
DummyUIDescription uidesc;
testAttribute<CGradientView> (
kCGradientView, kAttrGradient, kGradientName, &uidesc,
[&] (CGradientView* v) { return v->getGradient () == uidesc.gradient; });
}
TEST_CASE (CGradientViewCreatorTest, GradientStyleValues)
{
DummyUIDescription uidesc;
testPossibleValues (kCGradientView, kAttrGradientStyle, &uidesc, {"radial", "linear"});
}
TEST_CASE (CGradientViewCreatorTest, GradientAngleMinMax)
{
DummyUIDescription uidesc;
testMinMaxValues (kCGradientView, kAttrGradientAngle, &uidesc, 0., 360.);
}
TEST_CASE (CGradientViewCreatorTest, LegacyGradient)
{
DummyUIDescription uidesc;
UIViewFactory factory;
UIAttributes a;
a.setAttribute (kAttrClass, kCGradientView);
a.setAttribute (kAttrGradientStartColor, kColorName);
auto v = owned (factory.createView (a, &uidesc));
auto view = v.cast<CGradientView> ();
EXPECT (view);
EXPECT (view->getGradient () == nullptr);
a.setAttribute (kAttrGradientEndColor, kColorName);
v = owned (factory.createView (a, &uidesc));
view = v.cast<CGradientView> ();
EXPECT (view);
EXPECT (view->getGradient () == nullptr);
a.setDoubleAttribute (kAttrGradientStartColorOffset, 0.);
v = owned (factory.createView (a, &uidesc));
view = v.cast<CGradientView> ();
EXPECT (view);
EXPECT (view->getGradient () == nullptr);
a.setDoubleAttribute (kAttrGradientEndColorOffset, 1.);
v = owned (factory.createView (a, &uidesc));
view = v.cast<CGradientView> ();
EXPECT (view);
EXPECT (view->getGradient ());
}
} // VSTGUI
@@ -0,0 +1,36 @@
// This file is part of VSTGUI. It is subject to the license terms
// in the LICENSE file found in the top-level directory of this
// distribution and at http://github.com/steinbergmedia/vstgui/LICENSE
#include "../../../../lib/controls/cswitch.h"
#include "../../../../lib/cstring.h"
#include "../../../../uidescription/detail/uiviewcreatorattributes.h"
#include "../../../../uidescription/uiattributes.h"
#include "../../../../uidescription/uiviewfactory.h"
#include "../../unittests.h"
#include "helpers.h"
namespace VSTGUI {
using namespace UIViewCreator;
#if VSTGUI_ENABLE_DEPRECATED_METHODS
TEST_CASE (CHorizontalSwitchCreatorTest, HeightOfOneImage)
{
DummyUIDescription uidesc;
testAttribute<CHorizontalSwitch> (
kCHorizontalSwitch, kAttrHeightOfOneImage, 10, &uidesc,
[] (CHorizontalSwitch* v) { return v->getHeightOfOneImage () == 10; });
}
TEST_CASE (CHorizontalSwitchCreatorTest, SubPixmaps)
{
DummyUIDescription uidesc;
testAttribute<CHorizontalSwitch> (
kCHorizontalSwitch, kAttrSubPixmaps, 11, &uidesc,
[] (CHorizontalSwitch* v) { return v->getNumSubPixmaps () == 11; });
}
#endif
} // VSTGUI
@@ -0,0 +1,34 @@
// This file is part of VSTGUI. It is subject to the license terms
// in the LICENSE file found in the top-level directory of this
// distribution and at http://github.com/steinbergmedia/vstgui/LICENSE
#include "../../../../lib/controls/cbuttons.h"
#include "../../../../lib/cstring.h"
#include "../../../../uidescription/detail/uiviewcreatorattributes.h"
#include "../../../../uidescription/uiattributes.h"
#include "../../../../uidescription/uiviewfactory.h"
#include "../../unittests.h"
#include "helpers.h"
namespace VSTGUI {
using namespace UIViewCreator;
#if VSTGUI_ENABLE_DEPRECATED_METHODS
TEST_CASE (CKickButtonCreatorTest, HeightOfOneImage)
{
DummyUIDescription uidesc;
testAttribute<CKickButton> (kCKickButton, kAttrHeightOfOneImage, 10, &uidesc,
[] (CKickButton* v) { return v->getHeightOfOneImage () == 10; });
}
TEST_CASE (CKickButtonCreatorTest, SubPixmaps)
{
DummyUIDescription uidesc;
testAttribute<CKickButton> (kCKickButton, kAttrSubPixmaps, 11, &uidesc,
[] (CKickButton* v) { return v->getNumSubPixmaps () == 11; });
}
#endif
} // VSTGUI
@@ -0,0 +1,186 @@
// This file is part of VSTGUI. It is subject to the license terms
// in the LICENSE file found in the top-level directory of this
// distribution and at http://github.com/steinbergmedia/vstgui/LICENSE
#include "../../../../lib/cbitmap.h"
#include "../../../../lib/cgradient.h"
#include "../../../../lib/controls/cknob.h"
#include "../../../../lib/cstring.h"
#include "../../../../uidescription/detail/uiviewcreatorattributes.h"
#include "../../../../uidescription/uiattributes.h"
#include "../../../../uidescription/uiviewfactory.h"
#include "../../unittests.h"
#include "helpers.h"
namespace VSTGUI {
using namespace UIViewCreator;
TEST_CASE (CKnobCreatorTest, AngleStart)
{
DummyUIDescription uidesc;
testAttribute<CKnob> (kCKnob, kAttrAngleStart, 20., &uidesc, [&] (CKnob* v) {
return static_cast<int32_t> (v->getStartAngle () / Constants::pi * 180.) == 20;
});
}
TEST_CASE (CKnobCreatorTest, AngleRange)
{
DummyUIDescription uidesc;
testAttribute<CKnob> (kCKnob, kAttrAngleRange, 100., &uidesc, [&] (CKnob* v) {
return static_cast<int32_t> (v->getRangeAngle () / Constants::pi * 180.) == 100;
});
}
TEST_CASE (CKnobCreatorTest, KnobRange)
{
DummyUIDescription uidesc;
testAttribute<CKnob> (kCKnob, kAttrKnobRange, 200., &uidesc,
[&] (CKnob* v) { return v->getKnobRange () == 200.; });
}
TEST_CASE (CKnobCreatorTest, ValueInset)
{
DummyUIDescription uidesc;
testAttribute<CKnob> (kCKnob, kAttrValueInset, 10., &uidesc,
[&] (CKnob* v) { return v->getInsetValue () == 10.; });
}
TEST_CASE (CKnobCreatorTest, CoronaInset)
{
DummyUIDescription uidesc;
testAttribute<CKnob> (kCKnob, kAttrCoronaInset, 10., &uidesc,
[&] (CKnob* v) { return v->getCoronaInset () == 10.; });
}
TEST_CASE (CKnobCreatorTest, ZoomFactor)
{
DummyUIDescription uidesc;
testAttribute<CKnob> (kCKnob, kAttrZoomFactor, 10., &uidesc,
[&] (CKnob* v) { return v->getZoomFactor () == 10.; });
}
TEST_CASE (CKnobCreatorTest, HandleLineWidth)
{
DummyUIDescription uidesc;
testAttribute<CKnob> (kCKnob, kAttrHandleLineWidth, 10., &uidesc,
[&] (CKnob* v) { return v->getHandleLineWidth () == 10.; });
}
TEST_CASE (CKnobCreatorTest, CoronaColor)
{
DummyUIDescription uidesc;
testAttribute<CKnob> (kCKnob, kAttrCoronaColor, kColorName, &uidesc,
[&] (CKnob* v) { return v->getCoronaColor () == uidesc.color; });
}
TEST_CASE (CKnobCreatorTest, HandleShadowColor)
{
DummyUIDescription uidesc;
testAttribute<CKnob> (kCKnob, kAttrHandleShadowColor, kColorName, &uidesc,
[&] (CKnob* v) { return v->getColorShadowHandle () == uidesc.color; });
}
TEST_CASE (CKnobCreatorTest, HandleColor)
{
DummyUIDescription uidesc;
testAttribute<CKnob> (kCKnob, kAttrHandleColor, kColorName, &uidesc,
[&] (CKnob* v) { return v->getColorHandle () == uidesc.color; });
}
TEST_CASE (CKnobCreatorTest, HandleBitmap)
{
DummyUIDescription uidesc;
testAttribute<CKnob> (kCKnob, kAttrHandleBitmap, kBitmapName, &uidesc,
[&] (CKnob* v) { return v->getHandleBitmap () == uidesc.bitmap; });
}
TEST_CASE (CKnobCreatorTest, CircleDrawing)
{
DummyUIDescription uidesc;
testAttribute<CKnob> (kCKnob, kAttrCircleDrawing, true, &uidesc, [&] (CKnob* v) {
return v->getDrawStyle () & CKnob::kHandleCircleDrawing;
});
testAttribute<CKnob> (kCKnob, kAttrCircleDrawing, false, &uidesc, [&] (CKnob* v) {
return !(v->getDrawStyle () & CKnob::kHandleCircleDrawing);
});
}
TEST_CASE (CKnobCreatorTest, CoronaDrawing)
{
DummyUIDescription uidesc;
testAttribute<CKnob> (kCKnob, kAttrCoronaDrawing, true, &uidesc,
[&] (CKnob* v) { return v->getDrawStyle () & CKnob::kCoronaDrawing; });
testAttribute<CKnob> (kCKnob, kAttrCoronaDrawing, false, &uidesc,
[&] (CKnob* v) { return !(v->getDrawStyle () & CKnob::kCoronaDrawing); });
}
TEST_CASE (CKnobCreatorTest, CoronaFromCenter)
{
DummyUIDescription uidesc;
testAttribute<CKnob> (kCKnob, kAttrCoronaFromCenter, true, &uidesc,
[&] (CKnob* v) { return v->getDrawStyle () & CKnob::kCoronaFromCenter; });
testAttribute<CKnob> (kCKnob, kAttrCoronaFromCenter, false, &uidesc, [&] (CKnob* v) {
return !(v->getDrawStyle () & CKnob::kCoronaFromCenter);
});
}
TEST_CASE (CKnobCreatorTest, CoronaInverted)
{
DummyUIDescription uidesc;
testAttribute<CKnob> (kCKnob, kAttrCoronaInverted, true, &uidesc,
[&] (CKnob* v) { return v->getDrawStyle () & CKnob::kCoronaInverted; });
testAttribute<CKnob> (kCKnob, kAttrCoronaInverted, false, &uidesc, [&] (CKnob* v) {
return !(v->getDrawStyle () & CKnob::kCoronaInverted);
});
}
TEST_CASE (CKnobCreatorTest, CoronaDashDot)
{
DummyUIDescription uidesc;
testAttribute<CKnob> (kCKnob, kAttrCoronaDashDot, true, &uidesc, [&] (CKnob* v) {
return v->getDrawStyle () & CKnob::kCoronaLineDashDot;
});
testAttribute<CKnob> (kCKnob, kAttrCoronaDashDot, false, &uidesc, [&] (CKnob* v) {
return !(v->getDrawStyle () & CKnob::kCoronaLineDashDot);
});
}
TEST_CASE (CKnobCreatorTest, CoronaOutline)
{
DummyUIDescription uidesc;
testAttribute<CKnob> (kCKnob, kAttrCoronaOutline, true, &uidesc,
[&] (CKnob* v) { return v->getDrawStyle () & CKnob::kCoronaOutline; });
testAttribute<CKnob> (kCKnob, kAttrCoronaOutline, false, &uidesc,
[&] (CKnob* v) { return !(v->getDrawStyle () & CKnob::kCoronaOutline); });
}
TEST_CASE (CKnobCreatorTest, CoronaLineCapButt)
{
DummyUIDescription uidesc;
testAttribute<CKnob> (kCKnob, kAttrCoronaLineCapButt, true, &uidesc, [&] (CKnob* v) {
return v->getDrawStyle () & CKnob::kCoronaLineCapButt;
});
testAttribute<CKnob> (kCKnob, kAttrCoronaLineCapButt, false, &uidesc, [&] (CKnob* v) {
return !(v->getDrawStyle () & CKnob::kCoronaLineCapButt);
});
}
TEST_CASE (CKnobCreatorTest, SkipHandleDrawing)
{
DummyUIDescription uidesc;
testAttribute<CKnob> (kCKnob, kAttrSkipHandleDrawing, true, &uidesc, [&] (CKnob* v) {
return v->getDrawStyle () & CKnob::kSkipHandleDrawing;
});
testAttribute<CKnob> (kCKnob, kAttrSkipHandleDrawing, false, &uidesc, [&] (CKnob* v) {
return !(v->getDrawStyle () & CKnob::kSkipHandleDrawing);
});
}
TEST_CASE (CKnobCreatorTest, CoronaOutlineWithAdd)
{
DummyUIDescription uidesc;
testAttribute<CKnob> (kCKnob, kAttrCoronaOutlineWidthAdd, 10., &uidesc,
[&] (CKnob* v) { return v->getCoronaOutlineWidthAdd () == 10.; });
}
} // VSTGUI
@@ -0,0 +1,23 @@
// This file is part of VSTGUI. It is subject to the license terms
// in the LICENSE file found in the top-level directory of this
// distribution and at http://github.com/steinbergmedia/vstgui/LICENSE
#include "../../../../lib/clayeredviewcontainer.h"
#include "../../../../lib/cstring.h"
#include "../../../../uidescription/detail/uiviewcreatorattributes.h"
#include "../../../../uidescription/uiattributes.h"
#include "../../../../uidescription/uiviewfactory.h"
#include "../../unittests.h"
#include "helpers.h"
namespace VSTGUI {
using namespace UIViewCreator;
TEST_CASE (CLayeredViewContainerCreatorTest, ZIndex)
{
testAttribute<CLayeredViewContainer> (
kCLayeredViewContainer, kAttrZIndex, 1, nullptr,
[] (CLayeredViewContainer* v) { return v->getZIndex () == 1; });
}
} // VSTGUI
@@ -0,0 +1,34 @@
// This file is part of VSTGUI. It is subject to the license terms
// in the LICENSE file found in the top-level directory of this
// distribution and at http://github.com/steinbergmedia/vstgui/LICENSE
#include "../../../../lib/controls/cmoviebitmap.h"
#include "../../../../lib/cstring.h"
#include "../../../../uidescription/detail/uiviewcreatorattributes.h"
#include "../../../../uidescription/uiattributes.h"
#include "../../../../uidescription/uiviewfactory.h"
#include "../../unittests.h"
#include "helpers.h"
namespace VSTGUI {
using namespace UIViewCreator;
#if VSTGUI_ENABLE_DEPRECATED_METHODS
TEST_CASE (CMovieBitmapCreatorTest, HeightOfOneImage)
{
DummyUIDescription uidesc;
testAttribute<CMovieBitmap> (kCMovieBitmap, kAttrHeightOfOneImage, 10, &uidesc,
[] (CMovieBitmap* v) { return v->getHeightOfOneImage () == 10; });
}
TEST_CASE (CMovieBitmapCreatorTest, SubPixmaps)
{
DummyUIDescription uidesc;
testAttribute<CMovieBitmap> (kCMovieBitmap, kAttrSubPixmaps, 11, &uidesc,
[] (CMovieBitmap* v) { return v->getNumSubPixmaps () == 11; });
}
#endif
} // VSTGUI
@@ -0,0 +1,35 @@
// This file is part of VSTGUI. It is subject to the license terms
// in the LICENSE file found in the top-level directory of this
// distribution and at http://github.com/steinbergmedia/vstgui/LICENSE
#include "../../../../lib/controls/cmoviebutton.h"
#include "../../../../lib/cstring.h"
#include "../../../../uidescription/detail/uiviewcreatorattributes.h"
#include "../../../../uidescription/uiattributes.h"
#include "../../../../uidescription/uiviewfactory.h"
#include "../../unittests.h"
#include "helpers.h"
namespace VSTGUI {
using namespace UIViewCreator;
#if VSTGUI_ENABLE_DEPRECATED_METHODS
TEST_CASE (CMovieButtonCreatorTest, HeightOfOneImage)
{
DummyUIDescription uidesc;
testAttribute<CMovieButton> (kCMovieButton, kAttrHeightOfOneImage, 10, &uidesc,
[] (CMovieButton* v) { return v->getHeightOfOneImage () == 10; });
}
TEST_CASE (CMovieButtonCreatorTest, SubPixmaps)
{
DummyUIDescription uidesc;
testAttribute<CMovieButton> (kCMovieButton, kAttrSubPixmaps, 11, &uidesc,
[] (CMovieButton* v) { return v->getNumSubPixmaps () == 11; });
}
#endif
} // VSTGUI
@@ -0,0 +1,48 @@
// This file is part of VSTGUI. It is subject to the license terms
// in the LICENSE file found in the top-level directory of this
// distribution and at http://github.com/steinbergmedia/vstgui/LICENSE
#include "../../../../lib/controls/ctextlabel.h"
#include "../../../../lib/cstring.h"
#include "../../../../uidescription/detail/uiviewcreatorattributes.h"
#include "../../../../uidescription/uiattributes.h"
#include "../../../../uidescription/uiviewfactory.h"
#include "../../unittests.h"
#include "helpers.h"
namespace VSTGUI {
using namespace UIViewCreator;
TEST_CASE (CMultiLineTextLabelCreatorTest, AutoHeight)
{
UIDescriptionAdapter uidesc;
testAttribute<CMultiLineTextLabel> (
kCMultiLineTextLabel, kAttrAutoHeight, true, &uidesc,
[] (CMultiLineTextLabel* v) { return v->getAutoHeight () == true; });
}
TEST_CASE (CMultiLineTextLabelCreatorTest, LineLayout)
{
UIDescriptionAdapter uidesc;
testAttribute<CMultiLineTextLabel> (
kCMultiLineTextLabel, kAttrLineLayout, "truncate", &uidesc, [] (CMultiLineTextLabel* v) {
return v->getLineLayout () == CMultiLineTextLabel::LineLayout::truncate;
});
testAttribute<CMultiLineTextLabel> (
kCMultiLineTextLabel, kAttrLineLayout, "wrap", &uidesc, [] (CMultiLineTextLabel* v) {
return v->getLineLayout () == CMultiLineTextLabel::LineLayout::wrap;
});
testAttribute<CMultiLineTextLabel> (
kCMultiLineTextLabel, kAttrLineLayout, "clip", &uidesc, [] (CMultiLineTextLabel* v) {
return v->getLineLayout () == CMultiLineTextLabel::LineLayout::clip;
});
}
TEST_CASE (CMultiLineTextLabelCreatorTest, LineLayoutPossibleValues)
{
UIDescriptionAdapter uidesc;
testPossibleValues (kCMultiLineTextLabel, kAttrLineLayout, &uidesc,
{"clip", "truncate", "wrap"});
}
} // VSTGUI
@@ -0,0 +1,28 @@
// This file is part of VSTGUI. It is subject to the license terms
// in the LICENSE file found in the top-level directory of this
// distribution and at http://github.com/steinbergmedia/vstgui/LICENSE
#include "../../../../lib/controls/cbuttons.h"
#include "../../../../lib/cstring.h"
#include "../../../../uidescription/detail/uiviewcreatorattributes.h"
#include "../../../../uidescription/uiattributes.h"
#include "../../../../uidescription/uiviewfactory.h"
#include "../../unittests.h"
namespace VSTGUI {
using namespace UIViewCreator;
TEST_CASE (COnOffButtonCreatorTest, Create)
{
UIViewFactory factory;
UIAttributes a;
a.setAttribute (kAttrClass, kCOnOffButton);
auto view = owned (factory.createView (a, nullptr));
auto control = view.cast<COnOffButton> ();
EXPECT (control);
UIAttributes a2;
EXPECT (factory.getAttributesForView (view, nullptr, a2));
}
} // VSTGUI
@@ -0,0 +1,32 @@
// This file is part of VSTGUI. It is subject to the license terms
// in the LICENSE file found in the top-level directory of this
// distribution and at http://github.com/steinbergmedia/vstgui/LICENSE
#include "../../../../lib/controls/coptionmenu.h"
#include "../../../../lib/cstring.h"
#include "../../../../uidescription/detail/uiviewcreatorattributes.h"
#include "../../../../uidescription/uiattributes.h"
#include "../../../../uidescription/uiviewfactory.h"
#include "../../unittests.h"
#include "helpers.h"
namespace VSTGUI {
using namespace UIViewCreator;
TEST_CASE (COptionMenuCreatorTest, PopupStyle)
{
UIDescriptionAdapter uidesc;
testAttribute<COptionMenu> (
kCOptionMenu, kAttrMenuPopupStyle, true, &uidesc,
[] (COptionMenu* v) { return v->getStyle () & COptionMenu::kPopupStyle; });
}
TEST_CASE (COptionMenuCreatorTest, checkStyle)
{
UIDescriptionAdapter uidesc;
testAttribute<COptionMenu> (
kCOptionMenu, kAttrMenuCheckStyle, true, &uidesc,
[] (COptionMenu* v) { return v->getStyle () & COptionMenu::kCheckStyle; });
}
} // VSTGUI
@@ -0,0 +1,165 @@
// This file is part of VSTGUI. It is subject to the license terms
// in the LICENSE file found in the top-level directory of this
// distribution and at http://github.com/steinbergmedia/vstgui/LICENSE
#include "../../../../lib/controls/cparamdisplay.h"
#include "../../../../lib/cstring.h"
#include "../../../../uidescription/detail/uiviewcreatorattributes.h"
#include "../../../../uidescription/uiattributes.h"
#include "../../../../uidescription/uiviewfactory.h"
#include "../../unittests.h"
#include "helpers.h"
namespace VSTGUI {
using namespace UIViewCreator;
TEST_CASE (CParamDisplayCreatorTest, Font)
{
DummyUIDescription uiDesc;
testAttribute<CParamDisplay> (kCParamDisplay, kAttrFont, kFontName, &uiDesc,
[&] (CParamDisplay* v) { return v->getFont () == uiDesc.font; },
true);
}
TEST_CASE (CParamDisplayCreatorTest, FontColor)
{
DummyUIDescription uiDesc;
testAttribute<CParamDisplay> (
kCParamDisplay, kAttrFontColor, kColorName, &uiDesc,
[&] (CParamDisplay* v) { return v->getFontColor () == uiDesc.color; });
}
TEST_CASE (CParamDisplayCreatorTest, BackColor)
{
DummyUIDescription uiDesc;
testAttribute<CParamDisplay> (
kCParamDisplay, kAttrBackColor, kColorName, &uiDesc,
[&] (CParamDisplay* v) { return v->getBackColor () == uiDesc.color; });
}
TEST_CASE (CParamDisplayCreatorTest, FrameColor)
{
DummyUIDescription uiDesc;
testAttribute<CParamDisplay> (
kCParamDisplay, kAttrFrameColor, kColorName, &uiDesc,
[&] (CParamDisplay* v) { return v->getFrameColor () == uiDesc.color; });
}
TEST_CASE (CParamDisplayCreatorTest, ShadowColor)
{
DummyUIDescription uiDesc;
testAttribute<CParamDisplay> (
kCParamDisplay, kAttrShadowColor, kColorName, &uiDesc,
[&] (CParamDisplay* v) { return v->getShadowColor () == uiDesc.color; });
}
TEST_CASE (CParamDisplayCreatorTest, TextInset)
{
DummyUIDescription uiDesc;
CPoint inset (5, 6);
testAttribute<CParamDisplay> (kCParamDisplay, kAttrTextInset, inset, &uiDesc,
[&] (CParamDisplay* v) { return v->getTextInset () == inset; });
}
TEST_CASE (CParamDisplayCreatorTest, FontAntialias)
{
DummyUIDescription uiDesc;
testAttribute<CParamDisplay> (kCParamDisplay, kAttrFontAntialias, true, &uiDesc,
[&] (CParamDisplay* v) { return v->getAntialias (); });
testAttribute<CParamDisplay> (kCParamDisplay, kAttrFontAntialias, false, &uiDesc,
[&] (CParamDisplay* v) { return v->getAntialias () == false; });
}
TEST_CASE (CParamDisplayCreatorTest, TextAlignment)
{
DummyUIDescription uiDesc;
testAttribute<CParamDisplay> (
kCParamDisplay, kAttrTextAlignment, "left", &uiDesc,
[&] (CParamDisplay* v) { return v->getHoriAlign () == kLeftText; });
testAttribute<CParamDisplay> (
kCParamDisplay, kAttrTextAlignment, "center", &uiDesc,
[&] (CParamDisplay* v) { return v->getHoriAlign () == kCenterText; });
testAttribute<CParamDisplay> (
kCParamDisplay, kAttrTextAlignment, "right", &uiDesc,
[&] (CParamDisplay* v) { return v->getHoriAlign () == kRightText; });
}
TEST_CASE (CParamDisplayCreatorTest, RoundRectRadius)
{
DummyUIDescription uiDesc;
testAttribute<CParamDisplay> (
kCParamDisplay, kAttrRoundRectRadius, 15., &uiDesc,
[&] (CParamDisplay* v) { return v->getRoundRectRadius () == 15.; });
}
TEST_CASE (CParamDisplayCreatorTest, FrameWidth)
{
DummyUIDescription uiDesc;
testAttribute<CParamDisplay> (kCParamDisplay, kAttrFrameWidth, 12., &uiDesc,
[&] (CParamDisplay* v) { return v->getFrameWidth () == 12.; });
}
TEST_CASE (CParamDisplayCreatorTest, TextRotation)
{
DummyUIDescription uiDesc;
testAttribute<CParamDisplay> (kCParamDisplay, kAttrTextRotation, 89., &uiDesc,
[&] (CParamDisplay* v) { return v->getTextRotation () == 89.; });
}
TEST_CASE (CParamDisplayCreatorTest, Styles)
{
DummyUIDescription uiDesc;
testAttribute<CParamDisplay> (
kCParamDisplay, kAttrStyle3DIn, true, &uiDesc,
[&] (CParamDisplay* v) { return v->getStyle () & CParamDisplay::k3DIn; });
testAttribute<CParamDisplay> (
kCParamDisplay, kAttrStyle3DOut, true, &uiDesc,
[&] (CParamDisplay* v) { return v->getStyle () & CParamDisplay::k3DOut; });
testAttribute<CParamDisplay> (
kCParamDisplay, kAttrStyleNoFrame, true, &uiDesc,
[&] (CParamDisplay* v) { return v->getStyle () & CParamDisplay::kNoFrame; });
testAttribute<CParamDisplay> (
kCParamDisplay, kAttrStyleNoDraw, true, &uiDesc,
[&] (CParamDisplay* v) { return v->getStyle () & CParamDisplay::kNoDrawStyle; });
testAttribute<CParamDisplay> (
kCParamDisplay, kAttrStyleNoText, true, &uiDesc,
[&] (CParamDisplay* v) { return v->getStyle () & CParamDisplay::kNoTextStyle; });
testAttribute<CParamDisplay> (
kCParamDisplay, kAttrStyleShadowText, true, &uiDesc,
[&] (CParamDisplay* v) { return v->getStyle () & CParamDisplay::kShadowText; });
testAttribute<CParamDisplay> (
kCParamDisplay, kAttrStyleRoundRect, true, &uiDesc,
[&] (CParamDisplay* v) { return v->getStyle () & CParamDisplay::kRoundRectStyle; });
}
TEST_CASE (CParamDisplayCreatorTest, ValuePrecision)
{
DummyUIDescription uiDesc;
testAttribute<CParamDisplay> (kCParamDisplay, kAttrValuePrecision, 3, &uiDesc,
[&] (CParamDisplay* v) { return v->getPrecision () == 3; });
}
TEST_CASE (CParamDisplayCreatorTest, TextRotationMinMax)
{
DummyUIDescription uidesc;
testMinMaxValues (kCParamDisplay, kAttrTextRotation, &uidesc, 0., 360.);
}
TEST_CASE (CParamDisplayCreatorTest, BackgroundOffset)
{
DummyUIDescription uiDesc;
CPoint offset (20, 20);
testAttribute<CParamDisplay> (kCParamDisplay, kAttrBackgroundOffset, offset, &uiDesc,
[&] (CParamDisplay* v) { return v->getBackOffset () == offset; });
}
TEST_CASE (CParamDisplayCreatorTest, ShadowOffset)
{
DummyUIDescription uiDesc;
CPoint offset (15, 9);
testAttribute<CParamDisplay> (
kCParamDisplay, kAttrTextShadowOffset, offset, &uiDesc,
[&] (CParamDisplay* v) { return v->getShadowTextOffset () == offset; });
}
} // VSTGUI
@@ -0,0 +1,35 @@
// This file is part of VSTGUI. It is subject to the license terms
// in the LICENSE file found in the top-level directory of this
// distribution and at http://github.com/steinbergmedia/vstgui/LICENSE
#include "../../../../lib/controls/cswitch.h"
#include "../../../../lib/cstring.h"
#include "../../../../uidescription/detail/uiviewcreatorattributes.h"
#include "../../../../uidescription/uiattributes.h"
#include "../../../../uidescription/uiviewfactory.h"
#include "../../unittests.h"
#include "helpers.h"
namespace VSTGUI {
using namespace UIViewCreator;
#if VSTGUI_ENABLE_DEPRECATED_METHODS
TEST_CASE (CRockerSwitchCreatorTest, HeightOfOneImage)
{
DummyUIDescription uidesc;
testAttribute<CRockerSwitch> (
kCRockerSwitch, kAttrHeightOfOneImage, 10, &uidesc,
[] (CRockerSwitch* v) { return v->getHeightOfOneImage () == 10; });
}
TEST_CASE (CRockerSwitchCreatorTest, SubPixmaps)
{
DummyUIDescription uidesc;
testAttribute<CRockerSwitch> (kCRockerSwitch, kAttrSubPixmaps, 11, &uidesc,
[] (CRockerSwitch* v) { return v->getNumSubPixmaps () == 11; });
}
#endif
} // VSTGUI
@@ -0,0 +1,99 @@
// This file is part of VSTGUI. It is subject to the license terms
// in the LICENSE file found in the top-level directory of this
// distribution and at http://github.com/steinbergmedia/vstgui/LICENSE
#include "../../../../lib/crowcolumnview.h"
#include "../../../../lib/cstring.h"
#include "../../../../uidescription/detail/uiviewcreatorattributes.h"
#include "../../../../uidescription/uiattributes.h"
#include "../../../../uidescription/uiviewfactory.h"
#include "../../unittests.h"
#include "helpers.h"
namespace VSTGUI {
using namespace UIViewCreator;
TEST_CASE (CRowColumnViewCreatorTest, RowStyle)
{
testAttribute<CRowColumnView> (
kCRowColumnView, kAttrRowStyle, true, nullptr,
[] (CRowColumnView* v) { return v->getStyle () == CRowColumnView::kRowStyle; });
}
TEST_CASE (CRowColumnViewCreatorTest, ColumnStyle)
{
testAttribute<CRowColumnView> (
kCRowColumnView, kAttrRowStyle, false, nullptr,
[] (CRowColumnView* v) { return v->getStyle () == CRowColumnView::kColumnStyle; });
}
TEST_CASE (CRowColumnViewCreatorTest, Spacing)
{
testAttribute<CRowColumnView> (kCRowColumnView, kAttrSpacing, 5., nullptr,
[] (CRowColumnView* v) { return v->getSpacing () == 5.; });
}
TEST_CASE (CRowColumnViewCreatorTest, Margin)
{
CRect margin (5, 6, 7, 8);
testAttribute<CRowColumnView> (kCRowColumnView, kAttrMargin, margin, nullptr,
[&] (CRowColumnView* v) { return v->getMargin () == margin; });
}
TEST_CASE (CRowColumnViewCreatorTest, AnimateViewResizing)
{
testAttribute<CRowColumnView> (kCRowColumnView, kAttrAnimateViewResizing, true, nullptr,
[] (CRowColumnView* v) { return v->isAnimateViewResizing (); });
}
TEST_CASE (CRowColumnViewCreatorTest, EqualSizeLayoutStretch)
{
testAttribute<CRowColumnView> (
kCRowColumnView, kAttrEqualSizeLayout, "stretch", nullptr,
[] (CRowColumnView* v) { return v->getLayoutStyle () == CRowColumnView::kStretchEqualy; });
}
TEST_CASE (CRowColumnViewCreatorTest, EqualSizeLayoutCenter)
{
testAttribute<CRowColumnView> (
kCRowColumnView, kAttrEqualSizeLayout, "center", nullptr,
[] (CRowColumnView* v) { return v->getLayoutStyle () == CRowColumnView::kCenterEqualy; });
}
TEST_CASE (CRowColumnViewCreatorTest, EqualSizeLayoutRightBottom)
{
testAttribute<CRowColumnView> (
kCRowColumnView, kAttrEqualSizeLayout, "right-bottom", nullptr, [] (CRowColumnView* v) {
return v->getLayoutStyle () == CRowColumnView::kRightBottomEqualy;
});
}
TEST_CASE (CRowColumnViewCreatorTest, EqualSizeLayoutLeftTop)
{
testAttribute<CRowColumnView> (
kCRowColumnView, kAttrEqualSizeLayout, "left-top", nullptr,
[] (CRowColumnView* v) { return v->getLayoutStyle () == CRowColumnView::kLeftTopEqualy; });
}
TEST_CASE (CRowColumnViewCreatorTest, AnimationTime)
{
testAttribute<CRowColumnView> (
kCRowColumnView, kAttrViewResizeAnimationTime, 100, nullptr,
[] (CRowColumnView* v) { return v->getViewResizeAnimationTime () == 100; });
}
TEST_CASE (CRowColumnViewCreatorTest, EqualSizeLayoutValues)
{
testPossibleValues (kCRowColumnView, kAttrEqualSizeLayout, nullptr,
{"left-top", "stretch", "center", "right-bottom", "top-left", "top-center",
"top-right", "middle-left", "middle-center", "middle-right", "bottom-left",
"bottom-center", "bottom-right"});
}
TEST_CASE (CRowColumnViewCreatorTest, HideClippedSubviews)
{
testAttribute<CRowColumnView> (kCRowColumnView, kAttrHideClippedSubviews, true, nullptr,
[] (CRowColumnView* v) { return v->hideClippedSubviews (); });
}
} // VSTGUI
@@ -0,0 +1,120 @@
// This file is part of VSTGUI. It is subject to the license terms
// in the LICENSE file found in the top-level directory of this
// distribution and at http://github.com/steinbergmedia/vstgui/LICENSE
#include "../../../../lib/controls/cscrollbar.h"
#include "../../../../lib/cscrollview.h"
#include "../../../../lib/cstring.h"
#include "../../../../uidescription/detail/uiviewcreatorattributes.h"
#include "../../../../uidescription/uiattributes.h"
#include "../../../../uidescription/uiviewfactory.h"
#include "../../unittests.h"
#include "helpers.h"
namespace VSTGUI {
using namespace UIViewCreator;
TEST_CASE (CScrollViewContainerCreatorTest, ContainerSize)
{
CPoint size (100, 100);
testAttribute<CScrollView> (
kCScrollView, kAttrContainerSize, size, nullptr,
[&] (CScrollView* v) { return v->getContainerSize ().getSize () == size; });
}
TEST_CASE (CScrollViewContainerCreatorTest, HorizontalScrollbar)
{
testAttribute<CScrollView> (
kCScrollView, kAttrHorizontalScrollbar, true, nullptr,
[&] (CScrollView* v) { return v->getStyle () & CScrollView::kHorizontalScrollbar; });
}
TEST_CASE (CScrollViewContainerCreatorTest, VerticalScrollbar)
{
testAttribute<CScrollView> (
kCScrollView, kAttrVerticalScrollbar, true, nullptr,
[&] (CScrollView* v) { return v->getStyle () & CScrollView::kVerticalScrollbar; });
}
TEST_CASE (CScrollViewContainerCreatorTest, AutoDragScrolling)
{
testAttribute<CScrollView> (
kCScrollView, kAttrAutoDragScrolling, true, nullptr,
[&] (CScrollView* v) { return v->getStyle () & CScrollView::kAutoDragScrolling; });
}
TEST_CASE (CScrollViewContainerCreatorTest, DontDrawFrame)
{
DummyUIDescription uiDesc;
testAttribute<CScrollView> (kCScrollView, kAttrBordered, true, &uiDesc, [&] (CScrollView* v) {
return v->getStyle () & ~CScrollView::kDontDrawFrame;
});
testAttribute<CScrollView> (kCScrollView, kAttrBordered, false, &uiDesc, [&] (CScrollView* v) {
return v->getStyle () & CScrollView::kDontDrawFrame;
});
}
TEST_CASE (CScrollViewContainerCreatorTest, OverlayScrollbars)
{
testAttribute<CScrollView> (
kCScrollView, kAttrOverlayScrollbars, true, nullptr,
[&] (CScrollView* v) { return v->getStyle () & CScrollView::kOverlayScrollbars; });
}
TEST_CASE (CScrollViewContainerCreatorTest, FollowFocusView)
{
testAttribute<CScrollView> (
kCScrollView, kAttrFollowFocusView, true, nullptr,
[&] (CScrollView* v) { return v->getStyle () & CScrollView::kFollowFocusView; });
}
TEST_CASE (CScrollViewContainerCreatorTest, AutoHideScrollbars)
{
testAttribute<CScrollView> (
kCScrollView, kAttrAutoHideScrollbars, true, nullptr,
[&] (CScrollView* v) { return v->getStyle () & CScrollView::kAutoHideScrollbars; });
}
TEST_CASE (CScrollViewContainerCreatorTest, ScrollbarWidth)
{
testAttribute<CScrollView> (kCScrollView, kAttrScrollbarWidth, 5., nullptr,
[&] (CScrollView* v) { return v->getScrollbarWidth () == 5.; });
}
TEST_CASE (CScrollViewContainerCreatorTest, ScrollbarBackgroundColor)
{
DummyUIDescription uiDesc;
testAttribute<CScrollView> (kCScrollView, kAttrScrollbarBackgroundColor, kColorName, &uiDesc,
[&] (CScrollView* v) {
auto sb = v->getVerticalScrollbar ();
if (!sb)
sb = v->getHorizontalScrollbar ();
return sb->getBackgroundColor () == uiDesc.color;
});
}
TEST_CASE (CScrollViewContainerCreatorTest, ScrollbarFrameColor)
{
DummyUIDescription uiDesc;
testAttribute<CScrollView> (kCScrollView, kAttrScrollbarFrameColor, kColorName, &uiDesc,
[&] (CScrollView* v) {
auto sb = v->getVerticalScrollbar ();
if (!sb)
sb = v->getHorizontalScrollbar ();
return sb->getFrameColor () == uiDesc.color;
});
}
TEST_CASE (CScrollViewContainerCreatorTest, ScrollbarScrollerColor)
{
DummyUIDescription uiDesc;
testAttribute<CScrollView> (kCScrollView, kAttrScrollbarScrollerColor, kColorName, &uiDesc,
[&] (CScrollView* v) {
auto sb = v->getVerticalScrollbar ();
if (!sb)
sb = v->getHorizontalScrollbar ();
return sb->getScrollerColor () == uiDesc.color;
});
}
} // VSTGUI
@@ -0,0 +1,25 @@
// This file is part of VSTGUI. It is subject to the license terms
// in the LICENSE file found in the top-level directory of this
// distribution and at http://github.com/steinbergmedia/vstgui/LICENSE
#include "../../../../lib/controls/csearchtextedit.h"
#include "../../../../lib/cstring.h"
#include "../../../../uidescription/detail/uiviewcreatorattributes.h"
#include "../../../../uidescription/uiattributes.h"
#include "../../../../uidescription/uiviewfactory.h"
#include "../../unittests.h"
#include "helpers.h"
namespace VSTGUI {
using namespace UIViewCreator;
TEST_CASE (CSearchTextEditCreatorTest, ClearMarkInset)
{
UIDescriptionAdapter uidesc;
CPoint p (10, 11);
testAttribute<CSearchTextEdit> (
kCSearchTextEdit, kAttrClearMarkInset, p, &uidesc,
[&] (CSearchTextEdit* v) { return v->getClearMarkInset () == p; });
}
} // VSTGUI
@@ -0,0 +1,179 @@
// This file is part of VSTGUI. It is subject to the license terms
// in the LICENSE file found in the top-level directory of this
// distribution and at http://github.com/steinbergmedia/vstgui/LICENSE
#include "../../../../lib/controls/csegmentbutton.h"
#include "../../../../lib/cstring.h"
#include "../../../../uidescription/detail/uiviewcreatorattributes.h"
#include "../../../../uidescription/uiattributes.h"
#include "../../../../uidescription/uiviewfactory.h"
#include "../../unittests.h"
#include "helpers.h"
namespace VSTGUI {
using namespace UIViewCreator;
TEST_CASE (CSegmentButtonCreatorTest, Font)
{
DummyUIDescription uidesc;
testAttribute<CSegmentButton> (kCSegmentButton, kAttrFont, kFontName, &uidesc,
[&] (CSegmentButton* v) { return v->getFont () == uidesc.font; },
true);
}
TEST_CASE (CSegmentButtonCreatorTest, Style)
{
DummyUIDescription uidesc;
testAttribute<CSegmentButton> (
kCSegmentButton, kAttrStyle, "horizontal", &uidesc,
[&] (CSegmentButton* v) { return v->getStyle () == CSegmentButton::Style::kHorizontal; });
testAttribute<CSegmentButton> (
kCSegmentButton, kAttrStyle, "vertical", &uidesc,
[&] (CSegmentButton* v) { return v->getStyle () == CSegmentButton::Style::kVertical; });
testAttribute<CSegmentButton> (
kCSegmentButton, kAttrStyle, "horizontal-inverse", &uidesc, [&] (CSegmentButton* v) {
return v->getStyle () == CSegmentButton::Style::kHorizontalInverse;
});
testAttribute<CSegmentButton> (
kCSegmentButton, kAttrStyle, "vertical-inverse", &uidesc, [&] (CSegmentButton* v) {
return v->getStyle () == CSegmentButton::Style::kVerticalInverse;
});
}
TEST_CASE (CSegmentButtonCreatorTest, SelectionMode)
{
DummyUIDescription uidesc;
testAttribute<CSegmentButton> (
kCSegmentButton, kAttrSelectionMode, "Single", &uidesc, [&] (CSegmentButton* v) {
return v->getSelectionMode () == CSegmentButton::SelectionMode::kSingle;
});
testAttribute<CSegmentButton> (
kCSegmentButton, kAttrSelectionMode, "Single-Toggle", &uidesc, [&] (CSegmentButton* v) {
return v->getSelectionMode () == CSegmentButton::SelectionMode::kSingleToggle;
});
testAttribute<CSegmentButton> (
kCSegmentButton, kAttrSelectionMode, "Multiple", &uidesc, [&] (CSegmentButton* v) {
return v->getSelectionMode () == CSegmentButton::SelectionMode::kMultiple;
});
testPossibleValues (kCSegmentButton, kAttrSelectionMode, &uidesc,
{"Single", "Single-Toggle", "Multiple"});
}
TEST_CASE (CSegmentButtonCreatorTest, TextColor)
{
DummyUIDescription uidesc;
testAttribute<CSegmentButton> (
kCSegmentButton, kAttrTextColor, kColorName, &uidesc,
[&] (CSegmentButton* v) { return v->getTextColor () == uidesc.color; });
}
TEST_CASE (CSegmentButtonCreatorTest, TextColorHighlighted)
{
DummyUIDescription uidesc;
testAttribute<CSegmentButton> (
kCSegmentButton, kAttrTextColorHighlighted, kColorName, &uidesc,
[&] (CSegmentButton* v) { return v->getTextColorHighlighted () == uidesc.color; });
}
TEST_CASE (CSegmentButtonCreatorTest, FrameColor)
{
DummyUIDescription uidesc;
testAttribute<CSegmentButton> (
kCSegmentButton, kAttrFrameColor, kColorName, &uidesc,
[&] (CSegmentButton* v) { return v->getFrameColor () == uidesc.color; });
}
TEST_CASE (CSegmentButtonCreatorTest, FrameWidth)
{
DummyUIDescription uidesc;
testAttribute<CSegmentButton> (kCSegmentButton, kAttrFrameWidth, 5., &uidesc,
[&] (CSegmentButton* v) { return v->getFrameWidth () == 5.; });
}
TEST_CASE (CSegmentButtonCreatorTest, RoundRadius)
{
DummyUIDescription uidesc;
testAttribute<CSegmentButton> (kCSegmentButton, kAttrRoundRadius, 15., &uidesc,
[&] (CSegmentButton* v) { return v->getRoundRadius () == 15.; });
}
TEST_CASE (CSegmentButtonCreatorTest, TextIconMargin)
{
DummyUIDescription uidesc;
testAttribute<CSegmentButton> (kCSegmentButton, kAttrIconTextMargin, 15., &uidesc,
[&] (CSegmentButton* v) { return v->getTextMargin () == 15; });
}
TEST_CASE (CSegmentButtonCreatorTest, TextAlignment)
{
DummyUIDescription uiDesc;
testAttribute<CSegmentButton> (
kCSegmentButton, kAttrTextAlignment, "left", &uiDesc,
[&] (CSegmentButton* v) { return v->getTextAlignment () == kLeftText; });
testAttribute<CSegmentButton> (
kCSegmentButton, kAttrTextAlignment, "center", &uiDesc,
[&] (CSegmentButton* v) { return v->getTextAlignment () == kCenterText; });
testAttribute<CSegmentButton> (
kCSegmentButton, kAttrTextAlignment, "right", &uiDesc,
[&] (CSegmentButton* v) { return v->getTextAlignment () == kRightText; });
}
TEST_CASE (CSegmentButtonCreatorTest, Gradient)
{
DummyUIDescription uidesc;
testAttribute<CSegmentButton> (
kCSegmentButton, kAttrGradient, kGradientName, &uidesc,
[&] (CSegmentButton* v) { return v->getGradient () == uidesc.gradient; }, true);
}
TEST_CASE (CSegmentButtonCreatorTest, GradientHighlighted)
{
DummyUIDescription uidesc;
testAttribute<CSegmentButton> (
kCSegmentButton, kAttrGradientHighlighted, kGradientName, &uidesc,
[&] (CSegmentButton* v) { return v->getGradientHighlighted () == uidesc.gradient; }, true);
}
TEST_CASE (CSegmentButtonCreatorTest, SegmentNames)
{
DummyUIDescription uidesc;
testAttribute<CSegmentButton> (kCSegmentButton, kAttrSegmentNames, "s1,s2,s3", &uidesc,
[&] (CSegmentButton* v) {
EXPECT (v->getSegments ()[0].name == "s1");
EXPECT (v->getSegments ()[1].name == "s2");
EXPECT (v->getSegments ()[2].name == "s3");
return v->getSegments ().size () == 3;
});
}
TEST_CASE (CSegmentButtonCreatorTest, TruncateMode)
{
DummyUIDescription uidesc;
testAttribute<CSegmentButton> (
kCSegmentButton, kAttrTruncateMode, "head", &uidesc, [] (CSegmentButton* v) {
return v->getTextTruncateMode () == CDrawMethods::kTextTruncateHead;
});
testAttribute<CSegmentButton> (
kCSegmentButton, kAttrTruncateMode, "tail", &uidesc, [] (CSegmentButton* v) {
return v->getTextTruncateMode () == CDrawMethods::kTextTruncateTail;
});
testAttribute<CSegmentButton> (
kCSegmentButton, kAttrTruncateMode, "", &uidesc, [] (CSegmentButton* v) {
return v->getTextTruncateMode () == CDrawMethods::kTextTruncateNone;
});
}
TEST_CASE (CSegmentButtonCreatorTest, TruncateModeValues)
{
DummyUIDescription uidesc;
testPossibleValues (kCSegmentButton, kAttrTruncateMode, &uidesc, {"head", "tail", "none"});
}
TEST_CASE (CSegmentButtonCreatorTest, OrientationValues)
{
DummyUIDescription uidesc;
testPossibleValues (kCSegmentButton, kAttrStyle, &uidesc,
{"horizontal", "vertical", "horizontal-inverse", "vertical-inverse"});
}
} // VSTGUI
@@ -0,0 +1,53 @@
// This file is part of VSTGUI. It is subject to the license terms
// in the LICENSE file found in the top-level directory of this
// distribution and at http://github.com/steinbergmedia/vstgui/LICENSE
#include "../../../../lib/cshadowviewcontainer.h"
#include "../../../../lib/cstring.h"
#include "../../../../uidescription/detail/uiviewcreatorattributes.h"
#include "../../../../uidescription/uiattributes.h"
#include "../../../../uidescription/uiviewfactory.h"
#include "../../unittests.h"
#include "helpers.h"
namespace VSTGUI {
using namespace UIViewCreator;
TEST_CASE (CShadowViewContainerCreatorTest, ShadowIntensity)
{
DummyUIDescription uidesc;
testAttribute<CShadowViewContainer> (
kCShadowViewContainer, kAttrShadowIntensity, 0.5, &uidesc,
[] (CShadowViewContainer* v) { return v->getShadowIntensity () == 0.5f; });
}
TEST_CASE (CShadowViewContainerCreatorTest, ShadowBlurSize)
{
DummyUIDescription uidesc;
testAttribute<CShadowViewContainer> (
kCShadowViewContainer, kAttrShadowBlurSize, 0.5, &uidesc,
[] (CShadowViewContainer* v) { return v->getShadowBlurSize () == 0.5f; });
}
TEST_CASE (CShadowViewContainerCreatorTest, ShadowOffset)
{
DummyUIDescription uidesc;
CPoint p (20, 20);
testAttribute<CShadowViewContainer> (
kCShadowViewContainer, kAttrShadowOffset, p, &uidesc,
[&] (CShadowViewContainer* v) { return v->getShadowOffset () == p; });
}
TEST_CASE (CShadowViewContainerCreatorTest, ShadowBlurSizeMinMax)
{
DummyUIDescription uidesc;
testMinMaxValues (kCShadowViewContainer, kAttrShadowBlurSize, &uidesc, 0.8, 20);
}
TEST_CASE (CShadowViewContainerCreatorTest, ShadowIntensityMinMax)
{
DummyUIDescription uidesc;
testMinMaxValues (kCShadowViewContainer, kAttrShadowIntensity, &uidesc, 0., 1.);
}
} // VSTGUI
@@ -0,0 +1,183 @@
// This file is part of VSTGUI. It is subject to the license terms
// in the LICENSE file found in the top-level directory of this
// distribution and at http://github.com/steinbergmedia/vstgui/LICENSE
#include "../../../../lib/controls/cslider.h"
#include "../../../../lib/cstring.h"
#include "../../../../uidescription/detail/uiviewcreatorattributes.h"
#include "../../../../uidescription/uiattributes.h"
#include "../../../../uidescription/uiviewfactory.h"
#include "../../unittests.h"
#include "helpers.h"
namespace VSTGUI {
using namespace UIViewCreator;
TEST_CASE (CSliderCreatorTest, Mode)
{
DummyUIDescription uidesc;
testAttribute<CSlider> (kCSlider, kAttrMode, "touch", &uidesc,
[&] (CSlider* v) { return v->getSliderMode () == CSliderMode::Touch; });
testAttribute<CSlider> (kCSlider, kAttrMode, "relative touch", &uidesc, [&] (CSlider* v) {
return v->getSliderMode () == CSliderMode::RelativeTouch;
});
testAttribute<CSlider> (kCSlider, kAttrMode, "free click", &uidesc, [&] (CSlider* v) {
return v->getSliderMode () == CSliderMode::FreeClick;
});
testAttribute<CSlider> (kCSlider, kAttrMode, "ramp", &uidesc,
[&] (CSlider* v) { return v->getSliderMode () == CSliderMode::Ramp; });
testAttribute<CSlider> (kCSlider, kAttrMode, "use global", &uidesc, [&] (CSlider* v) {
return v->getSliderMode () == CSliderMode::UseGlobal;
});
}
TEST_CASE (CSliderCreatorTest, HandleBitmap)
{
DummyUIDescription uidesc;
testAttribute<CSlider> (kCSlider, kAttrHandleBitmap, kBitmapName, &uidesc,
[&] (CSlider* v) { return v->getHandle () == uidesc.bitmap; });
}
TEST_CASE (CSliderCreatorTest, HandleOffset)
{
DummyUIDescription uidesc;
CPoint p (20, 20);
testAttribute<CSlider> (kCSlider, kAttrHandleOffset, p, &uidesc,
[&] (CSlider* v) { return v->getOffsetHandle () == p; });
}
TEST_CASE (CSliderCreatorTest, BitmapOffset)
{
DummyUIDescription uidesc;
CPoint p (20, 20);
testAttribute<CSlider> (kCSlider, kAttrBitmapOffset, p, &uidesc,
[&] (CSlider* v) { return v->getBackgroundOffset () == p; });
}
TEST_CASE (CSliderCreatorTest, ZoomFactor)
{
DummyUIDescription uidesc;
testAttribute<CSlider> (kCSlider, kAttrZoomFactor, 15., &uidesc,
[&] (CSlider* v) { return v->getZoomFactor () == 15.; });
}
TEST_CASE (CSliderCreatorTest, Orientation)
{
DummyUIDescription uidesc;
testAttribute<CSlider> (kCSlider, kAttrOrientation, "horizontal", &uidesc,
[&] (CSlider* v) { return v->getStyle () & CSlider::kHorizontal; });
testAttribute<CSlider> (kCSlider, kAttrOrientation, "vertical", &uidesc,
[&] (CSlider* v) { return v->getStyle () & CSlider::kVertical; });
}
TEST_CASE (CSliderCreatorTest, ReverseOrientation)
{
DummyUIDescription uidesc;
testAttribute<CSlider> (kCSlider, kAttrReverseOrientation, true, &uidesc, [&] (CSlider* v) {
auto style = v->getStyle ();
if (style & CSlider::kHorizontal)
return style & CSlider::kRight;
return style & CSlider::kTop;
});
testAttribute<CSlider> (kCSlider, kAttrReverseOrientation, false, &uidesc, [&] (CSlider* v) {
auto style = v->getStyle ();
if (style & CSlider::kHorizontal)
return style & CSlider::kLeft;
return style & CSlider::kBottom;
});
}
TEST_CASE (CSliderCreatorTest, DrawFrame)
{
DummyUIDescription uidesc;
testAttribute<CSlider> (kCSlider, kAttrDrawFrame, true, &uidesc,
[&] (CSlider* v) { return v->getDrawStyle () & CSlider::kDrawFrame; });
testAttribute<CSlider> (kCSlider, kAttrDrawFrame, false, &uidesc, [&] (CSlider* v) {
return !(v->getDrawStyle () & CSlider::kDrawFrame);
});
}
TEST_CASE (CSliderCreatorTest, DrawBack)
{
DummyUIDescription uidesc;
testAttribute<CSlider> (kCSlider, kAttrDrawBack, true, &uidesc,
[&] (CSlider* v) { return v->getDrawStyle () & CSlider::kDrawBack; });
testAttribute<CSlider> (kCSlider, kAttrDrawBack, false, &uidesc, [&] (CSlider* v) {
return !(v->getDrawStyle () & CSlider::kDrawBack);
});
}
TEST_CASE (CSliderCreatorTest, DrawValue)
{
DummyUIDescription uidesc;
testAttribute<CSlider> (kCSlider, kAttrDrawValue, true, &uidesc,
[&] (CSlider* v) { return v->getDrawStyle () & CSlider::kDrawValue; });
testAttribute<CSlider> (kCSlider, kAttrDrawValue, false, &uidesc, [&] (CSlider* v) {
return !(v->getDrawStyle () & CSlider::kDrawValue);
});
}
TEST_CASE (CSliderCreatorTest, DrawValueFromCenter)
{
DummyUIDescription uidesc;
testAttribute<CSlider> (kCSlider, kAttrDrawValueFromCenter, true, &uidesc, [&] (CSlider* v) {
return v->getDrawStyle () & CSlider::kDrawValueFromCenter;
});
testAttribute<CSlider> (kCSlider, kAttrDrawValueFromCenter, false, &uidesc, [&] (CSlider* v) {
return !(v->getDrawStyle () & CSlider::kDrawValueFromCenter);
});
}
TEST_CASE (CSliderCreatorTest, DrawValueInverted)
{
DummyUIDescription uidesc;
testAttribute<CSlider> (kCSlider, kAttrDrawValueInverted, true, &uidesc, [&] (CSlider* v) {
return v->getDrawStyle () & CSlider::kDrawInverted;
});
testAttribute<CSlider> (kCSlider, kAttrDrawValueInverted, false, &uidesc, [&] (CSlider* v) {
return !(v->getDrawStyle () & CSlider::kDrawInverted);
});
}
TEST_CASE (CSliderCreatorTest, FrameColor)
{
DummyUIDescription uidesc;
testAttribute<CSlider> (kCSlider, kAttrDrawFrameColor, kColorName, &uidesc,
[&] (CSlider* v) { return v->getFrameColor () == uidesc.color; });
}
TEST_CASE (CSliderCreatorTest, BackColor)
{
DummyUIDescription uidesc;
testAttribute<CSlider> (kCSlider, kAttrDrawBackColor, kColorName, &uidesc,
[&] (CSlider* v) { return v->getBackColor () == uidesc.color; });
}
TEST_CASE (CSliderCreatorTest, ValueColor)
{
DummyUIDescription uidesc;
testAttribute<CSlider> (kCSlider, kAttrDrawValueColor, kColorName, &uidesc,
[&] (CSlider* v) { return v->getValueColor () == uidesc.color; });
}
TEST_CASE (CSliderCreatorTest, OrientationValues)
{
DummyUIDescription uidesc;
testPossibleValues (kCSlider, kAttrOrientation, &uidesc, {"horizontal", "vertical"});
}
TEST_CASE (CSliderCreatorTest, ModeValues)
{
DummyUIDescription uidesc;
testPossibleValues (kCSlider, kAttrMode, &uidesc,
{"touch", "relative touch", "free click", "ramp", "use global"});
}
TEST_CASE (CSliderCreatorTest, FrameWidth)
{
DummyUIDescription uidesc;
testAttribute<CSlider> (kCSlider, kAttrFrameWidth, 10, &uidesc,
[&] (CSlider* v) { return v->getFrameWidth () == 10; });
}
} // VSTGUI
@@ -0,0 +1,63 @@
// This file is part of VSTGUI. It is subject to the license terms
// in the LICENSE file found in the top-level directory of this
// distribution and at http://github.com/steinbergmedia/vstgui/LICENSE
#include "../../../../lib/csplitview.h"
#include "../../../../lib/cstring.h"
#include "../../../../uidescription/detail/uiviewcreatorattributes.h"
#include "../../../../uidescription/uiattributes.h"
#include "../../../../uidescription/uiviewfactory.h"
#include "../../unittests.h"
#include "helpers.h"
namespace VSTGUI {
using namespace UIViewCreator;
TEST_CASE (CSplitViewCreatorTest, SeparatorWidth)
{
testAttribute<CSplitView> (kCSplitView, kAttrSeparatorWidth, 123, nullptr,
[] (CSplitView* v) { return v->getSeparatorWidth () == 123; });
}
TEST_CASE (CSplitViewCreatorTest, Orientation)
{
DummyUIDescription uidesc;
testAttribute<CSplitView> (
kCSplitView, kAttrOrientation, "horizontal", &uidesc,
[&] (CSplitView* v) { return v->getStyle () == CSplitView::kHorizontal; });
testAttribute<CSplitView> (
kCSplitView, kAttrOrientation, "vertical", &uidesc,
[&] (CSplitView* v) { return v->getStyle () == CSplitView::kVertical; });
}
TEST_CASE (CSplitViewCreatorTest, ResizeMethod)
{
DummyUIDescription uidesc;
testAttribute<CSplitView> (
kCSplitView, kAttrResizeMethod, "first", &uidesc,
[&] (CSplitView* v) { return v->getResizeMethod () == CSplitView::kResizeFirstView; });
testAttribute<CSplitView> (
kCSplitView, kAttrResizeMethod, "second", &uidesc,
[&] (CSplitView* v) { return v->getResizeMethod () == CSplitView::kResizeSecondView; });
testAttribute<CSplitView> (
kCSplitView, kAttrResizeMethod, "last", &uidesc,
[&] (CSplitView* v) { return v->getResizeMethod () == CSplitView::kResizeLastView; });
testAttribute<CSplitView> (kCSplitView, kAttrResizeMethod, "all", &uidesc, [&] (CSplitView* v) {
return v->getResizeMethod () == CSplitView::kResizeAllViews;
});
}
TEST_CASE (CSplitViewCreatorTest, OrientationValues)
{
DummyUIDescription uidesc;
testPossibleValues (kCSplitView, kAttrOrientation, &uidesc, {"horizontal", "vertical"});
}
TEST_CASE (CSplitViewCreatorTest, ResizeMethodValues)
{
DummyUIDescription uidesc;
testPossibleValues (kCSplitView, kAttrResizeMethod, &uidesc,
{"first", "second", "last", "all"});
}
} // VSTGUI
@@ -0,0 +1,213 @@
// This file is part of VSTGUI. It is subject to the license terms
// in the LICENSE file found in the top-level directory of this
// distribution and at http://github.com/steinbergmedia/vstgui/LICENSE
#include "../../../../lib/controls/cbuttons.h"
#include "../../../../lib/cstring.h"
#include "../../../../uidescription/detail/uiviewcreatorattributes.h"
#include "../../../../uidescription/uiattributes.h"
#include "../../../../uidescription/uiviewfactory.h"
#include "../../unittests.h"
#include "helpers.h"
namespace VSTGUI {
using namespace UIViewCreator;
TEST_CASE (CTextButtonCreatorTest, Title)
{
DummyUIDescription uidesc;
UTF8String title ("Title");
testAttribute<CTextButton> (kCTextButton, kAttrTitle, title, &uidesc,
[&] (CTextButton* v) { return v->getTitle () == title; });
}
TEST_CASE (CTextButtonCreatorTest, Font)
{
DummyUIDescription uidesc;
testAttribute<CTextButton> (kCTextButton, kAttrFont, kFontName, &uidesc,
[&] (CTextButton* v) { return v->getFont () == uidesc.font; },
true);
}
TEST_CASE (CTextButtonCreatorTest, TextColor)
{
DummyUIDescription uidesc;
testAttribute<CTextButton> (
kCTextButton, kAttrTextColor, kColorName, &uidesc,
[&] (CTextButton* v) { return v->getTextColor () == uidesc.color; });
}
TEST_CASE (CTextButtonCreatorTest, TextColorHighlighted)
{
DummyUIDescription uidesc;
testAttribute<CTextButton> (
kCTextButton, kAttrTextColorHighlighted, kColorName, &uidesc,
[&] (CTextButton* v) { return v->getTextColorHighlighted () == uidesc.color; });
}
TEST_CASE (CTextButtonCreatorTest, FrameColor)
{
DummyUIDescription uidesc;
testAttribute<CTextButton> (
kCTextButton, kAttrFrameColor, kColorName, &uidesc,
[&] (CTextButton* v) { return v->getFrameColor () == uidesc.color; });
}
TEST_CASE (CTextButtonCreatorTest, FrameColorHighlighted)
{
DummyUIDescription uidesc;
testAttribute<CTextButton> (
kCTextButton, kAttrFrameColorHighlighted, kColorName, &uidesc,
[&] (CTextButton* v) { return v->getFrameColorHighlighted () == uidesc.color; });
}
TEST_CASE (CTextButtonCreatorTest, FrameWidth)
{
DummyUIDescription uidesc;
testAttribute<CTextButton> (kCTextButton, kAttrFrameWidth, 5., &uidesc,
[&] (CTextButton* v) { return v->getFrameWidth () == 5.; });
}
TEST_CASE (CTextButtonCreatorTest, RoundRadius)
{
DummyUIDescription uidesc;
testAttribute<CTextButton> (kCTextButton, kAttrRoundRadius, 5., &uidesc,
[&] (CTextButton* v) { return v->getRoundRadius () == 5.; });
}
TEST_CASE (CTextButtonCreatorTest, IconTextMargin)
{
DummyUIDescription uidesc;
testAttribute<CTextButton> (kCTextButton, kAttrIconTextMargin, 5., &uidesc,
[&] (CTextButton* v) { return v->getTextMargin () == 5.; });
}
TEST_CASE (CTextButtonCreatorTest, KickStyle)
{
DummyUIDescription uidesc;
testAttribute<CTextButton> (kCTextButton, kAttrKickStyle, true, &uidesc, [&] (CTextButton* v) {
return v->getStyle () == CTextButton::kKickStyle;
});
testAttribute<CTextButton> (kCTextButton, kAttrKickStyle, false, &uidesc, [&] (CTextButton* v) {
return v->getStyle () == CTextButton::kOnOffStyle;
});
}
TEST_CASE (CTextButtonCreatorTest, Icon)
{
DummyUIDescription uidesc;
testAttribute<CTextButton> (kCTextButton, kAttrIcon, kBitmapName, &uidesc,
[&] (CTextButton* v) { return v->getIcon () == uidesc.bitmap; });
}
TEST_CASE (CTextButtonCreatorTest, IconHighlighted)
{
DummyUIDescription uidesc;
testAttribute<CTextButton> (
kCTextButton, kAttrIconHighlighted, kBitmapName, &uidesc,
[&] (CTextButton* v) { return v->getIconHighlighted () == uidesc.bitmap; });
}
TEST_CASE (CTextButtonCreatorTest, IconPosition)
{
DummyUIDescription uidesc;
testAttribute<CTextButton> (
kCTextButton, kAttrIconPosition, "left", &uidesc,
[&] (CTextButton* v) { return v->getIconPosition () == CDrawMethods::kIconLeft; });
testAttribute<CTextButton> (
kCTextButton, kAttrIconPosition, "right", &uidesc,
[&] (CTextButton* v) { return v->getIconPosition () == CDrawMethods::kIconRight; });
testAttribute<CTextButton> (
kCTextButton, kAttrIconPosition, "center above text", &uidesc,
[&] (CTextButton* v) { return v->getIconPosition () == CDrawMethods::kIconCenterAbove; });
testAttribute<CTextButton> (
kCTextButton, kAttrIconPosition, "center below text", &uidesc,
[&] (CTextButton* v) { return v->getIconPosition () == CDrawMethods::kIconCenterBelow; });
}
TEST_CASE (CTextButtonCreatorTest, TextAlignment)
{
DummyUIDescription uiDesc;
testAttribute<CTextButton> (
kCTextButton, kAttrTextAlignment, "left", &uiDesc,
[&] (CTextButton* v) { return v->getTextAlignment () == kLeftText; });
testAttribute<CTextButton> (
kCTextButton, kAttrTextAlignment, "center", &uiDesc,
[&] (CTextButton* v) { return v->getTextAlignment () == kCenterText; });
testAttribute<CTextButton> (
kCTextButton, kAttrTextAlignment, "right", &uiDesc,
[&] (CTextButton* v) { return v->getTextAlignment () == kRightText; });
}
TEST_CASE (CTextButtonCreatorTest, Gradient)
{
DummyUIDescription uidesc;
testAttribute<CTextButton> (
kCTextButton, kAttrGradient, kGradientName, &uidesc,
[&] (CTextButton* v) { return v->getGradient () == uidesc.gradient; });
}
TEST_CASE (CTextButtonCreatorTest, GradientHighlighted)
{
DummyUIDescription uidesc;
testAttribute<CTextButton> (
kCTextButton, kAttrGradientHighlighted, kGradientName, &uidesc,
[&] (CTextButton* v) { return v->getGradientHighlighted () == uidesc.gradient; });
}
TEST_CASE (CTextButtonCreatorTest, IconPositionValues)
{
DummyUIDescription uidesc;
testPossibleValues (kCTextButton, kAttrIconPosition, &uidesc,
{"left", "right", "center above text", "center below text"});
}
TEST_CASE (CTextButtonCreatorTest, LegacyGradient)
{
auto defTB = owned (new CTextButton (CRect (0, 0, 100, 20), nullptr, -1, ""));
DummyUIDescription uidesc;
UIViewFactory factory;
UIAttributes a;
a.setAttribute (kAttrClass, kCTextButton);
a.setAttribute (kAttrGradientStartColor, kColorName);
auto v = owned (factory.createView (a, &uidesc));
auto view = v.cast<CTextButton> ();
EXPECT (view);
EXPECT (*view->getGradient () == *defTB->getGradient ());
EXPECT (*view->getGradientHighlighted () == *defTB->getGradientHighlighted ());
a.setAttribute (kAttrGradientStartColorHighlighted, kColorName);
v = owned (factory.createView (a, &uidesc));
view = v.cast<CTextButton> ();
EXPECT (view);
EXPECT (*view->getGradient () == *defTB->getGradient ());
EXPECT (*view->getGradientHighlighted () == *defTB->getGradientHighlighted ());
a.setAttribute (kAttrGradientEndColor, kColorName);
v = owned (factory.createView (a, &uidesc));
view = v.cast<CTextButton> ();
EXPECT (view);
EXPECT (*view->getGradient () == *defTB->getGradient ());
EXPECT (*view->getGradientHighlighted () == *defTB->getGradientHighlighted ());
a.setAttribute (kAttrGradientEndColorHighlighted, kColorName);
v = owned (factory.createView (a, &uidesc));
view = v.cast<CTextButton> ();
EXPECT (view);
EXPECT (*view->getGradient () != *defTB->getGradient ());
EXPECT (*view->getGradientHighlighted () != *defTB->getGradientHighlighted ());
UIAttributes a2;
factory.getAttributesForView (view, &uidesc, a2);
auto str = a2.getAttributeValue (kAttrGradient);
EXPECT (str);
str = a2.getAttributeValue (kAttrGradientHighlighted);
EXPECT (str);
}
} // VSTGUI
@@ -0,0 +1,47 @@
// This file is part of VSTGUI. It is subject to the license terms
// in the LICENSE file found in the top-level directory of this
// distribution and at http://github.com/steinbergmedia/vstgui/LICENSE
#include "../../../../lib/controls/ctextedit.h"
#include "../../../../lib/cstring.h"
#include "../../../../uidescription/detail/uiviewcreatorattributes.h"
#include "../../../../uidescription/uiattributes.h"
#include "../../../../uidescription/uiviewfactory.h"
#include "../../unittests.h"
#include "helpers.h"
namespace VSTGUI {
using namespace UIViewCreator;
TEST_CASE (CTextEditCreatorTest, ImmediateTextChange)
{
UIDescriptionAdapter uidesc;
testAttribute<CTextEdit> (kCTextEdit, kAttrImmediateTextChange, true, &uidesc,
[] (CTextEdit* v) { return v->getImmediateTextChange (); });
}
TEST_CASE (CTextEditCreatorTest, DoubleClick)
{
UIDescriptionAdapter uidesc;
testAttribute<CTextEdit> (kCTextEdit, kAttrStyleDoubleClick, true, &uidesc, [] (CTextEdit* v) {
return v->getStyle () & CTextEdit::kDoubleClickStyle;
});
}
TEST_CASE (CTextEditCreatorTest, SecureStyle)
{
DummyUIDescription uidesc;
testAttribute<CTextEdit> (kCTextEdit, kAttrSecureStyle, true, &uidesc,
[&] (CTextEdit* v) { return v->getSecureStyle () == true; });
}
TEST_CASE (CTextEditCreatorTest, PlaceholderTitle)
{
DummyUIDescription uidesc;
auto testValue = "This is a placeholder";
testAttribute<CTextEdit> (
kCTextEdit, kAttrPlaceholderTitle, testValue, &uidesc,
[&] (CTextEdit* b) { return b->getPlaceholderString () == testValue; });
}
} // VSTGUI
@@ -0,0 +1,47 @@
// This file is part of VSTGUI. It is subject to the license terms
// in the LICENSE file found in the top-level directory of this
// distribution and at http://github.com/steinbergmedia/vstgui/LICENSE
#include "../../../../lib/controls/ctextlabel.h"
#include "../../../../lib/cstring.h"
#include "../../../../uidescription/detail/uiviewcreatorattributes.h"
#include "../../../../uidescription/uiattributes.h"
#include "../../../../uidescription/uiviewfactory.h"
#include "../../unittests.h"
#include "helpers.h"
namespace VSTGUI {
using namespace UIViewCreator;
TEST_CASE (CTextLabelCreatorTest, Title)
{
UIDescriptionAdapter uidesc;
testAttribute<CTextLabel> (kCTextLabel, kAttrTitle, "Title", &uidesc,
[] (CTextLabel* v) { return v->getText () == "Title"; });
}
TEST_CASE (CTextLabelCreatorTest, TitleWithNewLines)
{
UIDescriptionAdapter uidesc;
const auto title = "This\\nIs\\nA Title";
testAttribute<CTextLabel> (kCTextLabel, kAttrTitle, title, &uidesc, [&] (CTextLabel* v) {
return v->getText () == "This\nIs\nA Title";
});
}
TEST_CASE (CTextLabelCreatorTest, TruncateMode)
{
UIDescriptionAdapter uidesc;
testAttribute<CTextLabel> (kCTextLabel, kAttrTruncateMode, "head", &uidesc, [] (CTextLabel* v) {
return v->getTextTruncateMode () == CTextLabel::kTruncateHead;
});
testAttribute<CTextLabel> (kCTextLabel, kAttrTruncateMode, "tail", &uidesc, [] (CTextLabel* v) {
return v->getTextTruncateMode () == CTextLabel::kTruncateTail;
});
testAttribute<CTextLabel> (kCTextLabel, kAttrTruncateMode, "", &uidesc, [] (CTextLabel* v) {
return v->getTextTruncateMode () == CTextLabel::kTruncateNone;
});
testPossibleValues (kCTextLabel, kAttrTruncateMode, &uidesc, {"head", "tail", "none"});
}
} // VSTGUI
@@ -0,0 +1,47 @@
// This file is part of VSTGUI. It is subject to the license terms
// in the LICENSE file found in the top-level directory of this
// distribution and at http://github.com/steinbergmedia/vstgui/LICENSE
#include "../../../../lib/controls/cswitch.h"
#include "../../../../lib/cstring.h"
#include "../../../../uidescription/detail/uiviewcreatorattributes.h"
#include "../../../../uidescription/uiattributes.h"
#include "../../../../uidescription/uiviewfactory.h"
#include "../../unittests.h"
#include "helpers.h"
namespace VSTGUI {
using namespace UIViewCreator;
#if VSTGUI_ENABLE_DEPRECATED_METHODS
TEST_CASE (CVerticalSwitchCreatorTest, HeightOfOneImage)
{
DummyUIDescription uidesc;
testAttribute<CVerticalSwitch> (
kCVerticalSwitch, kAttrHeightOfOneImage, 10, &uidesc,
[] (CVerticalSwitch* v) { return v->getHeightOfOneImage () == 10; });
}
TEST_CASE (CVerticalSwitchCreatorTest, SubPixmaps)
{
DummyUIDescription uidesc;
testAttribute<CVerticalSwitch> (
kCVerticalSwitch, kAttrSubPixmaps, 11, &uidesc,
[] (CVerticalSwitch* v) { return v->getNumSubPixmaps () == 11; });
}
#endif
TEST_CASE (CVerticalSwitchCreatorTest, InverseBitmap)
{
DummyUIDescription uidesc;
testAttribute<CVerticalSwitch> (
kCVerticalSwitch, kAttrInverseBitmap, true, &uidesc,
[] (CVerticalSwitch* v) { return v->getInverseBitmap () == true; });
testAttribute<CVerticalSwitch> (
kCVerticalSwitch, kAttrInverseBitmap, false, &uidesc,
[] (CVerticalSwitch* v) { return v->getInverseBitmap () == false; });
}
} // VSTGUI
@@ -0,0 +1,50 @@
// This file is part of VSTGUI. It is subject to the license terms
// in the LICENSE file found in the top-level directory of this
// distribution and at http://github.com/steinbergmedia/vstgui/LICENSE
#include "../../../../lib/cstring.h"
#include "../../../../lib/cviewcontainer.h"
#include "../../../../uidescription/detail/uiviewcreatorattributes.h"
#include "../../../../uidescription/uiattributes.h"
#include "../../../../uidescription/uiviewfactory.h"
#include "../../unittests.h"
#include "helpers.h"
namespace VSTGUI {
using namespace UIViewCreator;
TEST_CASE (CViewContainerCreatorTest, BackgroundColor)
{
DummyUIDescription uidesc;
testAttribute<CViewContainer> (
kCViewContainer, kAttrBackgroundColor, kColorName, &uidesc,
[&] (CViewContainer* v) { return v->getBackgroundColor () == uidesc.color; });
testAttribute<CViewContainer> (
kCViewContainer, kAttrBackgroundColor, kColorName, &uidesc,
[&] (CViewContainer* v) { return v->getBackgroundColor () == uidesc.color; }, true);
}
TEST_CASE (CViewContainerCreatorTest, BackgroundColorDrawStyle)
{
DummyUIDescription uidesc;
testAttribute<CViewContainer> (
kCViewContainer, kAttrBackgroundColorDrawStyle, "stroked", &uidesc,
[] (CViewContainer* v) { return v->getBackgroundColorDrawStyle () == kDrawStroked; });
testAttribute<CViewContainer> (
kCViewContainer, kAttrBackgroundColorDrawStyle, "filled", &uidesc,
[] (CViewContainer* v) { return v->getBackgroundColorDrawStyle () == kDrawFilled; });
testAttribute<CViewContainer> (kCViewContainer, kAttrBackgroundColorDrawStyle,
"filled and stroked", &uidesc, [] (CViewContainer* v) {
return v->getBackgroundColorDrawStyle () ==
kDrawFilledAndStroked;
});
}
TEST_CASE (CViewContainerCreatorTest, BackgroundColorDrawStyleValues)
{
DummyUIDescription uidesc;
testPossibleValues (kCViewContainer, kAttrBackgroundColorDrawStyle, &uidesc,
{"stroked", "filled", "filled and stroked"});
}
} // VSTGUI
@@ -0,0 +1,149 @@
// This file is part of VSTGUI. It is subject to the license terms
// in the LICENSE file found in the top-level directory of this
// distribution and at http://github.com/steinbergmedia/vstgui/LICENSE
#include "../../../../lib/cbitmap.h"
#include "../../../../lib/cstring.h"
#include "../../../../lib/cview.h"
#include "../../../../uidescription/detail/uiviewcreatorattributes.h"
#include "../../../../uidescription/uiattributes.h"
#include "../../../../uidescription/uiviewfactory.h"
#include "../../unittests.h"
#include "helpers.h"
namespace VSTGUI {
using namespace UIViewCreator;
namespace {
bool getViewAttributeString (CView* view, const CViewAttributeID attrID, std::string& value)
{
uint32_t attrSize = 0;
if (view->getAttributeSize (attrID, attrSize))
{
char* cstr = new char[attrSize + 1];
if (view->getAttribute (attrID, attrSize, cstr, attrSize))
value = cstr;
else
value = "";
delete[] cstr;
return true;
}
return false;
}
} // anonymous
TEST_CASE (CViewCreatorTest, Origin)
{
CPoint origin (20, 20);
testAttribute<CView> (kCView, kAttrOrigin, origin, nullptr,
[&] (CView* v) { return v->getViewSize ().getTopLeft () == origin; });
}
TEST_CASE (CViewCreatorTest, Size)
{
CPoint size (20, 20);
testAttribute<CView> (kCView, kAttrSize, size, nullptr,
[&] (CView* v) { return v->getViewSize ().getSize () == size; });
}
TEST_CASE (CViewCreatorTest, Bitmap)
{
DummyUIDescription uiDesc;
testAttribute<CView> (kCView, kAttrBitmap, kBitmapName, &uiDesc,
[&] (CView* v) { return v->getBackground () == uiDesc.bitmap; });
}
TEST_CASE (CViewCreatorTest, DisabledBitmap)
{
DummyUIDescription uiDesc;
testAttribute<CView> (kCView, kAttrDisabledBitmap, kBitmapName, &uiDesc,
[&] (CView* v) { return v->getDisabledBackground () == uiDesc.bitmap; });
}
TEST_CASE (CViewCreatorTest, Transparent)
{
testAttribute<CView> (kCView, kAttrTransparent, true, nullptr,
[&] (CView* v) { return v->getTransparency (); });
testAttribute<CView> (kCView, kAttrTransparent, false, nullptr,
[&] (CView* v) { return v->getTransparency () == false; });
}
TEST_CASE (CViewCreatorTest, MouseEnabled)
{
testAttribute<CView> (kCView, kAttrMouseEnabled, true, nullptr,
[&] (CView* v) { return v->getMouseEnabled (); });
testAttribute<CView> (kCView, kAttrMouseEnabled, false, nullptr,
[&] (CView* v) { return v->getMouseEnabled () == false; });
}
TEST_CASE (CViewCreatorTest, Autosize)
{
testAttribute<CView> (kCView, kAttrAutosize, "left ", nullptr,
[&] (CView* v) { return v->getAutosizeFlags () & kAutosizeLeft; });
testAttribute<CView> (kCView, kAttrAutosize, "top ", nullptr,
[&] (CView* v) { return v->getAutosizeFlags () & kAutosizeTop; });
testAttribute<CView> (kCView, kAttrAutosize, "right ", nullptr,
[&] (CView* v) { return v->getAutosizeFlags () & kAutosizeRight; });
testAttribute<CView> (kCView, kAttrAutosize, "bottom ", nullptr,
[&] (CView* v) { return v->getAutosizeFlags () & kAutosizeBottom; });
testAttribute<CView> (kCView, kAttrAutosize, "row ", nullptr,
[&] (CView* v) { return v->getAutosizeFlags () & kAutosizeRow; });
testAttribute<CView> (kCView, kAttrAutosize, "column ", nullptr,
[&] (CView* v) { return v->getAutosizeFlags () & kAutosizeColumn; });
}
TEST_CASE (CViewCreatorTest, Tooltip)
{
std::string tooltipStr = "This is a tooltip";
testAttribute<CView> (kCView, kAttrTooltip, tooltipStr.c_str (), nullptr, [&] (CView* v) {
std::string str;
EXPECT (getViewAttributeString (v, kCViewTooltipAttribute, str));
return str == tooltipStr;
});
UIViewFactory factory;
UIAttributes a;
a.setAttribute (kAttrClass, kCView);
a.setAttribute (kAttrTooltip, "");
auto view = owned (factory.createView (a, nullptr));
std::string str;
EXPECT (getViewAttributeString (view, kCViewTooltipAttribute, str) == false);
}
TEST_CASE (CViewCreatorTest, CustomViewName)
{
std::string customViewName = "CustomView";
testAttribute<CView> (kCView, kAttrCustomViewName, customViewName.c_str (), nullptr,
[&] (CView* v) {
std::string str;
EXPECT (getViewAttributeString (v, 'uicv', str));
return str == customViewName;
});
}
TEST_CASE (CViewCreatorTest, SubControllerName)
{
std::string subControllerName = "SubController";
testAttribute<CView> (kCView, kAttrSubController, subControllerName.c_str (), nullptr,
[&] (CView* v) {
std::string str;
EXPECT (getViewAttributeString (v, 'uisc', str));
return str == subControllerName;
});
}
TEST_CASE (CViewCreatorTest, Opacity)
{
testAttribute<CView> (kCView, kAttrOpacity, 0.5, nullptr,
[&] (CView* v) { return v->getAlphaValue () == 0.5; });
}
TEST_CASE (CViewCreatorTest, OpacityValueRange)
{
testMinMaxValues (kCView, kAttrOpacity, nullptr, 0., 1.);
}
} // VSTGUI
@@ -0,0 +1,54 @@
// This file is part of VSTGUI. It is subject to the license terms
// in the LICENSE file found in the top-level directory of this
// distribution and at http://github.com/steinbergmedia/vstgui/LICENSE
#include "../../../../lib/controls/cvumeter.h"
#include "../../../../lib/cstring.h"
#include "../../../../uidescription/detail/uiviewcreatorattributes.h"
#include "../../../../uidescription/uiattributes.h"
#include "../../../../uidescription/uiviewfactory.h"
#include "../../unittests.h"
#include "helpers.h"
namespace VSTGUI {
using namespace UIViewCreator;
TEST_CASE (CVuMeterCreatorTest, OffBitmap)
{
DummyUIDescription uidesc;
testAttribute<CVuMeter> (kCVuMeter, kAttrOffBitmap, kBitmapName, &uidesc,
[&] (CVuMeter* v) { return v->getOffBitmap () == uidesc.bitmap; });
}
TEST_CASE (CVuMeterCreatorTest, Orientation)
{
DummyUIDescription uidesc;
testAttribute<CVuMeter> (kCVuMeter, kAttrOrientation, "horizontal", &uidesc, [&] (CVuMeter* v) {
return v->getStyle () == CVuMeter::Style::kHorizontal;
});
testAttribute<CVuMeter> (kCVuMeter, kAttrOrientation, "vertical", &uidesc, [&] (CVuMeter* v) {
return v->getStyle () == CVuMeter::Style::kVertical;
});
}
TEST_CASE (CVuMeterCreatorTest, NumLed)
{
DummyUIDescription uidesc;
testAttribute<CVuMeter> (kCVuMeter, kAttrNumLed, 5, &uidesc,
[&] (CVuMeter* v) { return v->getNbLed () == 5; });
}
TEST_CASE (CVuMeterCreatorTest, DecreaseStepValue)
{
DummyUIDescription uidesc;
testAttribute<CVuMeter> (kCVuMeter, kAttrDecreaseStepValue, 15., &uidesc,
[&] (CVuMeter* v) { return v->getDecreaseStepValue () == 15.; });
}
TEST_CASE (CVuMeterCreatorTest, OrientationValues)
{
DummyUIDescription uidesc;
testPossibleValues (kCVuMeter, kAttrOrientation, &uidesc, {"horizontal", "vertical"});
}
} // VSTGUI
@@ -0,0 +1,30 @@
// This file is part of VSTGUI. It is subject to the license terms
// in the LICENSE file found in the top-level directory of this
// distribution and at http://github.com/steinbergmedia/vstgui/LICENSE
#include "../../../../lib/controls/cxypad.h"
#include "../../../../lib/cstring.h"
#include "../../../../uidescription/detail/uiviewcreatorattributes.h"
#include "../../../../uidescription/uiattributes.h"
#include "../../../../uidescription/uiviewfactory.h"
#include "../../unittests.h"
#include "helpers.h"
namespace VSTGUI {
using namespace UIViewCreator;
TEST_CASE (CXYPadCreatorTest, Create)
{
DummyUIDescription uidesc;
UIViewFactory factory;
UIAttributes a;
a.setAttribute (kAttrClass, kCXYPad);
auto view = owned (factory.createView (a, &uidesc));
auto control = view.cast<CXYPad> ();
EXPECT (control);
UIAttributes a2;
EXPECT (factory.getAttributesForView (view, &uidesc, a2));
}
} // VSTGUI
@@ -0,0 +1,287 @@
// This file is part of VSTGUI. It is subject to the license terms
// in the LICENSE file found in the top-level directory of this
// distribution and at http://github.com/steinbergmedia/vstgui/LICENSE
#pragma once
#include "../../../../lib/cbitmap.h"
#include "../../../../lib/cgradient.h"
#include "../../../../lib/cstring.h"
#include "../../../../uidescription/uiattributes.h"
#include "../../../../uidescription/uiviewcreator.h"
#include "../../../../uidescription/uiviewfactory.h"
#include "../uidescriptionadapter.h"
namespace VSTGUI {
constexpr IdStringPtr kColorName = "MyColor";
constexpr IdStringPtr kFontName = "MyFont";
constexpr IdStringPtr kBitmapName = "MyBitmap";
constexpr IdStringPtr kGradientName = "MyGradient";
constexpr IdStringPtr kTagName = "tagname";
class DummyUIDescription : public UIDescriptionAdapter
{
public:
bool getColor (UTF8StringPtr name, CColor& c) const override
{
if (UTF8StringView (name) == kColorName)
{
c = this->color;
return true;
}
return false;
}
UTF8StringPtr lookupColorName (const CColor& c) const override
{
if (this->color == c)
return kColorName;
return nullptr;
}
CFontRef getFont (UTF8StringPtr name) const override
{
if (UTF8StringView (name) == kFontName)
return font;
return nullptr;
}
UTF8StringPtr lookupFontName (const CFontRef f) const override
{
if (f == this->font)
return kFontName;
return nullptr;
}
CBitmap* getBitmap (UTF8StringPtr name) const override
{
if (UTF8StringView (name) == kBitmapName)
return bitmap;
return nullptr;
}
UTF8StringPtr lookupBitmapName (const CBitmap* inBitmap) const override
{
if (inBitmap == bitmap)
return kBitmapName;
return nullptr;
}
CGradient* getGradient (UTF8StringPtr name) const override
{
if (UTF8StringView (name) == kGradientName)
return gradient;
return nullptr;
}
UTF8StringPtr lookupGradientName (const CGradient* g) const override
{
if (g == this->gradient)
return kGradientName;
return nullptr;
}
int32_t getTagForName (UTF8StringPtr name) const override
{
if (UTF8StringView (name) == kTagName)
return tag;
return -1;
}
UTF8StringPtr lookupControlTagName (const int32_t t) const override
{
if (this->tag != -1 && t == this->tag)
return kTagName;
return nullptr;
}
IControlListener* getControlListener (UTF8StringPtr name) const override
{
if (UTF8StringView (name) == kTagName)
return listener;
return nullptr;
}
int32_t tag {-1};
CColor color {20, 30, 50, 255};
SharedPointer<CFontDesc> font = owned (new CFontDesc ("Arial", 12));
SharedPointer<CBitmap> bitmap = owned (new CBitmap (1, 1));
SharedPointer<CGradient> gradient =
owned (CGradient::create (0, 1, kBlackCColor, kWhiteCColor));
IControlListener* listener {nullptr};
};
inline void testPossibleValues (const IdStringPtr className, const std::string& attrName,
IUIDescription* desc, UIViewFactory::StringList expectedValues)
{
UIViewFactory factory;
UIAttributes a;
a.setAttribute (UIViewCreator::kAttrClass, className);
auto view = owned (factory.createView (a, desc));
UIViewFactory::StringPtrList values;
EXPECT (factory.getPossibleAttributeListValues (view, attrName, values));
for (auto& v : expectedValues)
{
EXPECT (std::find_if (values.begin (), values.end (),
[&] (const UIViewFactory::StringPtrList::value_type& value) {
return *value == v;
}) != values.end ());
}
EXPECT (values.size () == expectedValues.size ());
}
inline void testMinMaxValues (const IdStringPtr className, const std::string& attrName,
IUIDescription* desc, double minValue, double maxValue)
{
UIViewFactory factory;
UIAttributes a;
a.setAttribute (UIViewCreator::kAttrClass, className);
auto view = owned (factory.createView (a, desc));
double min, max;
EXPECT (factory.getAttributeValueRange (view, attrName, min, max));
EXPECT (min == minValue);
EXPECT (max == maxValue);
}
template <typename ViewClass, typename Proc>
void testAttribute (const IdStringPtr viewName, const std::string& attrName,
const IdStringPtr attrValue, IUIDescription* desc, const Proc& proc,
bool disableRememberAttributes = false)
{
UIViewFactory factory;
factory.disableRememberAttributes = disableRememberAttributes;
UIAttributes a;
a.setAttribute (UIViewCreator::kAttrClass, viewName);
a.setAttribute (attrName, attrValue);
auto v = owned (factory.createView (a, desc));
auto view = v.cast<ViewClass> ();
EXPECT (view);
EXPECT (proc (view));
UIAttributes a2;
factory.getAttributesForView (view, desc, a2);
auto str = a2.getAttributeValue (attrName);
EXPECT (str);
EXPECT (*str == attrValue);
}
template <typename ViewClass, typename Proc>
void testAttribute (const IdStringPtr viewName, const std::string& attrName, int32_t attrValue,
IUIDescription* desc, const Proc& proc)
{
UIViewFactory factory;
UIAttributes a;
a.setAttribute (UIViewCreator::kAttrClass, viewName);
a.setIntegerAttribute (attrName, attrValue);
auto v = owned (factory.createView (a, desc));
auto view = v.cast<ViewClass> ();
EXPECT (view);
EXPECT (proc (view));
UIAttributes a2;
factory.getAttributesForView (view, desc, a2);
int32_t value;
a2.getIntegerAttribute (attrName, value);
EXPECT (value == attrValue);
}
template <typename ViewClass, typename Proc>
void testAttribute (const IdStringPtr viewName, const std::string& attrName, bool attrValue,
IUIDescription* desc, const Proc& proc)
{
UIViewFactory factory;
UIAttributes a;
a.setAttribute (UIViewCreator::kAttrClass, viewName);
a.setBooleanAttribute (attrName, attrValue);
auto v = owned (factory.createView (a, desc));
auto view = v.cast<ViewClass> ();
EXPECT (view);
EXPECT (proc (view));
UIAttributes a2;
factory.getAttributesForView (view, desc, a2);
bool value;
a2.getBooleanAttribute (attrName, value);
EXPECT (value == attrValue);
}
template <typename ViewClass, typename Proc>
void testAttribute (const IdStringPtr viewName, const std::string& attrName, double attrValue,
IUIDescription* desc, const Proc& proc)
{
UIViewFactory factory;
UIAttributes a;
a.setAttribute (UIViewCreator::kAttrClass, viewName);
a.setDoubleAttribute (attrName, attrValue);
auto v = owned (factory.createView (a, desc));
auto view = v.cast<ViewClass> ();
EXPECT (view);
EXPECT (proc (view));
UIAttributes a2;
factory.getAttributesForView (view, desc, a2);
double value;
a2.getDoubleAttribute (attrName, value);
EXPECT (value == attrValue);
}
template <typename ViewClass, typename Proc>
void testAttribute (const IdStringPtr viewName, const std::string& attrName, const CRect& attrValue,
IUIDescription* desc, const Proc& proc)
{
UIViewFactory factory;
UIAttributes a;
a.setAttribute (UIViewCreator::kAttrClass, viewName);
a.setRectAttribute (attrName, attrValue);
auto v = owned (factory.createView (a, desc));
auto view = v.cast<ViewClass> ();
EXPECT (view);
EXPECT (proc (view));
UIAttributes a2;
factory.getAttributesForView (view, desc, a2);
CRect value;
a2.getRectAttribute (attrName, value);
EXPECT (value == attrValue);
}
template <typename ViewClass, typename Proc>
void testAttribute (const IdStringPtr viewName, const std::string& attrName,
const CPoint& attrValue, IUIDescription* desc, const Proc& proc)
{
UIViewFactory factory;
UIAttributes a;
a.setAttribute (UIViewCreator::kAttrClass, viewName);
a.setPointAttribute (attrName, attrValue);
auto v = owned (factory.createView (a, desc));
auto view = v.cast<ViewClass> ();
EXPECT (view);
EXPECT (proc (view));
UIAttributes a2;
factory.getAttributesForView (view, desc, a2);
CPoint value;
a2.getPointAttribute (attrName, value);
EXPECT (value == attrValue);
}
inline bool operator!= (const CGradient& g1, const CGradient& g2)
{
auto cs1 = g1.getColorStops ();
auto cs2 = g2.getColorStops ();
return cs1 != cs2;
}
inline bool operator== (const CGradient& g1, const CGradient& g2)
{
auto cs1 = g1.getColorStops ();
auto cs2 = g2.getColorStops ();
return cs1 == cs2;
}
} // VSTGUI
@@ -0,0 +1,137 @@
// This file is part of VSTGUI. It is subject to the license terms
// in the LICENSE file found in the top-level directory of this
// distribution and at http://github.com/steinbergmedia/vstgui/LICENSE
#include "../../../../lib/controls/cstringlist.h"
#include "../../../../lib/cstring.h"
#include "../../../../uidescription/detail/uiviewcreatorattributes.h"
#include "../../../../uidescription/uiattributes.h"
#include "../../../../uidescription/uiviewfactory.h"
#include "../../unittests.h"
#include "helpers.h"
namespace VSTGUI {
using namespace UIViewCreator;
//------------------------------------------------------------------------
static StringListControlDrawer* getDrawer (CListControl* c)
{
return dynamic_cast<StringListControlDrawer*> (c->getDrawer ());
}
//------------------------------------------------------------------------
static StaticListControlConfigurator* getConfigurator (CListControl* c)
{
return dynamic_cast<StaticListControlConfigurator*> (c->getConfigurator ());
}
//------------------------------------------------------------------------
TEST_CASE (StringListControlCreatorTest, StyleHover)
{
DummyUIDescription uidesc;
testAttribute<CListControl> (
kCStringListControl, kAttrStyleHover, true, &uidesc, [&] (CListControl* v) {
return (getConfigurator (v)->getFlags () & CListControlRowDesc::Hoverable) != 0;
});
testAttribute<CListControl> (
kCStringListControl, kAttrStyleHover, false, &uidesc, [&] (CListControl* v) {
return (getConfigurator (v)->getFlags () & CListControlRowDesc::Hoverable) == 0;
});
}
TEST_CASE (StringListControlCreatorTest, RowHeight)
{
DummyUIDescription uidesc;
testAttribute<CListControl> (
kCStringListControl, kAttrRowHeight, 14., &uidesc,
[&] (CListControl* v) { return getConfigurator (v)->getRowHeight () == 14.; });
}
TEST_CASE (StringListControlCreatorTest, Font)
{
DummyUIDescription uidesc;
testAttribute<CListControl> (
kCStringListControl, kAttrFont, kFontName, &uidesc,
[&] (CListControl* v) { return getDrawer (v)->getFont () == uidesc.font; }, true);
}
TEST_CASE (StringListControlCreatorTest, TextAlignment)
{
DummyUIDescription uidesc;
testAttribute<CListControl> (
kCStringListControl, kAttrTextAlignment, strRight, &uidesc,
[&] (CListControl* v) { return getDrawer (v)->getTextAlign () == kRightText; });
testAttribute<CListControl> (
kCStringListControl, kAttrTextAlignment, strLeft, &uidesc,
[&] (CListControl* v) { return getDrawer (v)->getTextAlign () == kLeftText; });
testAttribute<CListControl> (
kCStringListControl, kAttrTextAlignment, strCenter, &uidesc,
[&] (CListControl* v) { return getDrawer (v)->getTextAlign () == kCenterText; });
}
TEST_CASE (StringListControlCreatorTest, FontColor)
{
DummyUIDescription uidesc;
testAttribute<CListControl> (
kCStringListControl, kAttrFontColor, kColorName, &uidesc,
[&] (CListControl* v) { return getDrawer (v)->getFontColor () == uidesc.color; });
}
TEST_CASE (StringListControlCreatorTest, SelectedFontColor)
{
DummyUIDescription uidesc;
testAttribute<CListControl> (
kCStringListControl, kAttrSelectedFontColor, kColorName, &uidesc,
[&] (CListControl* v) { return getDrawer (v)->getSelectedFontColor () == uidesc.color; });
}
TEST_CASE (StringListControlCreatorTest, BackColor)
{
DummyUIDescription uidesc;
testAttribute<CListControl> (
kCStringListControl, kAttrBackColor, kColorName, &uidesc,
[&] (CListControl* v) { return getDrawer (v)->getBackColor () == uidesc.color; });
}
TEST_CASE (StringListControlCreatorTest, SelectedBackColor)
{
DummyUIDescription uidesc;
testAttribute<CListControl> (
kCStringListControl, kAttrSelectedBackColor, kColorName, &uidesc,
[&] (CListControl* v) { return getDrawer (v)->getSelectedBackColor () == uidesc.color; });
}
TEST_CASE (StringListControlCreatorTest, HoverColor)
{
DummyUIDescription uidesc;
testAttribute<CListControl> (
kCStringListControl, kAttrHoverColor, kColorName, &uidesc,
[&] (CListControl* v) { return getDrawer (v)->getHoverColor () == uidesc.color; });
}
TEST_CASE (StringListControlCreatorTest, LineColor)
{
DummyUIDescription uidesc;
testAttribute<CListControl> (
kCStringListControl, kAttrLineColor, kColorName, &uidesc,
[&] (CListControl* v) { return getDrawer (v)->getLineColor () == uidesc.color; });
}
TEST_CASE (StringListControlCreatorTest, LineWidth)
{
DummyUIDescription uidesc;
testAttribute<CListControl> (
kCStringListControl, kAttrLineWidth, 14., &uidesc,
[&] (CListControl* v) { return getDrawer (v)->getLineWidth () == 14.; });
}
TEST_CASE (StringListControlCreatorTest, TextInset)
{
DummyUIDescription uidesc;
testAttribute<CListControl> (
kCStringListControl, kAttrTextInset, 14., &uidesc,
[&] (CListControl* v) { return getDrawer (v)->getTextInset () == 14.; });
}
} // VSTGUI
@@ -0,0 +1,55 @@
// This file is part of VSTGUI. It is subject to the license terms
// in the LICENSE file found in the top-level directory of this
// distribution and at http://github.com/steinbergmedia/vstgui/LICENSE
#include "../../../../lib/cbitmap.h"
#include "../../../../lib/ccolor.h"
#include "../../../../lib/cpoint.h"
#include "../../../../lib/cstring.h"
#include "../../../../uidescription/uiviewcreator.h"
#include "../../unittests.h"
#include "../uidescriptionadapter.h"
namespace VSTGUI {
using namespace UIViewCreator;
TEST_CASE (UIViewCreatorTest, BitmapToString)
{
UIDescriptionAdapter uidesc;
std::string str;
CBitmap bitmap (CResourceDescription ("test.png"));
EXPECT (bitmapToString (&bitmap, str, &uidesc) == true);
EXPECT (str == "test.png");
CBitmap bitmap2 (CResourceDescription (100));
EXPECT (bitmapToString (&bitmap2, str, &uidesc) == true);
EXPECT (str == "100");
}
TEST_CASE (UIViewCreatorTest, ColorToString)
{
UIDescriptionAdapter uidesc;
std::string str;
CColor c (0, 0, 0, 255);
EXPECT (colorToString (c, str, &uidesc) == true);
EXPECT (str == "#000000ff")
c = CColor (0, 0, 255, 0);
EXPECT (colorToString (c, str, &uidesc) == true);
EXPECT (str == "#0000ff00")
c = CColor (0, 255, 0, 0);
EXPECT (colorToString (c, str, &uidesc) == true);
EXPECT (str == "#00ff0000")
c = CColor (255, 0, 0, 0);
EXPECT (colorToString (c, str, &uidesc) == true);
EXPECT (str == "#ff000000")
}
TEST_CASE (UIViewCreatorTest, EmptyStringToTransparentColor)
{
UIDescriptionAdapter uidesc;
std::string str = "";
CColor c;
EXPECT (stringToColor (&str, c, &uidesc) == true);
EXPECT (c == kTransparentCColor);
}
} // VSTGUI
@@ -0,0 +1,118 @@
// This file is part of VSTGUI. It is subject to the license terms
// in the LICENSE file found in the top-level directory of this
// distribution and at http://github.com/steinbergmedia/vstgui/LICENSE
#include "../../../../lib/cstring.h"
#include "../../../../uidescription/detail/uiviewcreatorattributes.h"
#include "../../../../uidescription/uiattributes.h"
#include "../../../../uidescription/uiviewfactory.h"
#include "../../../../uidescription/uiviewswitchcontainer.h"
#include "../../unittests.h"
#include "helpers.h"
namespace VSTGUI {
using namespace UIViewCreator;
TEST_CASE (UIViewSwitchContainerCreatorTest, TemplateNames)
{
DummyUIDescription uidesc;
testAttribute<UIViewSwitchContainer> (kUIViewSwitchContainer, kAttrTemplateNames, "temp1,temp2",
&uidesc, [] (UIViewSwitchContainer* v) {
auto controller =
dynamic_cast<UIDescriptionViewSwitchController*> (
v->getController ());
EXPECT (controller);
std::string str;
controller->getTemplateNames (str);
return str == "temp1,temp2";
});
}
TEST_CASE (UIViewSwitchContainerCreatorTest, TemplateSwitchControl)
{
DummyUIDescription uidesc;
uidesc.tag = 12345;
testAttribute<UIViewSwitchContainer> (
kUIViewSwitchContainer, kAttrTemplateSwitchControl, kTagName, &uidesc,
[&] (UIViewSwitchContainer* v) {
auto controller =
dynamic_cast<UIDescriptionViewSwitchController*> (v->getController ());
EXPECT (controller);
return controller->getSwitchControlTag () == uidesc.tag;
},
true);
}
TEST_CASE (UIViewSwitchContainerCreatorTest, AnimationStyle)
{
DummyUIDescription uidesc;
testAttribute<UIViewSwitchContainer> (kUIViewSwitchContainer, kAttrAnimationStyle, "fade",
&uidesc, [] (UIViewSwitchContainer* v) {
return v->getAnimationStyle () ==
UIViewSwitchContainer::kFadeInOut;
});
testAttribute<UIViewSwitchContainer> (kUIViewSwitchContainer, kAttrAnimationStyle, "move",
&uidesc, [] (UIViewSwitchContainer* v) {
return v->getAnimationStyle () ==
UIViewSwitchContainer::kMoveInOut;
});
testAttribute<UIViewSwitchContainer> (kUIViewSwitchContainer, kAttrAnimationStyle, "push",
&uidesc, [] (UIViewSwitchContainer* v) {
return v->getAnimationStyle () ==
UIViewSwitchContainer::kPushInOut;
});
}
TEST_CASE (UIViewSwitchContainerCreatorTest, AnimationTime)
{
DummyUIDescription uidesc;
testAttribute<UIViewSwitchContainer> (
kUIViewSwitchContainer, kAttrAnimationTime, 1234, &uidesc,
[] (UIViewSwitchContainer* v) { return v->getAnimationTime () == 1234; });
}
TEST_CASE (UIViewSwitchContainerCreatorTest, AnimationStyleValues)
{
DummyUIDescription uidesc;
testPossibleValues (kUIViewSwitchContainer, kAttrAnimationStyle, &uidesc,
{"fade", "move", "push"});
}
TEST_CASE (UIViewSwitchContainerCreatorTest, AnimationTimingFunction)
{
DummyUIDescription uidesc;
testAttribute<UIViewSwitchContainer> (kUIViewSwitchContainer, kAttrAnimationTimingFunction,
"linear", &uidesc, [] (UIViewSwitchContainer* v) {
return v->getTimingFunction () ==
UIViewSwitchContainer::kLinear;
});
testAttribute<UIViewSwitchContainer> (kUIViewSwitchContainer, kAttrAnimationTimingFunction,
"easy-in", &uidesc, [] (UIViewSwitchContainer* v) {
return v->getTimingFunction () ==
UIViewSwitchContainer::kEasyIn;
});
testAttribute<UIViewSwitchContainer> (kUIViewSwitchContainer, kAttrAnimationTimingFunction,
"easy-out", &uidesc, [] (UIViewSwitchContainer* v) {
return v->getTimingFunction () ==
UIViewSwitchContainer::kEasyOut;
});
testAttribute<UIViewSwitchContainer> (kUIViewSwitchContainer, kAttrAnimationTimingFunction,
"easy-in-out", &uidesc, [] (UIViewSwitchContainer* v) {
return v->getTimingFunction () ==
UIViewSwitchContainer::kEasyInOut;
});
testAttribute<UIViewSwitchContainer> (kUIViewSwitchContainer, kAttrAnimationTimingFunction,
"easy", &uidesc, [] (UIViewSwitchContainer* v) {
return v->getTimingFunction () ==
UIViewSwitchContainer::kEasy;
});
}
TEST_CASE (UIViewSwitchContainerCreatorTest, AnimationTimingFunctionValues)
{
DummyUIDescription uidesc;
testPossibleValues (kUIViewSwitchContainer, kAttrAnimationTimingFunction, &uidesc,
{"linear", "easy-in", "easy-out", "easy-in-out", "easy"});
}
} // VSTGUI
@@ -0,0 +1,351 @@
// This file is part of VSTGUI. It is subject to the license terms
// in the LICENSE file found in the top-level directory of this
// distribution and at http://github.com/steinbergmedia/vstgui/LICENSE
#include "../../../lib/cview.h"
#include "../../../lib/cviewcontainer.h"
#include "../../../uidescription/detail/uiviewcreatorattributes.h"
#include "../../../uidescription/uiattributes.h"
#include "../../../uidescription/uiviewfactory.h"
#include "../unittests.h"
#include <algorithm>
namespace VSTGUI {
namespace {
class BaseView : public CView
{
public:
BaseView () : CView (CRect (0, 0, 0, 0)) {}
enum class State
{
kState1,
kState2,
kState3
};
State baseState {State::kState1};
};
class View : public BaseView
{
public:
View () {}
int32_t value {0};
};
class CustomView : public View
{
public:
CustomView () {}
};
static std::string baseViewAttr ("BaseViewAttr");
struct BaseViewCreator : public ViewCreatorAdapter
{
IdStringPtr getViewName () const override { return "BaseView"; }
UTF8StringPtr getDisplayName () const override { return "Base View"; }
IdStringPtr getBaseViewName () const override { return nullptr; }
CView* create (const UIAttributes& attributes, const IUIDescription* description) const override
{
return new BaseView ();
}
bool apply (CView* view, const UIAttributes& attributes,
const IUIDescription* description) const override
{
auto v = dynamic_cast<BaseView*> (view);
if (!v)
return false;
auto attr = attributes.getAttributeValue (baseViewAttr);
if (attr)
{
if (*attr == "1")
v->baseState = BaseView::State::kState1;
if (*attr == "2")
v->baseState = BaseView::State::kState2;
if (*attr == "3")
v->baseState = BaseView::State::kState3;
}
return true;
}
bool getAttributeNames (std::list<std::string>& attributeNames) const override
{
attributeNames.push_back (baseViewAttr);
return true;
}
AttrType getAttributeType (const std::string& attributeName) const override
{
if (attributeName == baseViewAttr)
return kListType;
return kUnknownType;
}
bool getAttributeValue (CView* view, const std::string& attributeName, std::string& stringValue,
const IUIDescription* desc) const override
{
auto v = dynamic_cast<BaseView*> (view);
if (!v)
return false;
if (attributeName == baseViewAttr)
{
switch (v->baseState)
{
case BaseView::State::kState1: stringValue = "1"; break;
case BaseView::State::kState2: stringValue = "2"; break;
case BaseView::State::kState3: stringValue = "3"; break;
}
return true;
}
return false;
}
bool getPossibleListValues (const std::string& attributeName,
std::list<const std::string*>& values) const override
{
if (attributeName != baseViewAttr)
return false;
static const std::string v1 = "1";
static const std::string v2 = "2";
static const std::string v3 = "3";
values.push_back (&v1);
values.push_back (&v2);
values.push_back (&v3);
return true;
}
bool getAttributeValueRange (const std::string& attributeName, double& minValue,
double& maxValue) const override
{
return false;
}
};
BaseViewCreator baseViewCreator;
static std::string viewAttr ("ViewAttr");
struct ViewCreator : public ViewCreatorAdapter
{
IdStringPtr getViewName () const override { return "TestView"; }
UTF8StringPtr getDisplayName () const override { return "Test View"; }
IdStringPtr getBaseViewName () const override { return "BaseView"; }
CView* create (const UIAttributes& attributes, const IUIDescription* description) const override
{
return new View ();
}
bool apply (CView* view, const UIAttributes& attributes,
const IUIDescription* description) const override
{
auto v = dynamic_cast<View*> (view);
if (!v)
return false;
int32_t value;
if (attributes.getIntegerAttribute (viewAttr, value))
v->value = value;
return true;
}
bool getAttributeNames (std::list<std::string>& attributeNames) const override
{
attributeNames.push_back (viewAttr);
return true;
}
AttrType getAttributeType (const std::string& attributeName) const override
{
if (attributeName == viewAttr)
return kTagType;
return kUnknownType;
}
bool getAttributeValue (CView* view, const std::string& attributeName, std::string& stringValue,
const IUIDescription* desc) const override
{
auto v = dynamic_cast<View*> (view);
if (!v)
return false;
if (attributeName == viewAttr)
{
stringValue = std::to_string (v->value);
return true;
}
return false;
}
bool getPossibleListValues (const std::string& attributeName,
std::list<const std::string*>& values) const override
{
return false;
}
bool getAttributeValueRange (const std::string& attributeName, double& minValue,
double& maxValue) const override
{
if (attributeName != viewAttr)
return false;
minValue = -10;
maxValue = 10;
return true;
}
};
ViewCreator viewCreator;
static SharedPointer<CView> createView (IViewFactory* factory)
{
UIAttributes a;
a.setAttribute (UIViewCreator::kAttrClass, viewCreator.getViewName ());
return owned (factory->createView (a, nullptr));
}
} // anonymous
TEST_SUITE_SETUP (UIViewFactoryTest)
{
auto factory = makeOwned<UIViewFactory> ();
factory->registerViewCreator (baseViewCreator);
factory->registerViewCreator (viewCreator);
TEST_SUITE_SET_STORAGE (SharedPointer<UIViewFactory>, factory);
}
TEST_SUITE_TEARDOWN (UIViewFactoryTest)
{
auto& factory = TEST_SUITE_GET_STORAGE (SharedPointer<UIViewFactory>);
factory->unregisterViewCreator (baseViewCreator);
factory->unregisterViewCreator (viewCreator);
factory = nullptr;
}
TEST_CASE (UIViewFactoryTest, RegisterViewCreator)
{
auto& factory = TEST_SUITE_GET_STORAGE (SharedPointer<UIViewFactory>);
UIViewFactory::StringPtrList registeredViews;
factory->collectRegisteredViewNames (registeredViews);
auto found =
std::find_if (registeredViews.begin (), registeredViews.end (),
[&] (const std::string*& str) { return *str == viewCreator.getViewName (); });
EXPECT (found != registeredViews.end ());
}
TEST_CASE (UIViewFactoryTest, CollectFilteredViewNames)
{
auto& factory = TEST_SUITE_GET_STORAGE (SharedPointer<UIViewFactory>);
UIViewFactory::StringPtrList registeredViews;
factory->collectRegisteredViewNames (registeredViews, "BaseView");
EXPECT (registeredViews.size () == 1);
}
TEST_CASE (UIViewFactoryTest, CollectRegisteredViewAndDisplayNames)
{
auto& factory = TEST_SUITE_GET_STORAGE (SharedPointer<UIViewFactory>);
auto list = factory->collectRegisteredViewAndDisplayNames ();
auto it = std::find_if (list.begin (), list.end (),
[] (const auto& value) { return *value.first == "BaseView"; });
EXPECT (it != list.end ());
EXPECT (UTF8StringView (it->second) == UTF8StringView ("Base View"));
}
TEST_CASE (UIViewFactoryTest, CreateView)
{
auto& factory = TEST_SUITE_GET_STORAGE (SharedPointer<UIViewFactory>);
auto v = createView (factory);
EXPECT (v != nullptr);
EXPECT (v.cast<View> () != nullptr);
}
TEST_CASE (UIViewFactoryTest, CreateUnknownView)
{
auto& factory = TEST_SUITE_GET_STORAGE (SharedPointer<UIViewFactory>);
UIAttributes a;
a.setAttribute (UIViewCreator::kAttrClass, "Unknown");
auto view = owned (factory->createView (a, nullptr));
EXPECT (view == nullptr);
}
TEST_CASE (UIViewFactoryTest, ApplyAttributes)
{
auto& factory = TEST_SUITE_GET_STORAGE (SharedPointer<UIViewFactory>);
auto v = createView (factory);
auto view = v.cast<View> ();
EXPECT (view->value == 0);
UIAttributes a;
a.setIntegerAttribute (viewAttr, 1);
factory->applyAttributeValues (v, a, nullptr);
EXPECT (view->value == 1);
}
TEST_CASE (UIViewFactoryTest, GetAttributeValue)
{
auto& factory = TEST_SUITE_GET_STORAGE (SharedPointer<UIViewFactory>);
auto v = createView (factory);
std::string value;
factory->getAttributeValue (v, viewAttr, value, nullptr);
EXPECT (value == "0");
}
TEST_CASE (UIViewFactoryTest, GetAttributeNames)
{
auto& factory = TEST_SUITE_GET_STORAGE (SharedPointer<UIViewFactory>);
auto v = createView (factory);
UIViewFactory::StringList attributeNames;
EXPECT (factory->getAttributeNamesForView (v, attributeNames) == true);
EXPECT (attributeNames.size () == 2);
EXPECT (attributeNames.front () == viewAttr);
}
TEST_CASE (UIViewFactoryTest, GetAttributesForView)
{
auto& factory = TEST_SUITE_GET_STORAGE (SharedPointer<UIViewFactory>);
auto v = createView (factory);
UIAttributes a;
factory->getAttributesForView (v, nullptr, a);
EXPECT (a.hasAttribute (viewAttr) == true);
EXPECT (a.hasAttribute (baseViewAttr) == true);
}
TEST_CASE (UIViewFactoryTest, GetPossibleListValues)
{
auto& factory = TEST_SUITE_GET_STORAGE (SharedPointer<UIViewFactory>);
auto v = createView (factory);
UIViewFactory::StringPtrList values;
EXPECT (factory->getPossibleAttributeListValues (v, baseViewAttr, values) == true);
EXPECT (values.size () == 3);
}
TEST_CASE (UIViewFactoryTest, GetAttributeValueRange)
{
auto& factory = TEST_SUITE_GET_STORAGE (SharedPointer<UIViewFactory>);
auto v = createView (factory);
double minValue;
double maxValue;
EXPECT (factory->getAttributeValueRange (v, viewAttr, minValue, maxValue) == true);
EXPECT (minValue == -10.);
EXPECT (maxValue == 10.);
EXPECT (factory->getAttributeValueRange (v, baseViewAttr, minValue, maxValue) == false);
}
TEST_CASE (UIViewFactoryTest, DefaultViewCreation)
{
auto& factory = TEST_SUITE_GET_STORAGE (SharedPointer<UIViewFactory>);
UIAttributes a;
auto v = owned (factory->createView (a, nullptr));
EXPECT (v.cast<CViewContainer> ());
}
TEST_CASE (UIViewFactoryTest, ApplyCustomViewAttributes)
{
auto& factory = TEST_SUITE_GET_STORAGE (SharedPointer<UIViewFactory>);
auto view = owned (new CustomView ());
UIAttributes a;
a.setAttribute (baseViewAttr, "3");
EXPECT (factory->applyCustomViewAttributeValues (view, "TestView", a, nullptr));
EXPECT (view->baseState == BaseView::State::kState3);
}
} // VSTGUI
@@ -0,0 +1,118 @@
// This file is part of VSTGUI. It is subject to the license terms
// in the LICENSE file found in the top-level directory of this
// distribution and at http://github.com/steinbergmedia/vstgui/LICENSE
#include "../../../lib/controls/cbuttons.h"
#include "../../../lib/cstring.h"
#include "../../../uidescription/uiviewswitchcontainer.h"
#include "../unittests.h"
#include "uidescriptionadapter.h"
namespace VSTGUI {
struct View1 : public CView
{
View1 () : CView (CRect ()) {}
};
struct View2 : public CView
{
View2 () : CView (CRect ()) {}
};
struct View3 : public CView
{
View3 () : CView (CRect ()) { setAutosizeFlags (kAutosizeAll); }
};
struct TestUIDescription : public UIDescriptionAdapter
{
CView* createView (UTF8StringPtr name, IController* controller) const override
{
if (UTF8StringView (name) == "v1")
return new View1 ();
else if (UTF8StringView (name) == "v2")
return new View2 ();
else if (UTF8StringView (name) == "v3")
return new View3 ();
return nullptr;
}
};
TEST_CASE (UIDescriptionViewSwitchControllerTest, SwitchViaIndex)
{
TestUIDescription uiDesc;
auto rootView = owned (new CViewContainer (CRect (0, 0, 100, 100)));
auto container = owned (new CViewContainer (CRect (0, 0, 100, 100)));
auto viewSwitch = new UIViewSwitchContainer (CRect (0, 0, 100, 100));
viewSwitch->setAnimationTime (0);
auto controller = new UIDescriptionViewSwitchController (viewSwitch, &uiDesc, nullptr);
controller->setTemplateNames ("v1,v2");
EXPECT (container->addView (viewSwitch));
container->attached (rootView);
EXPECT (viewSwitch->getView (0) == nullptr);
viewSwitch->setCurrentViewIndex (0);
EXPECT (dynamic_cast<View1*> (viewSwitch->getView (0)));
viewSwitch->setCurrentViewIndex (1);
EXPECT (dynamic_cast<View2*> (viewSwitch->getView (0)));
container->removed (rootView);
}
TEST_CASE (UIDescriptionViewSwitchControllerTest, SwitchViaControl)
{
TestUIDescription uiDesc;
auto rootView = owned (new CViewContainer (CRect (0, 0, 100, 100)));
auto container = owned (new CViewContainer (CRect (0, 0, 100, 100)));
auto viewSwitch = new UIViewSwitchContainer (CRect (0, 0, 100, 100));
viewSwitch->setAnimationTime (0);
auto control = new COnOffButton (CRect (0, 0, 0, 0));
control->setTag (1);
auto controller = new UIDescriptionViewSwitchController (viewSwitch, &uiDesc, nullptr);
controller->setTemplateNames ("v1,v2");
controller->setSwitchControlTag (1);
EXPECT (container->addView (control));
EXPECT (container->addView (viewSwitch));
container->attached (rootView);
EXPECT (dynamic_cast<View1*> (viewSwitch->getView (0)));
control->setValue (1.f);
control->valueChanged ();
EXPECT (dynamic_cast<View2*> (viewSwitch->getView (0)));
container->removed (rootView);
}
TEST_CASE (UIDescriptionViewSwitchControllerTest, AutosizeAll)
{
TestUIDescription uiDesc;
auto rootView = owned (new CViewContainer (CRect (0, 0, 100, 100)));
auto container = owned (new CViewContainer (CRect (0, 0, 100, 100)));
auto viewSwitch = new UIViewSwitchContainer (CRect (0, 0, 100, 100));
auto controller = new UIDescriptionViewSwitchController (viewSwitch, &uiDesc, nullptr);
controller->setTemplateNames ("v3");
EXPECT (container->addView (viewSwitch));
container->attached (rootView);
EXPECT (viewSwitch->getView (0) == nullptr);
viewSwitch->setCurrentViewIndex (0);
auto view = viewSwitch->getView (0);
EXPECT (dynamic_cast<View3*> (view));
EXPECT (view->getViewSize () == container->getViewSize ());
container->removed (rootView);
}
TEST_CASE (UIDescriptionViewSwitchControllerTest, NoAnimation)
{
TestUIDescription uiDesc;
auto rootView = owned (new CViewContainer (CRect (0, 0, 100, 100)));
auto container = owned (new CViewContainer (CRect (0, 0, 100, 100)));
auto viewSwitch = new UIViewSwitchContainer (CRect (0, 0, 100, 100));
viewSwitch->setAnimationTime (0);
auto controller = new UIDescriptionViewSwitchController (viewSwitch, &uiDesc, nullptr);
controller->setTemplateNames ("v1");
EXPECT (container->addView (viewSwitch));
container->attached (rootView);
EXPECT (viewSwitch->getView (0) == nullptr);
viewSwitch->setCurrentViewIndex (0);
EXPECT (dynamic_cast<View1*> (viewSwitch->getView (0)));
container->removed (rootView);
}
} // VSTGUI
@@ -0,0 +1,95 @@
// This file is part of VSTGUI. It is subject to the license terms
// in the LICENSE file found in the top-level directory of this
// distribution and at http://github.com/steinbergmedia/vstgui/LICENSE
#include "../unittests.h"
#if VSTGUI_ENABLE_XML_PARSER
#include "../../../uidescription/uicontentprovider.h"
#include "../../../uidescription/xmlparser.h"
#include <string>
namespace VSTGUI {
using namespace Xml;
namespace {
struct Handler : public IHandler
{
bool stopOnStartElement {false};
void startXmlElement (Parser* parser, IdStringPtr elementName,
UTF8StringPtr* elementAttributes) override
{
if (stopOnStartElement)
parser->stop ();
}
void endXmlElement (Parser* parser, IdStringPtr name) override {}
void xmlCharData (Parser* parser, const int8_t* data, int32_t length) override {}
void xmlComment (Parser* parser, IdStringPtr comment) override {}
};
} // anonymous
constexpr auto validXML =
R"(<?xml version="1.0" encoding="UTF-8"?>
<tag attr="bla">
CHARDATA
<!-- comment -->
</tag>
)";
constexpr auto validXMLWithJunkAtEnd =
R"(<?xml version="1.0" encoding="UTF-8"?>
<tag attr="bla">
CHARDATA
<!-- comment -->
</tag>
this is junk
)";
constexpr auto invalidXML =
R"(
<tag attr="bla">
CHARDATA
<!-- comment -->
</tag2>
)";
TEST_CASE (XMLParserTest, ValidParse)
{
MemoryContentProvider provider (validXML, static_cast<uint32_t> (strlen (validXML)));
Handler handler;
Parser p;
EXPECT (p.parse (&provider, &handler) == true);
}
TEST_CASE (XMLParserTest, ValidParseWithJunkAtEnd)
{
MemoryContentProvider provider (validXMLWithJunkAtEnd,
static_cast<uint32_t> (strlen (validXMLWithJunkAtEnd)));
Handler handler;
Parser p;
EXPECT (p.parse (&provider, &handler) == true);
}
TEST_CASE (XMLParserTest, InvalidParse)
{
MemoryContentProvider provider (invalidXML, static_cast<uint32_t> (strlen (invalidXML)));
Handler handler;
Parser p;
EXPECT (p.parse (&provider, &handler) == false);
}
TEST_CASE (XMLParserTest, StopParse)
{
MemoryContentProvider provider (validXML, static_cast<uint32_t> (strlen (validXML)));
Handler handler;
handler.stopOnStartElement = true;
Parser p;
EXPECT (p.parse (&provider, &handler) == false);
}
} // VSTGUI
#endif // VSTGUI_ENABLE_XML_PARSER
@@ -0,0 +1,192 @@
// This file is part of VSTGUI. It is subject to the license terms
// in the LICENSE file found in the top-level directory of this
// distribution and at http://github.com/steinbergmedia/vstgui/LICENSE
#include "unittests.h"
#if ENABLE_UNIT_TESTS
#include "../../lib/vstguidebug.h"
#include "../../lib/vstguiinit.h"
#include "../../lib/cstring.h"
#include <chrono>
#include <cstdarg>
#include <cstdio>
#if MAC
#include <CoreFoundation/CoreFoundation.h>
#endif
#if WINDOWS
#ifndef NOMINMAX
#define NOMINMAX
#endif
#include <windows.h>
#include <objbase.h>
#endif
//------------------------------------------------------------------------
namespace VSTGUI {
namespace UnitTest {
using namespace std::chrono;
//----------------------------------------------------------------------------------------------------
//----------------------------------------------------------------------------------------------------
//----------------------------------------------------------------------------------------------------
class StdOutContext : public Context
{
private:
struct Result {
int succeded;
int failed;
Result () : succeded (0), failed (0) {}
Result& operator +=(const Result& r) { succeded += r.succeded; failed += r.failed; return *this; }
};
public:
StdOutContext () : intend (0) {}
void printRaw (const char* str) override
{
testOutput += str;
testOutput += "\n";
}
void printOutput ()
{
if (testOutput.empty () == false)
{
printf ("%s", testOutput.c_str ());
testOutput = "";
}
}
void printIntend ()
{
for (int i = 0; i < intend; i++) printf ("\t");
}
Result runTestSuite (const TestSuite& testSuite)
{
currentTestSuite = &testSuite;
Result result;
printf ("%s\n", testSuite.getName ().c_str());
intend++;
for (auto& it : testSuite)
{
try {
if (testSuite.setup ())
{
testSuite.setup () (this);
}
if (runTest (it.first, it.second))
{
result.succeded++;
}
else
{
result.failed++;
}
if (testSuite.teardown ())
{
testSuite.teardown () (this);
}
} catch (const std::exception&)
{
result.failed++;
}
}
intend--;
return result;
}
bool runTest (const std::string& testName, const TestFunction& f)
{
time_point<system_clock> start, end;
printIntend ();
printf ("%s", testName.c_str());
intend++;
start = system_clock::now ();
bool result = true;
try {
f (this);
} catch (const error& exc)
{
result = false;
print ("%s", exc.what () ? exc.what () : "unknown");
} catch (const std::exception& exc)
{
result = false;
printf ("Exception: %s", exc.what () ? exc.what () : "unknown");
}
end = system_clock::now ();
intend--;
printf (" [%s] -> %lld µs\n", result ? "OK" : "Failed", duration_cast<microseconds> (end-start).count ());
printOutput ();
return result;
}
int run ()
{
Result result;
time_point<system_clock> start, end;
start = system_clock::now ();
for (auto& it : UnitTestRegistry::instance ())
{
result += runTestSuite (it);
}
end = system_clock::now ();
print ("\nDone running %d tests in %lldms. [%d Failed]\n", result.succeded+result.failed, duration_cast<milliseconds> (end-start).count (), result.failed);
printOutput ();
return result.failed;
}
std::any& storage () override
{
return currentTestSuite->getStorage ();
}
private:
int intend;
std::string testOutput;
const TestSuite* currentTestSuite {nullptr};
};
static int RunTests ()
{
StdOutContext context;
return context.run ();
}
//------------------------------------------------------------------------
} // UnitTest
} // VSTGUI
int main ()
{
VSTGUI::setAssertionHandler (
[] (const char* file, const char* line, const char* condition, const char* desc) {
size_t lineNo = 0;
if (line)
{
if (auto l = VSTGUI::UTF8StringView (line).toNumber<size_t> ())
lineNo = *l;
}
throw VSTGUI::UnitTest::error (file, lineNo, desc ? desc : condition);
});
#if MAC
VSTGUI::init (CFBundleGetMainBundle ());
#elif WINDOWS
CoInitialize (nullptr);
VSTGUI::init (GetModuleHandle (nullptr));
#elif LINUX
VSTGUI::init (nullptr);
#endif
auto result = VSTGUI::UnitTest::RunTests ();
VSTGUI::exit ();
return result;
}
#endif
@@ -0,0 +1,196 @@
// This file is part of VSTGUI. It is subject to the license terms
// in the LICENSE file found in the top-level directory of this
// distribution and at http://github.com/steinbergmedia/vstgui/LICENSE
#include "unittests.h"
#if ENABLE_UNIT_TESTS
#include "../../lib/vstguidebug.h"
#include "../../lib/vstguiinit.h"
#include <chrono>
#include <cstdarg>
#include <cstdio>
#if WINDOWS
#ifndef NOMINMAX
#define NOMINMAX
#endif
#include <windows.h>
#include <objbase.h>
#endif
namespace VSTGUI {
namespace UnitTest {
#if WINDOWS
static void printf (const char* fmt, ...)
{
va_list args;
va_start (args, fmt);
auto numBytes = vsnprintf (nullptr, 0, fmt, args);
if (numBytes <= 0)
return;
numBytes++;
auto buffer = new char[numBytes];
if (vsnprintf (buffer, numBytes, fmt, args) > 0)
{
if (IsDebuggerPresent ())
OutputDebugStringA (buffer);
else
::printf_s ("%s", buffer);
}
delete[] buffer;
}
#endif
//----------------------------------------------------------------------------------------------------
//----------------------------------------------------------------------------------------------------
//----------------------------------------------------------------------------------------------------
TestSuite::TestSuite (std::string&& name, TestSuiteFunction&& testCase)
: name (name)
{
tcf = std::move (testCase);
tcf (this);
}
//----------------------------------------------------------------------------------------------------
TestSuite::TestSuite (TestSuite&& tc) noexcept
{
*this = std::move (tc);
}
//----------------------------------------------------------------------------------------------------
TestSuite& TestSuite::operator=(TestSuite &&tc) noexcept
{
name = std::move (tc.name);
tests = std::move (tc.tests);
tcf = std::move (tc.tcf);
setupFunction = std::move (tc.setupFunction);
teardownFunction = std::move (tc.teardownFunction);
storage = std::move (tc.storage);
return *this;
}
//----------------------------------------------------------------------------------------------------
void TestSuite::registerTest (std::string&& testName, TestFunction&& testFunction)
{
tests.emplace_back (std::move (testName), std::move (testFunction));
}
//----------------------------------------------------------------------------------------------------
void TestSuite::setSetupFunction (SetupFunction&& _setupFunction)
{
setupFunction = std::move (_setupFunction);
}
//----------------------------------------------------------------------------------------------------
void TestSuite::setTeardownFunction (TeardownFunction&& _teardownFunction)
{
teardownFunction = std::move (_teardownFunction);
}
//----------------------------------------------------------------------------------------------------
void TestSuite::setStorage (std::any&& s)
{
storage = std::move (s);
}
//----------------------------------------------------------------------------------------------------
//----------------------------------------------------------------------------------------------------
//----------------------------------------------------------------------------------------------------
UnitTestRegistry& UnitTestRegistry::instance ()
{
static UnitTestRegistry gUnitTestRegistry;
return gUnitTestRegistry;
}
//----------------------------------------------------------------------------------------------------
void UnitTestRegistry::registerTestSuite (TestSuite&& testCase)
{
testSuites.push_back (std::move (testCase));
}
//------------------------------------------------------------------------
TestSuite* UnitTestRegistry::find (const std::string& name)
{
auto it = std::find_if (testSuites.begin (), testSuites.end (),
[&name] (auto& tc) { return tc.getName () == name; });
if (it == testSuites.end ())
return nullptr;
return &(*it);
}
//------------------------------------------------------------------------
TestRegistrar::TestRegistrar (std::string&& suite, TestSuiteFunction&& testCase)
{
UnitTestRegistry::instance ().registerTestSuite (
TestSuite (std::move (suite), std::move (testCase)));
}
//------------------------------------------------------------------------
TestRegistrar::TestRegistrar (std::string&& suite, std::string&& testName, TestFunction&& testFunction)
{
auto& registry = UnitTestRegistry::instance ();
if (auto tc = registry.find (suite))
{
tc->registerTest (std::move (testName), std::move (testFunction));
}
else
{
TestSuite ts (std::move (suite), [] (auto) {});
ts.registerTest (std::move (testName), std::move (testFunction));
registry.registerTestSuite (std::move (ts));
}
}
//----------------------------------------------------------------------------------------------------
TestRegistrar::TestRegistrar (std::string&& suite, SetupFunction&& sotFunction, bool isSetupFunc)
{
auto& registry = UnitTestRegistry::instance ();
if (auto tc = registry.find (suite))
{
if (isSetupFunc)
tc->setSetupFunction (std::move (sotFunction));
else
tc->setTeardownFunction (std::move (sotFunction));
}
else
{
TestSuite ts (std::move (suite), [] (auto) {});
if (isSetupFunc)
ts.setSetupFunction (std::move (sotFunction));
else
ts.setTeardownFunction (std::move (sotFunction));
registry.registerTestSuite (std::move (ts));
}
}
//----------------------------------------------------------------------------------------------------
void Context::print (const char* fmt, ...)
{
va_list args;
va_start (args, fmt);
#if WINDOWS
auto numBytes = vsnprintf(nullptr, 0, fmt, args);
if (numBytes <= 0)
return;
auto buffer = new char[numBytes];
if (vsnprintf(buffer, numBytes, fmt, args) > 0)
printRaw (buffer);
delete[] buffer;
#else
char* str = nullptr;
if (vasprintf (&str, fmt, args) >= 0 && str != nullptr)
{
printRaw (str);
std::free (str);
}
#endif
}
}} // namespaces
#endif
@@ -0,0 +1,213 @@
// This file is part of VSTGUI. It is subject to the license terms
// in the LICENSE file found in the top-level directory of this
// distribution and at http://github.com/steinbergmedia/vstgui/LICENSE
#pragma once
#if ENABLE_UNIT_TESTS
#include "../../lib/vstguifwd.h"
#include <string>
#include <string_view>
#include <list>
#include <functional>
#include <cstdio>
#include <cstdlib>
#include <stdexcept>
#include <any>
/** @page How-to write tests
How-to write tests:
1) include this file
2) optional: put the test code into namespaces: namespace VSTGUI { namespace UnitTest {
3) write tests with the function macro TEST_CASE(SuiteName, TestName) { TESTCODE }
Simple Example:
#include "unittests.h"
TEST_CASE (Example, OnePlusOneIsTwo)
{
auto result = 1+1;
EXPECT_EQ (result, 2)
}
Using a setup and teardown function and custom variable storage:
#include "unittests.h"
TEST_SUITE_SETUP (CViewContainerTest)
{
SharedPointer<CViewContainer> container = makeOwned<CViewContainer> (CRect (0, 0, 200, 200));
TEST_SUITE_SET_STORAGE (SharedPointer<CViewContainer>, container);
}
TEST_SUITE_TEARDOWN (CViewContainerTest)
{
TEST_SUITE_GET_STORAGE (SharedPointer<CViewContainer>) = nullptr;
}
TEST_CASE (CViewContainerTest, ChangeViewZOrder)
{
SharedPointer<CViewContainer>& container = TEST_SUITE_GET_STORAGE (SharedPointer<CViewContainer>);
...
}
*/
namespace VSTGUI {
namespace UnitTest {
//----------------------------------------------------------------------------------------------------
class error : public std::logic_error
{
public:
error (const char* file, size_t line, const char* str)
: std::logic_error (str), filePath (file), lineNo (line)
{
}
std::string filePath;
size_t lineNo;
};
#define VSTGUI_UNITTEST_MAKE_STRING_PRIVATE_DONT_USE(x) # x
#define VSTGUI_UNITTEST_MAKE_STRING(x) VSTGUI_UNITTEST_MAKE_STRING_PRIVATE_DONT_USE(x)
//----------------------------------------------------------------------------------------------------
#define TEST_CASE(suite, name) \
static void test##suite##name (VSTGUI::UnitTest::Context* context); \
static VSTGUI::UnitTest::TestRegistrar register##suite##name (VSTGUI_UNITTEST_MAKE_STRING(suite), \
VSTGUI_UNITTEST_MAKE_STRING(name), [](VSTGUI::UnitTest::Context* context) {\
test##suite##name (context); \
});\
void test##suite##name (VSTGUI::UnitTest::Context* context)
#define TEST_SUITE_SETUP(suite) \
static void setup##suite (VSTGUI::UnitTest::Context* context); \
static VSTGUI::UnitTest::TestRegistrar registerSetup##suite (VSTGUI_UNITTEST_MAKE_STRING(suite), \
[](VSTGUI::UnitTest::Context* context) { setup##suite (context); }, true);\
void setup##suite (VSTGUI::UnitTest::Context* context)
#define TEST_SUITE_TEARDOWN(suite) \
static void teardown##suite (VSTGUI::UnitTest::Context* context); \
static VSTGUI::UnitTest::TestRegistrar registerTeardown##suite (VSTGUI_UNITTEST_MAKE_STRING(suite), \
[](VSTGUI::UnitTest::Context* context) { teardown##suite (context); }, false);\
void teardown##suite (VSTGUI::UnitTest::Context* context)
#define TEST_SUITE_SET_STORAGE(Type, value) context->storage () = std::make_any<Type> (value)
#define TEST_SUITE_GET_STORAGE(Type) *std::any_cast<Type> (&context->storage ())
//----------------------------------------------------------------------------------------------------
#define EXPECT(condition) if (!(condition)) { throw VSTGUI::UnitTest::error (__FILE__, __LINE__, "Expected: " VSTGUI_UNITTEST_MAKE_STRING(condition)); }
#define FAIL(reason) { throw VSTGUI::UnitTest::error (__FILE__, __LINE__, "Failure: " reason); }
#define EXPECT_EXCEPTION(call, name) \
{ \
bool b = false; \
try \
{ \
call; \
} \
catch (const std::exception& error) \
{ \
EXPECT (std::string_view (error.what ()) == std::string_view (name)); \
b = true; \
} \
EXPECT (b); \
}
#define EXPECT_TRUE(condition) EXPECT(condition)
#define EXPECT_FALSE(condition) EXPECT(!condition)
#define EXPECT_EQ(var1, var2) EXPECT ((var1) == (var2))
#define EXPECT_NE(var1, var2) EXPECT ((var1) != (var2))
//----------------------------------------------------------------------------------------------------
class Context;
class TestSuite;
//----------------------------------------------------------------------------------------------------
using TestFunction = std::function<void(Context*)>;
using SetupFunction = std::function<void(Context*)>;
using TeardownFunction = std::function<void(Context*)>;
using TestSuiteFunction = std::function<void(TestSuite*)>;
//----------------------------------------------------------------------------------------------------
class UnitTestRegistry
{
using TestSuites = std::list<TestSuite>;
using Iterator = TestSuites::const_iterator;
public:
static UnitTestRegistry& instance ();
void registerTestSuite (TestSuite&& testSuite);
Iterator begin () const { return testSuites.begin (); }
Iterator end () const { return testSuites.end (); }
TestSuite* find (const std::string& name);
private:
TestSuites testSuites;
};
//----------------------------------------------------------------------------------------------------
class TestSuite
{
using TestPair = std::pair<std::string, TestFunction>;
using Tests = std::list<TestPair>;
using Iterator = Tests::const_iterator;
public:
TestSuite (std::string&& name, TestSuiteFunction&& testCase);
TestSuite (TestSuite&& tc) noexcept;
void setSetupFunction (SetupFunction&& setupFunction);
void setTeardownFunction (TeardownFunction&& teardownFunction);
void setStorage (std::any&& s);
void registerTest (std::string&& name, TestFunction&& function);
const std::string& getName () const { return name; }
std::any& getStorage () const { return storage; }
Iterator begin () const { return tests.begin (); }
Iterator end () const { return tests.end (); }
const SetupFunction& setup () const { return setupFunction; }
const TeardownFunction& teardown () const { return teardownFunction; }
TestSuite& operator= (TestSuite&& tc) noexcept;
private:
Tests tests;
std::string name;
TestSuiteFunction tcf;
SetupFunction setupFunction;
TeardownFunction teardownFunction;
mutable std::any storage;
};
//----------------------------------------------------------------------------------------------------
class TestRegistrar
{
public:
TestRegistrar (std::string&& suite, TestSuiteFunction&& testSuite);
TestRegistrar (std::string&& suite, std::string&& testName, TestFunction&& testFunction);
TestRegistrar (std::string&& suite, SetupFunction&& setupFunction, bool isSetupFunc = true);
};
//----------------------------------------------------------------------------------------------------
class Context
{
public:
void print (const char* fmt, ...);
virtual void printRaw (const char* str) = 0;
virtual std::any& storage () = 0;
};
}} // namespaces
#else
#define TESTCASE(x,y)
#endif
@@ -0,0 +1,176 @@
// This file is part of VSTGUI. It is subject to the license terms
// in the LICENSE file found in the top-level directory of this
// distribution and at http://github.com/steinbergmedia/vstgui/LICENSE
#import <XCTest/XCTest.h>
#import <objc/message.h>
#import <objc/runtime.h>
#import "../../lib/cstring.h"
#import "../../lib/vstguiinit.h"
#import "unittests.h"
#import <functional>
#import <string>
#import <unordered_map>
#import <vector>
using namespace VSTGUI::UnitTest;
//------------------------------------------------------------------------
void setupFunc (id self, SEL _cmd)
{
auto cls = [self class];
std::string clsName (class_getName (cls) + 7);
auto testSuite = UnitTestRegistry::instance ().find (clsName);
assert (testSuite);
auto ivar = class_getInstanceVariable ([self class], "_testSuite");
object_setIvar (self, ivar, reinterpret_cast<id> (testSuite));
}
//------------------------------------------------------------------------
void testFunc (id self, SEL _cmd)
{
auto ivar = class_getInstanceVariable ([self class], "_testSuite");
auto testSuite = reinterpret_cast<TestSuite*> (object_getIvar (self, ivar));
auto name = std::string (sel_getName (_cmd) + 4);
auto it = std::find_if (testSuite->begin (), testSuite->end (),
[&] (auto& pair) { return pair.first == name; });
assert (it != testSuite->end ());
struct TestContext : Context
{
TestContext (TestSuite& suite) : suite (suite) {}
void printRaw (const char* str) override { text += str; }
std::any& storage () override { return suite.getStorage (); }
TestSuite& suite;
std::string text;
} context (*testSuite);
size_t assertLineNo = 0;
std::string assertFilePath;
bool result = true;
try
{
if (auto setup = testSuite->setup ())
setup (&context);
try
{
it->second (&context);
}
catch (...)
{
if (auto teardown = testSuite->teardown ())
teardown (&context);
throw;
}
if (auto teardown = testSuite->teardown ())
teardown (&context);
}
catch (const error& exc)
{
result = false;
context.print ("%s", exc.what () ? exc.what () : "unknown");
assertLineNo = exc.lineNo;
assertFilePath = exc.filePath;
}
catch (const std::logic_error& exc)
{
result = false;
context.print ("%s", exc.what () ? exc.what () : "unknown");
}
catch (const std::exception& exc)
{
result = false;
context.print ("Exception: %s", exc.what () ? exc.what () : "unknown");
}
if (!result)
{
#ifdef MAC_OS_VERSION_11_0
auto sourceCodeLocation = [[[XCTSourceCodeLocation alloc]
initWithFilePath:[NSString stringWithUTF8String:assertFilePath.data ()]
lineNumber:assertLineNo] autorelease];
auto sourceCodeContext =
[[[XCTSourceCodeContext alloc] initWithLocation:sourceCodeLocation] autorelease];
auto issue =
[[[XCTIssue alloc] initWithType:XCTIssueTypeAssertionFailure
compactDescription:[NSString stringWithUTF8String:context.text.data ()]
detailedDescription:nullptr
sourceCodeContext:sourceCodeContext
associatedError:nullptr
attachments:@[]] autorelease];
[self recordIssue:issue];
#else
[self recordFailureWithDescription:[NSString stringWithUTF8String:context.text.data ()]
inFile:[NSString stringWithUTF8String:assertFilePath.data ()]
atLine:assertLineNo
expected:NO];
#endif
}
}
//------------------------------------------------------------------------
@interface VSTGUITestCaseFactory : XCTestCase
@end
@implementation VSTGUITestCaseFactory
//------------------------------------------------------------------------
+ (void)initialize
{
VSTGUI::setAssertionHandler (
[] (const char* file, const char* line, const char* condition, const char* desc) {
size_t lineNo = 0;
if (line)
{
if (auto l = VSTGUI::UTF8StringView (line).toNumber<size_t> ())
lineNo = *l;
}
std::string text;
if (desc)
{
text = desc;
}
else
{
text = "Assertion: '";
text += condition;
text += "' failed.";
}
throw VSTGUI::UnitTest::error (file, lineNo, text.data ());
});
VSTGUI::init (CFBundleGetMainBundle ());
auto baseClass = objc_getClass ("XCTestCase");
for (auto& testCase : UnitTestRegistry::instance ())
{
std::string className = "VSTGUI_" + testCase.getName ();
auto cls = objc_allocateClassPair (baseClass, className.data (), 0);
if (!cls)
{
NSLog (@"Duplicate TestCase name: %s", testCase.getName ().data ());
continue;
}
class_addIvar (cls, "_testSuite", sizeof (void*), (uint8_t)log2 (sizeof (void*)),
@encode (void*));
class_addMethod (cls, @selector (setUp), reinterpret_cast<IMP> (setupFunc), "v@:");
for (auto& test : testCase)
{
std::string name = "test" + test.first;
auto sel = sel_registerName (name.data ());
if (!class_addMethod (cls, sel, reinterpret_cast<IMP> (testFunc), "v@:"))
{
NSLog (@"Duplicate Method name: %s [%s]", name.data (), className.data ());
}
}
objc_registerClassPair (cls);
}
}
@end