polybar-3.7.2/0000755000175100001770000000000014660106015012537 5ustar runnerdockerpolybar-3.7.2/contrib/0000755000175100001770000000000014660106013014175 5ustar runnerdockerpolybar-3.7.2/contrib/vim/0000755000175100001770000000000014660106013014770 5ustar runnerdockerpolybar-3.7.2/contrib/vim/ftplugin/0000755000175100001770000000000014660106013016620 5ustar runnerdockerpolybar-3.7.2/contrib/vim/ftplugin/cpp.vim0000644000175100001770000000047314660106013020123 0ustar runnerdocker" Swap between source/header nnoremap af :call ft#cpphpp#Swap('edit') nnoremap as :call ft#cpphpp#Swap('new') nnoremap av :call ft#cpphpp#Swap('vnew') " Code formatting using clang-format set formatprg=/usr/bin/clang-format nmap :ClangFormat polybar-3.7.2/contrib/vim/ftplugin/dosini.vim0000644000175100001770000000056214660106013020625 0ustar runnerdocker" " Enables syntax folding for the configuration file. " Removes the need to clutter the file with fold markers. " " Put the file in $VIM/after/syntax/dosini.vim " syn region dosiniSection start="^\[" end="\(\n\+\[\)\@=" contains=dosiniLabel,dosiniHeader,dosiniComment keepend fold setlocal foldmethod=syntax " Uncomment to start with folds open "setlocal foldlevel=20 polybar-3.7.2/contrib/vim/autoload/0000755000175100001770000000000014660106013016600 5ustar runnerdockerpolybar-3.7.2/contrib/vim/autoload/ft/0000755000175100001770000000000014660106013017211 5ustar runnerdockerpolybar-3.7.2/contrib/vim/autoload/ft/cpphpp.vim0000644000175100001770000000076314660106013021226 0ustar runnerdocker" " Get the filename of the swap file " func! ft#cpphpp#GetFilename() let ext = expand('%:e') let root = expand('%:p:r') if (ext == 'cpp') return fnameescape(substitute(root, '\(src/.*/\)\?src/', '\1include/', '') . '.hpp') elseif (ext == 'hpp') return fnameescape(substitute(root, '\(include/.*/\)\?include/', '\1src/', '') . '.cpp') endif endfunc " " Swap between source/header using given cmd " func! ft#cpphpp#Swap(cmd) execute a:cmd . ' ' . ft#cpphpp#GetFilename() endfunc polybar-3.7.2/contrib/zsh/0000755000175100001770000000000014660106013015001 5ustar runnerdockerpolybar-3.7.2/contrib/zsh/_polybar0000644000175100001770000000433114660106013016534 0ustar runnerdocker#compdef polybar # # Completion for polybar (https://github.com/polybar/polybar) # jaagr # _polybar() { local L='-l --log' local Q='-q --quiet' local C='-c --config' local R='-r --reload' local D='-d --dump' local M='-m --list-monitors' local MM='-M --list-all-monitors' local W='-w --print-wmname' local S='-s --stdout' _arguments -n : \ '(-)'{-h,--help}'[Display help text and exit]' \ '(-)'{-v,--version}'[Display build details and exit]' \ "($L $Q)"{-l,--log=}'[Set the logging verbosity (default: notice)]:verbosity level:(error warning notice info trace)' \ "($L $Q)"{-q,--quiet}'[Be quiet (will override -l)]' \ "($C)"{-c,--config=}'[Path to the configuration file]:configuration file:_files' \ "($R)"{-r,--reload}'[Reload when the configuration has been modified]' \ "($D $R $M $W $S)"{-d,--dump=}'[Print parameter value in bar section and exit]:parameter name' \ "($MM $M $D $R $W $S)"{-m,--list-monitors}'[Print list of available monitors (Excluding cloned monitors) and exit]' \ "($MM $M $D $R $W $S)"{-M,--list-all-monitors}'[Print list of all available monitors (Including cloned monitors) and exit]' \ "($W $R $D $M $S)"{-w,--print-wmname}'[Print the generated WM_NAME and exit]' \ "($S)"{-s,--stdout}'[Output data to stdout instead of drawing the X window]' \ '::bar name:_polybar_list_names' } (( $+functions[_polybar_default_file] )) || _polybar_default_file() { local suffix=/polybar/config.ini local home_path=${XDG_CONFIG_HOME:-$HOME/.config}${suffix} local etc_xdg_path=${XDG_CONFIG_DIRS:-/etc/xdg}${suffix} local etc_path=/etc${suffix} if [ -r "$home_path" ]; then echo "$home_path" elif [ -r "$etc_xdg_path" ]; then echo "$etc_xdg_path" elif [ -r "$etc_path" ]; then echo "$etc_path" fi } (( $+functions[_polybar_list_names] )) || _polybar_list_names() { local conf if (( $+opt_args[-c] )); then conf=${(e)opt_args[-c]} elif (( $+opt_args[--config] )); then conf=${(e)opt_args[--config]} else conf=$(_polybar_default_file) fi local names; names=(${(f)"$(sed -nE 's|[[:space:]]*\[bar/([^\]+)\][[:space:]]*$|\1|p' ${conf} 2>/dev/null)"}) _describe -t names 'configuration name' names } _polybar "$@" polybar-3.7.2/contrib/zsh/_polybar_msg0000644000175100001770000000147414660106013017407 0ustar runnerdocker#compdef polybar-msg # # Completion for polybar-msg (https://github.com/polybar/polybar) # jaagr # _polybar_msg() { integer ret=1 _arguments -n : \ '-p[Process id of target instance]:process id:_polybar_msg_pids' \ '(-p)1:message type:(action cmd hook)' \ '*:: :->args' case $state in args) case $words[1] in hook) _arguments ':module name:' ':hook index:'; ret=0 ;; action) _arguments ':action payload:'; ret=0 ;; cmd) _arguments ':command payload:(show hide toggle restart quit)'; ret=0 ;; esac ;; esac return $ret } (( $+functions[_polybar_msg_pids] )) || _polybar_msg_pids() { local pids; pids=(${(f)"$(ls -1 /tmp/polybar_mqueue.* | egrep -o '[0-9]+$')"}) _describe -t pids 'process id of target instance' pids } _polybar_msg "$@" polybar-3.7.2/contrib/zsh/CMakeLists.txt0000644000175100001770000000021714660106013017541 0ustar runnerdocker# # Zsh completion template # install(FILES _polybar _polybar_msg DESTINATION ${CMAKE_INSTALL_DATADIR}/zsh/site-functions COMPONENT tools) polybar-3.7.2/contrib/polybar-git.aur/0000755000175100001770000000000014660106013017214 5ustar runnerdockerpolybar-3.7.2/contrib/polybar-git.aur/PKGBUILD0000644000175100001770000000255514660106013020347 0ustar runnerdocker# Maintainer: Patrick Ziegler _pkgname=polybar pkgname="${_pkgname}-git" pkgver=3.6.3 pkgrel=1 pkgdesc="A fast and easy-to-use status bar" # aarch64 is not officially supported by polybar, it is only listed here for convenience arch=("i686" "x86_64" "aarch64") url="https://github.com/polybar/polybar" license=("MIT") depends=("libuv" "cairo" "xcb-util-image" "xcb-util-wm" "xcb-util-xrm" "xcb-util-cursor" "alsa-lib" "libpulse" "libmpdclient" "libnl" "jsoncpp" "curl") optdepends=("i3-wm: i3 module support") makedepends=("cmake" "git" "python" "pkg-config" "python-sphinx" "python-packaging" "i3-wm") backup=("etc/polybar/config.ini") provides=("polybar") conflicts=("polybar") source=("${_pkgname}::git+${url}.git") sha256sums=("SKIP") pkgver() { git -C "${_pkgname}" describe --long --tags | sed "s/-/.r/;s/-/./g" } prepare() { git -C "${_pkgname}" submodule update --init --recursive mkdir -p "${_pkgname}/build" } build() { cd "${_pkgname}/build" || exit 1 # Force cmake to use system python (to detect xcbgen) cmake -DCMAKE_INSTALL_PREFIX=/usr -DCMAKE_BUILD_TYPE=Release -DPYTHON_EXECUTABLE=/usr/bin/python3 .. cmake --build . } package() { cmake --build "${_pkgname}/build" --target install -- DESTDIR="${pkgdir}" install -Dm644 "${_pkgname}/LICENSE" "${pkgdir}/usr/share/licenses/${_pkgname}/LICENSE" } polybar-3.7.2/contrib/bash/0000755000175100001770000000000014660106013015112 5ustar runnerdockerpolybar-3.7.2/contrib/bash/CMakeLists.txt0000644000175100001770000000021314660106013017646 0ustar runnerdocker# # Bash completion template # install(FILES polybar DESTINATION ${CMAKE_INSTALL_DATADIR}/bash-completion/completions COMPONENT tools) polybar-3.7.2/contrib/bash/polybar0000644000175100001770000000433314660106013016510 0ustar runnerdocker_polybar_default_file() { local suffix=/polybar/config.ini local home_path=${XDG_CONFIG_HOME:-$HOME/.config}${suffix} local etc_xdg_path=${XDG_CONFIG_DIRS:-/etc/xdg}${suffix} local etc_path=/etc${suffix} if [ -r "$home_path" ]; then echo "$home_path" elif [ -r "$etc_xdg_path" ]; then echo "$etc_xdg_path" elif [ -r "$etc_path" ]; then echo "$etc_path" fi } _polybar_config_file() { for ((i = 0; i < COMP_CWORD; i++)); do case ${COMP_WORDS[i]} in --config) echo "${COMP_WORDS[i + 2]}" return ;; -c) echo "${COMP_WORDS[i + 1]}" return ;; esac done _polybar_default_file } _polybar_bars() { local config_file=$(_polybar_config_file) if [ -r "$config_file" ]; then sed -nE 's|[[:space:]]*\[bar/([^\]+)\][[:space:]]*$|\1|p' "$config_file" fi } _polybar() { local options='-h --help -v --version -l --log= -q --quiet -c --config= -r --reload -d --dump= -m --list-monitors -M --list-all-monitors -w --print-wmname -s --stdout -p --png=' local log_levels='error warning notice info trace' COMPREPLY=() local cur=${COMP_WORDS[COMP_CWORD]} case "$cur" in -*) COMPREPLY=( $(compgen -W "$options" -- "$cur") ) ;; *) local prev=${COMP_WORDS[COMP_CWORD - 1]} if [ "$prev" = "=" ]; then prev=${COMP_WORDS[COMP_CWORD - 2]} fi case "$prev" in -l|--log) COMPREPLY=( $(compgen -W "$log_levels" -- "$cur") ) return 0 ;; -c|--config) COMPREPLY=( $(compgen -f "$cur") ) return 0 ;; -p|--png) COMPREPLY=( $(compgen -f -X "!*.png" "$cur") ) return 0 ;; -d|--dump) return 0 ;; *) COMPREPLY=( $(compgen -W "$options $(_polybar_bars)" -- "$cur") ) ;; esac esac for ((i = 0; i < ${#COMPREPLY[@]}; i++)); do case ${COMPREPLY[i]} in --*=) ;; -*) COMPREPLY[i]+=" " esac done return 0 } complete -o filenames -o noquote -o nospace -F _polybar polybar polybar-3.7.2/build.sh0000755000175100001770000001767414660106013014212 0ustar runnerdocker#!/usr/bin/env bash readonly SELF=${0##*/} declare -rA COLORS=( [RED]=$'\033[0;31m' [GREEN]=$'\033[0;32m' [BLUE]=$'\033[0;34m' [PURPLE]=$'\033[0;35m' [CYAN]=$'\033[0;36m' [WHITE]=$'\033[0;37m' [YELLOW]=$'\033[0;33m' [BOLD]=$'\033[1m' [OFF]=$'\033[0m' ) usage() { echo " Builds and installs polybar. ${COLORS[GREEN]}${COLORS[BOLD]}Usage:${COLORS[OFF]} ${COLORS[CYAN]}${SELF}${COLORS[OFF]} [options] ${COLORS[GREEN]}${COLORS[BOLD]}Options:${COLORS[OFF]} ${COLORS[GREEN]}-3, --i3${COLORS[OFF]} Include support for internal/i3 (requires i3); disabled by default. ${COLORS[GREEN]}-a, --alsa${COLORS[OFF]} Include support for internal/alsa (requires alsalib); disabled by default. ${COLORS[GREEN]}-p, --pulseaudio${COLORS[OFF]} Include support for internal/pulseaudio (requires libpulse); disabled by default. ${COLORS[GREEN]}-n, --network${COLORS[OFF]} Include support for internal/network (requires libnl/libiw); disabled by default. ${COLORS[GREEN]}-m, --mpd${COLORS[OFF]} Include support for internal/mpd (requires libmpdclient); disabled by default. ${COLORS[GREEN]}-c, --curl${COLORS[OFF]} Include support for internal/github (requires libcurl); disabled by default. ${COLORS[GREEN]}-i, --ipc${COLORS[OFF]} Build polybar-msg used to send ipc messages; disabled by default. ${COLORS[GREEN]}--all-features${COLORS[OFF]} Enable all abovementioned features; equal to -3 -a -p -n -m -c -i ${COLORS[GREEN]}-g, --gcc${COLORS[OFF]} Use GCC even if Clang is installed; disabled by default. ${COLORS[GREEN]}-j, --jobs${COLORS[OFF]} Use make -j to use make jobs with $(nproc) jobs; disabled by default. ${COLORS[GREEN]}-f${COLORS[OFF]} Remove existing build dir; disabled by default. ${COLORS[GREEN]}-I, --no-install${COLORS[OFF]} Do not execute 'sudo make install'; enabled by default. ${COLORS[GREEN]}-A, --auto${COLORS[OFF]} Automatic, non-interactive installation; disabled by default. When set, script defaults options not explicitly set. ${COLORS[GREEN]}-h, --help${COLORS[OFF]} Displays this help. " } msg_err() { echo -e "${COLORS[RED]}${COLORS[BOLD]}** ${COLORS[OFF]}$*\n" exit 1 } msg() { echo -e "${COLORS[GREEN]}${COLORS[BOLD]}** ${COLORS[OFF]}$*\n" } install() { local p if [[ "$AUTO" == ON ]]; then [[ -z "$INSTALL" ]] && INSTALL="ON" fi if [[ -z "$INSTALL" ]]; then read -r -p "$(msg "Execute 'sudo make install'? [Y/n] ")" -n 1 p && echo [[ "${p^^}" != "N" ]] && INSTALL="ON" || INSTALL="OFF" fi if [[ "$INSTALL" == ON ]]; then sudo make install || msg_err "Failed to install executables..." fi } set_build_opts() { local p msg "Setting build options" if [[ "$AUTO" == ON ]]; then [[ -z "$USE_GCC" ]] && USE_GCC="OFF" [[ -z "$ENABLE_I3" ]] && ENABLE_I3="OFF" [[ -z "$ENABLE_ALSA" ]] && ENABLE_ALSA="OFF" [[ -z "$ENABLE_PULSEAUDIO" ]] && ENABLE_PULSEAUDIO="OFF" [[ -z "$ENABLE_NETWORK" ]] && ENABLE_NETWORK="OFF" [[ -z "$ENABLE_MPD" ]] && ENABLE_MPD="OFF" [[ -z "$ENABLE_CURL" ]] && ENABLE_CURL="OFF" [[ -z "$ENABLE_IPC_MSG" ]] && ENABLE_IPC_MSG="OFF" [[ -z "$JOB_COUNT" ]] && JOB_COUNT=1 fi if [[ -z "$USE_GCC" ]]; then read -r -p "$(msg "Use GCC even if Clang is installed ----------------------------- [y/N]: ")" -n 1 p && echo [[ "${p^^}" != "Y" ]] && USE_GCC="OFF" || USE_GCC="ON" fi if [[ -z "$ENABLE_I3" ]]; then read -r -p "$(msg "Include support for \"internal/i3\" (requires i3) ---------------- [y/N]: ")" -n 1 p && echo [[ "${p^^}" != "Y" ]] && ENABLE_I3="OFF" || ENABLE_I3="ON" fi if [[ -z "$ENABLE_ALSA" ]]; then read -r -p "$(msg "Include support for \"internal/alsa\" (requires alsalib) --------- [y/N]: ")" -n 1 p && echo [[ "${p^^}" != "Y" ]] && ENABLE_ALSA="OFF" || ENABLE_ALSA="ON" fi if [[ -z "$ENABLE_PULSEAUDIO" ]]; then read -r -p "$(msg "Include support for \"internal/pulseaudio\" (requires libpulse) -- [y/N]: ")" -n 1 p && echo [[ "${p^^}" != "Y" ]] && ENABLE_PULSEAUDIO="OFF" || ENABLE_PULSEAUDIO="ON" fi if [[ -z "$ENABLE_NETWORK" ]]; then read -r -p "$(msg "Include support for \"internal/network\" (requires libnl/libiw) -- [y/N]: ")" -n 1 p && echo [[ "${p^^}" != "Y" ]] && ENABLE_NETWORK="OFF" || ENABLE_NETWORK="ON" fi if [[ -z "$ENABLE_MPD" ]]; then read -r -p "$(msg "Include support for \"internal/mpd\" (requires libmpdclient) ----- [y/N]: ")" -n 1 p && echo [[ "${p^^}" != "Y" ]] && ENABLE_MPD="OFF" || ENABLE_MPD="ON" fi if [[ -z "$ENABLE_CURL" ]]; then read -r -p "$(msg "Include support for \"internal/github\" (requires libcurl) ------- [y/N]: ")" -n 1 p && echo [[ "${p^^}" != "Y" ]] && ENABLE_CURL="OFF" || ENABLE_CURL="ON" fi if [[ -z "$ENABLE_IPC_MSG" ]]; then read -r -p "$(msg "Build \"polybar-msg\" used to send ipc messages ------------------ [y/N]: ")" -n 1 p && echo [[ "${p^^}" != "Y" ]] && ENABLE_IPC_MSG="OFF" || ENABLE_IPC_MSG="ON" fi if [[ -z "$JOB_COUNT" ]]; then read -r -p "$(msg "Parallelize the build using make -j$(nproc) --------------------------- [y/N]: ")" -n 1 p && echo [[ "${p^^}" != "Y" ]] && JOB_COUNT=1 || JOB_COUNT=$(nproc) fi CXX="c++" if [[ "$USE_GCC" == OFF ]]; then if command -v clang++ >/dev/null; then msg "Using compiler: clang++/clang" CXX="clang++" elif command -v g++ >/dev/null; then msg "Using compiler: g++/gcc" CXX="g++" fi else CXX="g++" fi } main() { [[ -d ./.git ]] && { msg "Fetching submodules" git submodule update --init --recursive || msg_err "Failed to clone submodules" } [[ -d ./build ]] && { if [[ "$REMOVE_BUILD_DIR" == ON ]]; then msg "Removing existing build dir (-f)" rm -rf ./build >/dev/null || msg_err "Failed to remove existing build dir" else msg "A build dir already exists (pass -f to replace)" fi } mkdir -p ./build || msg_err "Failed to create build dir" cd ./build || msg_err "Failed to enter build dir" set_build_opts msg "Executing cmake command" cmake \ -DCMAKE_CXX_COMPILER="${CXX}" \ -DENABLE_ALSA:BOOL="${ENABLE_ALSA}" \ -DENABLE_PULSEAUDIO:BOOL="${ENABLE_PULSEAUDIO}"\ -DENABLE_I3:BOOL="${ENABLE_I3}" \ -DENABLE_MPD:BOOL="${ENABLE_MPD}" \ -DENABLE_NETWORK:BOOL="${ENABLE_NETWORK}" \ -DENABLE_CURL:BOOL="${ENABLE_CURL}" \ -DBUILD_POLYBAR_MSG:BOOL="${ENABLE_IPC_MSG}" \ .. || msg_err "Failed to generate build... read output to get a hint of what went wrong" msg "Building project" if [ -z ${JOB_COUNT} ]; then make || msg_err "Failed to build project" else make -j$JOB_COUNT || msg_err "Failed to build project" fi install msg "Build complete!" exit 0 } ################# ###### Entry ################# while [[ "$1" == -* ]]; do case "$1" in -3|--i3) ENABLE_I3=ON; shift ;; -a|--alsa) ENABLE_ALSA=ON; shift ;; -p|--pulseaudio) ENABLE_PULSEAUDIO=ON; shift ;; -n|--network) ENABLE_NETWORK=ON; shift ;; -m|--mpd) ENABLE_MPD=ON; shift ;; -c|--curl) ENABLE_CURL=ON; shift ;; -i|--ipc) ENABLE_IPC_MSG=ON; shift ;; --all-features) ENABLE_I3=ON ENABLE_ALSA=ON ENABLE_PULSEAUDIO=ON ENABLE_NETWORK=ON ENABLE_MPD=ON ENABLE_CURL=ON ENABLE_IPC_MSG=ON shift ;; -g|--gcc) USE_GCC=ON; shift ;; -j|--jobs) JOB_COUNT=$(nproc); shift ;; -f) REMOVE_BUILD_DIR=ON; shift ;; -I|--no-install) INSTALL=OFF; shift ;; -A|--auto) AUTO=ON; shift ;; -h|--help) usage exit 0 ;; --) shift; break ;; *) usage [[ "$1" =~ ^-[0-9a-zA-Z]{2,}$ ]] && msg_err "don't combine options: ie do [-c -i] instead of [-ci]" || msg_err "unknown option [$1]" ;; esac done main polybar-3.7.2/tests/0000755000175100001770000000000014660106013013677 5ustar runnerdockerpolybar-3.7.2/tests/common/0000755000175100001770000000000014660106013015167 5ustar runnerdockerpolybar-3.7.2/tests/common/test.hpp0000644000175100001770000000004714660106013016660 0ustar runnerdocker#pragma once #include "gtest/gtest.h" polybar-3.7.2/tests/unit_tests/0000755000175100001770000000000014660106013016100 5ustar runnerdockerpolybar-3.7.2/tests/unit_tests/tags/0000755000175100001770000000000014660106013017036 5ustar runnerdockerpolybar-3.7.2/tests/unit_tests/tags/action_context.cpp0000644000175100001770000001246714660106013022575 0ustar runnerdocker#include "tags/action_context.hpp" #include "common/test.hpp" #include "components/logger.hpp" using namespace polybar; using namespace std; using namespace tags; TEST(ActionCtxtTest, dblClick) { action_context ctxt; EXPECT_FALSE(ctxt.has_double_click()); ctxt.action_open(mousebtn::DOUBLE_LEFT, "", alignment::LEFT, 0); ctxt.action_close(mousebtn::DOUBLE_LEFT, alignment::LEFT, 1); EXPECT_TRUE(ctxt.has_double_click()); ctxt.reset(); ctxt.action_open(mousebtn::DOUBLE_MIDDLE, "", alignment::LEFT, 0); ctxt.action_close(mousebtn::DOUBLE_MIDDLE, alignment::LEFT, 1); EXPECT_TRUE(ctxt.has_double_click()); ctxt.reset(); ctxt.action_open(mousebtn::DOUBLE_RIGHT, "", alignment::LEFT, 0); ctxt.action_close(mousebtn::DOUBLE_RIGHT, alignment::LEFT, 1); EXPECT_TRUE(ctxt.has_double_click()); } TEST(ActionCtxtTest, closing) { action_context ctxt; auto id1 = ctxt.action_open(mousebtn::LEFT, "", alignment::LEFT, 0); auto id2 = ctxt.action_open(mousebtn::RIGHT, "", alignment::CENTER, 0); auto id3 = ctxt.action_open(mousebtn::RIGHT, "", alignment::LEFT, 0); auto id4 = ctxt.action_open(mousebtn::MIDDLE, "", alignment::LEFT, 0); EXPECT_NE(NO_ACTION, id1); EXPECT_NE(NO_ACTION, id2); EXPECT_NE(NO_ACTION, id3); EXPECT_NE(NO_ACTION, id4); EXPECT_EQ(4, ctxt.num_unclosed()); EXPECT_EQ(make_pair(id1, mousebtn::LEFT), ctxt.action_close(mousebtn::LEFT, alignment::LEFT, 1)); EXPECT_EQ(3, ctxt.num_unclosed()); EXPECT_EQ(make_pair(id4, mousebtn::MIDDLE), ctxt.action_close(mousebtn::NONE, alignment::LEFT, 1)); EXPECT_EQ(2, ctxt.num_unclosed()); EXPECT_EQ(make_pair(id3, mousebtn::RIGHT), ctxt.action_close(mousebtn::NONE, alignment::LEFT, 1)); EXPECT_EQ(1, ctxt.num_unclosed()); EXPECT_EQ(make_pair(id2, mousebtn::RIGHT), ctxt.action_close(mousebtn::NONE, alignment::CENTER, 1)); EXPECT_EQ(0, ctxt.num_unclosed()); EXPECT_EQ(4, ctxt.num_actions()); } TEST(ActionCtxtTest, doubleClosing) { action_context ctxt; auto id = ctxt.action_open(mousebtn::LEFT, "", alignment::LEFT, 0); EXPECT_NE(NO_ACTION, id); EXPECT_EQ(1, ctxt.num_unclosed()); EXPECT_EQ(make_pair(id, mousebtn::LEFT), ctxt.action_close(mousebtn::LEFT, alignment::LEFT, 1)); EXPECT_EQ(0, ctxt.num_unclosed()); EXPECT_EQ(make_pair(tags::NO_ACTION, mousebtn::NONE), ctxt.action_close(mousebtn::LEFT, alignment::LEFT, 1)); EXPECT_EQ(0, ctxt.num_unclosed()); } TEST(ActionCtxtTest, overlapping) { action_context ctxt; /* * clang-format off * * Sets up the following overlapping of actions: * 0123456 * 1: [--) (LEFT) * 2: [----) (MIDDLE) * 3: [--) (RIGHT) * clang-format on */ auto id1 = ctxt.action_open(mousebtn::LEFT, "", alignment::LEFT, 0); auto id2 = ctxt.action_open(mousebtn::MIDDLE, "", alignment::LEFT, 1); auto id3 = ctxt.action_open(mousebtn::RIGHT, "", alignment::LEFT, 2); EXPECT_EQ(make_pair(id1, mousebtn::LEFT), ctxt.action_close(mousebtn::LEFT, alignment::LEFT, 3)); EXPECT_EQ(make_pair(id3, mousebtn::RIGHT), ctxt.action_close(mousebtn::RIGHT, alignment::LEFT, 6)); EXPECT_EQ(make_pair(id2, mousebtn::MIDDLE), ctxt.action_close(mousebtn::MIDDLE, alignment::LEFT, 5)); auto actions = ctxt.get_actions(2); EXPECT_EQ(id1, actions[mousebtn::LEFT]); EXPECT_EQ(id2, actions[mousebtn::MIDDLE]); EXPECT_EQ(id3, actions[mousebtn::RIGHT]); EXPECT_EQ(3, ctxt.num_actions()); EXPECT_EQ(0, ctxt.num_unclosed()); } TEST(ActionCtxtTest, stacking) { action_context ctxt; /* * clang-format off * * Sets up the following stacked actions: * 012345678 * 1: [-------) * 2: [-----) * 3: [--) * clang-format on */ auto id1 = ctxt.action_open(mousebtn::LEFT, "", alignment::LEFT, 0); auto id2 = ctxt.action_open(mousebtn::LEFT, "", alignment::LEFT, 1); auto id3 = ctxt.action_open(mousebtn::LEFT, "", alignment::LEFT, 3); EXPECT_EQ(make_pair(id3, mousebtn::LEFT), ctxt.action_close(mousebtn::NONE, alignment::LEFT, 6)); EXPECT_EQ(make_pair(id2, mousebtn::LEFT), ctxt.action_close(mousebtn::NONE, alignment::LEFT, 7)); EXPECT_EQ(make_pair(id1, mousebtn::LEFT), ctxt.action_close(mousebtn::NONE, alignment::LEFT, 8)); EXPECT_EQ(id1, ctxt.has_action(mousebtn::LEFT, 0)); EXPECT_EQ(id2, ctxt.has_action(mousebtn::LEFT, 1)); EXPECT_EQ(id2, ctxt.has_action(mousebtn::LEFT, 2)); EXPECT_EQ(id3, ctxt.has_action(mousebtn::LEFT, 3)); EXPECT_EQ(id3, ctxt.has_action(mousebtn::LEFT, 4)); EXPECT_EQ(id3, ctxt.has_action(mousebtn::LEFT, 5)); EXPECT_EQ(id2, ctxt.has_action(mousebtn::LEFT, 6)); EXPECT_EQ(id1, ctxt.has_action(mousebtn::LEFT, 7)); EXPECT_EQ(3, ctxt.num_actions()); EXPECT_EQ(0, ctxt.num_unclosed()); } TEST(ActionCtxtTest, cmd) { action_context ctxt; string cmd = "foobar"; auto id = ctxt.action_open(mousebtn::DOUBLE_RIGHT, cmd.substr(), alignment::RIGHT, 0); EXPECT_EQ(cmd, ctxt.get_action(id)); } TEST(ActionCtxtTest, getActionBlocks) { action_context ctxt; ctxt.action_open(mousebtn::DOUBLE_MIDDLE, "", alignment::RIGHT, 0); ctxt.action_close(mousebtn::DOUBLE_MIDDLE, alignment::RIGHT, 1); const auto& blocks = ctxt.get_blocks(); ASSERT_EQ(1, blocks.size()); const auto block = blocks[0]; EXPECT_EQ("", block.cmd); EXPECT_EQ(0, block.start_x); EXPECT_EQ(1, block.end_x); EXPECT_FALSE(block.is_open); EXPECT_EQ(mousebtn::DOUBLE_MIDDLE, block.button); EXPECT_EQ(alignment::RIGHT, block.align); } polybar-3.7.2/tests/unit_tests/tags/dispatch.cpp0000644000175100001770000002171114660106013021343 0ustar runnerdocker#include "tags/dispatch.hpp" #include "common/test.hpp" #include "components/logger.hpp" #include "events/signal_emitter.hpp" #include "gmock/gmock.h" using namespace polybar; using namespace std; using namespace tags; using ::testing::_; using ::testing::AllOf; using ::testing::InSequence; using ::testing::Property; using ::testing::Return; using ::testing::Truly; namespace polybar { inline bool operator==(const extent_val& a, const extent_val& b) { return a.type == b.type && a.value == b.value; } } // namespace polybar /** * Fake renderer that just tracks the current x-position per alignment. * * Each text character and point is treated as a single pixel. */ class FakeRenderer : public renderer_interface { public: FakeRenderer(action_context& action_ctxt) : renderer_interface(action_ctxt){}; void render_offset(const tags::context& ctxt, const extent_val offset) override { EXPECT_NE(alignment::NONE, ctxt.get_alignment()); block_x[ctxt.get_alignment()] += offset.value; }; void render_text(const tags::context& ctxt, const string&& str) override { EXPECT_NE(alignment::NONE, ctxt.get_alignment()); block_x[ctxt.get_alignment()] += str.size(); }; void change_alignment(const tags::context& ctxt) override { EXPECT_NE(alignment::NONE, ctxt.get_alignment()); }; double get_x(const tags::context& ctxt) const override { EXPECT_NE(alignment::NONE, ctxt.get_alignment()); return block_x.at(ctxt.get_alignment()); }; double get_alignment_start(const alignment) const override { return 0; }; void apply_tray_position(const tags::context&) override{}; private: map block_x = { {alignment::LEFT, 0}, {alignment::CENTER, 0}, {alignment::RIGHT, 0}, }; }; class MockRenderer : public renderer_interface { public: MockRenderer(action_context& action_ctxt) : renderer_interface(action_ctxt), fake(action_ctxt){}; MOCK_METHOD(void, render_offset, (const context& ctxt, const extent_val offset), (override)); MOCK_METHOD(void, render_text, (const context& ctxt, const string&& str), (override)); MOCK_METHOD(void, change_alignment, (const context& ctxt), (override)); MOCK_METHOD(double, get_x, (const context& ctxt), (const, override)); MOCK_METHOD(double, get_alignment_start, (const alignment align), (const, override)); MOCK_METHOD(void, apply_tray_position, (const polybar::tags::context& context), (override)); void DelegateToFake() { ON_CALL(*this, render_offset).WillByDefault([this](const context& ctxt, const extent_val offset) { fake.render_offset(ctxt, offset); }); ON_CALL(*this, render_text).WillByDefault([this](const context& ctxt, const string&& str) { fake.render_text(ctxt, std::forward(str)); }); ON_CALL(*this, get_x).WillByDefault([this](const context& ctxt) { return fake.get_x(ctxt); }); ON_CALL(*this, get_alignment_start).WillByDefault([this](const alignment a) { return fake.get_alignment_start(a); }); ON_CALL(*this, apply_tray_position).WillByDefault([this](const context& context) { return fake.apply_tray_position(context); }); } private: FakeRenderer fake; }; static auto match_fg = [](rgba c) { return Property("get_fg", &context::get_fg, c); }; static auto match_bg = [](rgba c) { return Property("get_bg", &context::get_bg, c); }; static auto match_ol = [](rgba c) { return Property("get_ol", &context::get_ol, c); }; static auto match_ul = [](rgba c) { return Property("get_ul", &context::get_ul, c); }; static auto match_font = [](int font) { return Property("get_font", &context::get_font, font); }; static auto match_overline = [](bool has) { return Property("has_overline", &context::has_overline, has); }; static auto match_underline = [](bool has) { return Property("has_underline", &context::has_underline, has); }; static auto match_align = [](alignment align) { return Property("get_alignment", &context::get_alignment, align); }; static auto match_left_align = match_align(alignment::LEFT); static auto match_center_align = match_align(alignment::CENTER); static auto match_right_align = match_align(alignment::RIGHT); class DispatchTest : public ::testing::Test { protected: unique_ptr m_action_ctxt = make_unique(); unique_ptr m_dispatch = make_unique(logger(loglevel::NONE), *m_action_ctxt); ::testing::NiceMock r{*m_action_ctxt}; void SetUp() override { r.DelegateToFake(); } }; TEST_F(DispatchTest, ignoreFormatting) { { InSequence seq; EXPECT_CALL(r, render_offset(_, extent_val{extent_type::PIXEL, 10})).Times(1); EXPECT_CALL(r, render_text(_, string{"abc"})).Times(1); EXPECT_CALL(r, render_text(_, string{"foo"})).Times(1); } bar_settings settings; m_dispatch->parse(settings, r, "%{l}%{O10}%{F#ff0000}abc%{F-}foo"); } TEST_F(DispatchTest, formatting) { bar_settings settings; rgba bar_fg = settings.foreground; rgba bar_bg = settings.background; rgba c1{"#ff0000"}; rgba c2{"#00ff00"}; rgba c3{"#0000ff"}; rgba c4{"#f0f0f0"}; { InSequence seq; EXPECT_CALL(r, change_alignment(match_left_align)).Times(1); EXPECT_CALL(r, render_offset(_, extent_val{extent_type::PIXEL, 10})).Times(1); EXPECT_CALL(r, render_text(match_fg(c1), string{"abc"})).Times(1); EXPECT_CALL(r, render_text(match_fg(bar_fg), string{"foo"})).Times(1); EXPECT_CALL(r, change_alignment(match_left_align)).Times(1); EXPECT_CALL(r, render_text(AllOf(match_left_align, match_bg(c2), match_fg(bar_fg)), string{"bar"})).Times(1); EXPECT_CALL(r, render_text(AllOf(match_left_align, match_fg(c2), match_bg(bar_fg)), string{"123"})).Times(1); EXPECT_CALL(r, change_alignment(match_center_align)).Times(1); EXPECT_CALL(r, render_text(match_center_align, string{"baz"})).Times(1); EXPECT_CALL(r, change_alignment(match_right_align)).Times(1); EXPECT_CALL(r, render_text(AllOf(match_right_align, match_font(123)), string{"def"})).Times(1); EXPECT_CALL(r, render_text(AllOf(match_right_align, match_fg(bar_fg), match_bg(bar_bg)), string{"ghi"})).Times(1); } m_dispatch->parse(settings, r, "%{l}%{O10}%{F#ff0000}abc%{F-}foo%{l}%{B#00ff00}bar%{R}123%{c}baz%{r}%{T123}def%{PR}" "ghi"); } TEST_F(DispatchTest, formattingAttributes) { bar_settings settings; rgba bar_ol = settings.overline.color; rgba bar_ul = settings.underline.color; rgba c1{"#0000ff"}; rgba c2{"#f0f0f0"}; { InSequence seq; EXPECT_CALL( r, render_text(AllOf(match_ul(c1), match_ol(c2), match_overline(true), match_underline(true)), string{"123"})) .Times(1); EXPECT_CALL( r, render_text(AllOf(match_ul(c1), match_ol(c2), match_overline(false), match_underline(false)), string{"456"})) .Times(1); EXPECT_CALL( r, render_text(AllOf(match_ul(c1), match_ol(c2), match_overline(true), match_underline(true)), string{"789"})) .Times(1); EXPECT_CALL(r, render_text(AllOf(match_ul(bar_ul), match_ol(bar_ol), match_overline(false), match_underline(false)), string{"0"})) .Times(1); } m_dispatch->parse(settings, r, "%{l}%{u#0000ff o#f0f0f0 +o +u}123%{-u -o}456%{!u !o}789%{PR}0"); } TEST_F(DispatchTest, unclosedActions) { { InSequence seq; } bar_settings settings; EXPECT_THROW(m_dispatch->parse(settings, r, "%{l}%{A1:cmd:}foo"), runtime_error); } TEST_F(DispatchTest, actions) { bar_settings settings; m_dispatch->parse(settings, r, "%{l}foo%{A1:cmd:}bar%{A}"); const auto& actions = m_action_ctxt->get_blocks(); ASSERT_EQ(1, actions.size()); const auto& blk = actions[0]; EXPECT_EQ(3, blk.start_x); EXPECT_EQ(6, blk.end_x); EXPECT_EQ(alignment::LEFT, blk.align); EXPECT_EQ(mousebtn::LEFT, blk.button); EXPECT_EQ("cmd", blk.cmd); } TEST_F(DispatchTest, actionOffsetStart) { bar_settings settings; m_dispatch->parse(settings, r, "%{l}a%{A1:cmd:}%{O-1}bar%{A}"); const auto& actions = m_action_ctxt->get_blocks(); ASSERT_EQ(1, actions.size()); const auto& blk = actions[0]; EXPECT_EQ(0, blk.start_x); EXPECT_EQ(3, blk.end_x); EXPECT_EQ(alignment::LEFT, blk.align); EXPECT_EQ(mousebtn::LEFT, blk.button); EXPECT_EQ("cmd", blk.cmd); } TEST_F(DispatchTest, actionOffsetEnd) { bar_settings settings; m_dispatch->parse(settings, r, "%{l}a%{A1:cmd:}bar%{O-3}%{A}"); const auto& actions = m_action_ctxt->get_blocks(); ASSERT_EQ(1, actions.size()); const auto& blk = actions[0]; EXPECT_EQ(1, blk.start_x); EXPECT_EQ(4, blk.end_x); EXPECT_EQ(alignment::LEFT, blk.align); EXPECT_EQ(mousebtn::LEFT, blk.button); EXPECT_EQ("cmd", blk.cmd); } TEST_F(DispatchTest, actionOffsetBefore) { bar_settings settings; m_dispatch->parse(settings, r, "%{l}%{O100 O-100}a%{A1:cmd:}bar%{O-3}%{A}"); const auto& actions = m_action_ctxt->get_blocks(); ASSERT_EQ(1, actions.size()); const auto& blk = actions[0]; EXPECT_EQ(1, blk.start_x); EXPECT_EQ(4, blk.end_x); EXPECT_EQ(alignment::LEFT, blk.align); EXPECT_EQ(mousebtn::LEFT, blk.button); EXPECT_EQ("cmd", blk.cmd); } polybar-3.7.2/tests/unit_tests/tags/parser.cpp0000644000175100001770000003102314660106013021035 0ustar runnerdocker#include "tags/parser.hpp" #include "common/test.hpp" using namespace polybar; using namespace tags; /** * Helper class to test parsed data. * * The expect_* functions will check that the current element corresponds to * what is expected and then move to the next element. * * The assert_* functions are used internally to check certain properties of the * current element. */ class TestableTagParser : public parser { public: TestableTagParser() : TestableTagParser(""){}; TestableTagParser(const string&& input) { setup_parser_test(std::move(input)); } void setup_parser_test(const string& input) { this->set(std::move(input)); } void expect_done() { EXPECT_FALSE(has_next_element()); } void expect_text(const string&& exp) { set_current(); assert_is_tag(false); EXPECT_EQ(exp, current.data); } void expect_color_reset(syntaxtag t) { set_current(); assert_format(t); EXPECT_EQ(color_type::RESET, current.tag_data.color.type); } void expect_color(syntaxtag t, const string& color) { set_current(); assert_format(t); rgba c{color}; EXPECT_EQ(color_type::COLOR, current.tag_data.color.type); EXPECT_EQ(c, current.tag_data.color.val); } void expect_action_closing(mousebtn exp = mousebtn::NONE) { set_current(); assert_format(syntaxtag::A); EXPECT_TRUE(current.tag_data.action.closing); EXPECT_EQ(exp, current.tag_data.action.btn); } void expect_action(const string& exp, mousebtn btn) { set_current(); assert_format(syntaxtag::A); EXPECT_FALSE(current.tag_data.action.closing); EXPECT_EQ(btn, current.tag_data.action.btn); EXPECT_EQ(exp, current.data); } void expect_font_reset() { expect_font(0); } void expect_font(unsigned exp) { set_current(); assert_format(syntaxtag::T); EXPECT_EQ(exp, current.tag_data.font); } void expect_offset_pixel(int exp) { set_current(); assert_format(syntaxtag::O); EXPECT_EQ(extent_type::PIXEL, current.tag_data.offset.type); EXPECT_EQ(exp, current.tag_data.offset.value); } void expect_offset_points(float exp) { set_current(); assert_format(syntaxtag::O); EXPECT_EQ(extent_type::POINT, current.tag_data.offset.type); EXPECT_EQ(exp, current.tag_data.offset.value); } void expect_ctrl(controltag exp) { set_current(); assert_format(syntaxtag::P); EXPECT_EQ(exp, current.tag_data.ctrl); } void expect_alignment(syntaxtag exp) { set_current(); assert_format(exp); } void expect_activation(attr_activation act, attribute attr) { set_current(); assert_type(tag_type::ATTR); EXPECT_EQ(act, current.tag_data.subtype.activation); EXPECT_EQ(attr, current.tag_data.attr); } void expect_reverse() { set_current(); assert_format(syntaxtag::R); } private: void assert_format(syntaxtag exp) { assert_type(tag_type::FORMAT); ASSERT_EQ(exp, current.tag_data.subtype.format); } void assert_type(tag_type exp) { assert_is_tag(true); ASSERT_EQ(exp, current.tag_data.type); } void assert_is_tag(bool exp) { ASSERT_EQ(exp, current.is_tag); } void assert_has() { if (!has_next_element()) { throw std::runtime_error("no next element"); } } void set_current() { assert_has(); current = next_element(); } element current; }; class TagParserTest : public ::testing::Test { protected: TestableTagParser p; }; TEST_F(TagParserTest, empty) { p.setup_parser_test(""); p.expect_done(); } TEST_F(TagParserTest, text) { p.setup_parser_test("text"); p.expect_text("text"); p.expect_done(); } // Single Tag {{{ // Parse Single Color {{{ /** * * * If the color string is empty, this is supposed to be a color reset */ using single_color = std::tuple; class ParseSingleColorTest : public TagParserTest, public ::testing::WithParamInterface {}; vector parse_single_color_list = { {"%{B-}", syntaxtag::B, ""}, {"%{F-}", syntaxtag::F, ""}, {"%{o-}", syntaxtag::o, ""}, {"%{u-}", syntaxtag::u, ""}, {"%{B}", syntaxtag::B, ""}, {"%{F}", syntaxtag::F, ""}, {"%{o}", syntaxtag::o, ""}, {"%{u}", syntaxtag::u, ""}, {"%{B#f0f0f0}", syntaxtag::B, "#f0f0f0"}, {"%{F#abc}", syntaxtag::F, "#abc"}, {"%{o#abcd}", syntaxtag::o, "#abcd"}, {"%{u#FDE}", syntaxtag::u, "#FDE"}, {"%{ u#FDE}", syntaxtag::u, "#FDE"}, }; INSTANTIATE_TEST_SUITE_P(Inst, ParseSingleColorTest, ::testing::ValuesIn(parse_single_color_list)); TEST_P(ParseSingleColorTest, correctness) { string input; syntaxtag t; string color; std::tie(input, t, color) = GetParam(); p.setup_parser_test(std::move(input)); if (color.empty()) { p.expect_color_reset(t); } else { p.expect_color(t, color); } p.expect_done(); } // }}} // Parse Single Action {{{ /** * If the third element is an empty string, this is a closing tag. */ using single_action = std::tuple; class ParseSingleActionTest : public TagParserTest, public ::testing::WithParamInterface {}; vector parse_single_action_list = { {"%{A:cmd:}", mousebtn::LEFT, "cmd"}, {"%{A1:cmd:}", mousebtn::LEFT, "cmd"}, {"%{A2:cmd:}", mousebtn::MIDDLE, "cmd"}, {"%{A3:cmd:}", mousebtn::RIGHT, "cmd"}, {"%{A4:cmd:}", mousebtn::SCROLL_UP, "cmd"}, {"%{A5:cmd:}", mousebtn::SCROLL_DOWN, "cmd"}, {"%{A6:cmd:}", mousebtn::DOUBLE_LEFT, "cmd"}, {"%{A7:cmd:}", mousebtn::DOUBLE_MIDDLE, "cmd"}, {"%{A8:cmd:}", mousebtn::DOUBLE_RIGHT, "cmd"}, {"%{A}", mousebtn::NONE, ""}, {"%{A1}", mousebtn::LEFT, ""}, {"%{A2}", mousebtn::MIDDLE, ""}, {"%{A3}", mousebtn::RIGHT, ""}, {"%{A4}", mousebtn::SCROLL_UP, ""}, {"%{A5}", mousebtn::SCROLL_DOWN, ""}, {"%{A6}", mousebtn::DOUBLE_LEFT, ""}, {"%{A7}", mousebtn::DOUBLE_MIDDLE, ""}, {"%{A8}", mousebtn::DOUBLE_RIGHT, ""}, {"%{A1:a\\:b:}", mousebtn::LEFT, "a:b"}, {"%{A1:\\:\\:\\::}", mousebtn::LEFT, ":::"}, {"%{A1:#apps.open.0:}", mousebtn::LEFT, "#apps.open.0"}, // https://github.com/polybar/polybar/issues/2040 {"%{A1:cmd | awk '{ print $NF }'):}", mousebtn::LEFT, "cmd | awk '{ print $NF }')"}, }; INSTANTIATE_TEST_SUITE_P(Inst, ParseSingleActionTest, ::testing::ValuesIn(parse_single_action_list)); TEST_P(ParseSingleActionTest, correctness) { string input; mousebtn btn; string cmd; std::tie(input, btn, cmd) = GetParam(); p.setup_parser_test(std::move(input)); if (cmd.empty()) { p.expect_action_closing(btn); } else { p.expect_action(cmd, btn); } p.expect_done(); } // }}} // Parse Single Activation {{{ using single_activation = std::tuple; class ParseSingleActivationTest : public TagParserTest, public ::testing::WithParamInterface {}; vector parse_single_activation_list = { {"%{+u}", attribute::UNDERLINE, attr_activation::ON}, {"%{-u}", attribute::UNDERLINE, attr_activation::OFF}, {"%{!u}", attribute::UNDERLINE, attr_activation::TOGGLE}, {"%{+o}", attribute::OVERLINE, attr_activation::ON}, {"%{-o}", attribute::OVERLINE, attr_activation::OFF}, {"%{!o}", attribute::OVERLINE, attr_activation::TOGGLE}, }; INSTANTIATE_TEST_SUITE_P(Inst, ParseSingleActivationTest, ::testing::ValuesIn(parse_single_activation_list)); TEST_P(ParseSingleActivationTest, correctness) { string input; attribute attr; attr_activation act; std::tie(input, attr, act) = GetParam(); p.setup_parser_test(std::move(input)); p.expect_activation(act, attr); p.expect_done(); } // }}} TEST_F(TagParserTest, reverse) { p.setup_parser_test("%{R}"); p.expect_reverse(); p.expect_done(); } TEST_F(TagParserTest, font) { p.setup_parser_test("%{T}"); p.expect_font_reset(); p.expect_done(); p.setup_parser_test("%{T-}"); p.expect_font_reset(); p.expect_done(); p.setup_parser_test("%{T-123}"); p.expect_font_reset(); p.expect_done(); p.setup_parser_test("%{T123}"); p.expect_font(123); p.expect_done(); } TEST_F(TagParserTest, offset) { p.setup_parser_test("%{O}"); p.expect_offset_pixel(0); p.expect_done(); p.setup_parser_test("%{O0}"); p.expect_offset_pixel(0); p.expect_done(); p.setup_parser_test("%{O-112}"); p.expect_offset_pixel(-112); p.expect_done(); p.setup_parser_test("%{O123}"); p.expect_offset_pixel(123); p.expect_done(); p.setup_parser_test("%{O0pt}"); p.expect_offset_points(0); p.expect_done(); p.setup_parser_test("%{O-112pt}"); p.expect_offset_points(-112); p.expect_done(); p.setup_parser_test("%{O123pt}"); p.expect_offset_points(123); p.expect_done(); p.setup_parser_test("%{O1.5pt}"); p.expect_offset_points(1.5); p.expect_done(); p.setup_parser_test("%{O1.1px}"); p.expect_offset_pixel(1); p.expect_done(); p.setup_parser_test("%{O1.1}"); p.expect_offset_pixel(1); p.expect_done(); } TEST_F(TagParserTest, alignment) { p.setup_parser_test("%{l}"); p.expect_alignment(syntaxtag::l); p.expect_done(); p.setup_parser_test("%{c}"); p.expect_alignment(syntaxtag::c); p.expect_done(); p.setup_parser_test("%{r}"); p.expect_alignment(syntaxtag::r); p.expect_done(); } TEST_F(TagParserTest, ctrl) { p.setup_parser_test("%{PR}"); p.expect_ctrl(controltag::R); p.expect_done(); } /** * Tests the the legacy %{U...} tag first produces %{u...} and then %{o...} */ TEST_F(TagParserTest, UnderOverLine) { p.setup_parser_test("%{U-}"); p.expect_color_reset(syntaxtag::u); p.expect_color_reset(syntaxtag::o); p.expect_done(); p.setup_parser_test("%{U#12ab}"); p.expect_color(syntaxtag::u, "#12ab"); p.expect_color(syntaxtag::o, "#12ab"); p.expect_done(); } // }}} TEST_F(TagParserTest, compoundTags) { p.setup_parser_test("%{F- B#ff0000 A:cmd:}"); p.expect_color_reset(syntaxtag::F); p.expect_color(syntaxtag::B, "#ff0000"); p.expect_action("cmd", mousebtn::LEFT); p.expect_done(); } TEST_F(TagParserTest, combinations) { p.setup_parser_test("%{r}%{u#4bffdc +u u#4bffdc} 20% abc%{-u u- PR}"); p.expect_alignment(syntaxtag::r); p.expect_color(syntaxtag::u, "#4bffdc"); p.expect_activation(attr_activation::ON, attribute::UNDERLINE); p.expect_color(syntaxtag::u, "#4bffdc"); p.expect_text(" 20% abc"); p.expect_activation(attr_activation::OFF, attribute::UNDERLINE); p.expect_color_reset(syntaxtag::u); p.expect_ctrl(controltag::R); p.expect_done(); } /** * The type of exception we expect. * * Since we can't directly pass typenames, we go through this enum. */ enum class exc { ERR, TOKEN, TAG, TAG_END, COLOR, ATTR, FONT, CTRL, OFFSET, BTN }; using exception_test = pair; class ParseErrorTest : public TagParserTest, public ::testing::WithParamInterface {}; vector parse_error_test = { {"%{F-", exc::TAG_END}, {"%{Q", exc::TAG}, {"%{", exc::TOKEN}, {"%{F#xyz}", exc::COLOR}, {"%{Ffoo}", exc::COLOR}, {"%{F-abc}", exc::COLOR}, {"%{+z}", exc::ATTR}, {"%{T-abc}", exc::FONT}, {"%{T12a}", exc::FONT}, {"%{Tabc}", exc::FONT}, {"%{?u", exc::TAG}, {"%{PRabc}", exc::CTRL}, {"%{P}", exc::CTRL}, {"%{PA}", exc::CTRL}, {"%{Oabc}", exc::OFFSET}, {"%{O123foo}", exc::OFFSET}, {"%{O0ptx}", exc::OFFSET}, {"%{O0a}", exc::OFFSET}, {"%{A2:cmd:cmd:}", exc::TAG_END}, {"%{A9}", exc::BTN}, {"%{rQ}", exc::TAG_END}, }; INSTANTIATE_TEST_SUITE_P(Inst, ParseErrorTest, ::testing::ValuesIn(parse_error_test)); TEST_P(ParseErrorTest, correctness) { string input; exc exception; std::tie(input, exception) = GetParam(); p.setup_parser_test(input); ASSERT_TRUE(p.has_next_element()); switch (exception) { case exc::ERR: ASSERT_THROW(p.next_element(), tags::error); break; case exc::TOKEN: ASSERT_THROW(p.next_element(), tags::token_error); break; case exc::TAG: ASSERT_THROW(p.next_element(), tags::unrecognized_tag); break; case exc::TAG_END: ASSERT_THROW(p.next_element(), tags::tag_end_error); break; case exc::COLOR: ASSERT_THROW(p.next_element(), tags::color_error); break; case exc::ATTR: ASSERT_THROW(p.next_element(), tags::unrecognized_attr); break; case exc::FONT: ASSERT_THROW(p.next_element(), tags::font_error); break; case exc::CTRL: ASSERT_THROW(p.next_element(), tags::control_error); break; case exc::OFFSET: ASSERT_THROW(p.next_element(), tags::offset_error); break; case exc::BTN: ASSERT_THROW(p.next_element(), tags::btn_error); break; default: FAIL(); } } polybar-3.7.2/tests/unit_tests/drawtypes/0000755000175100001770000000000014660106013020122 5ustar runnerdockerpolybar-3.7.2/tests/unit_tests/drawtypes/layouticonset.cpp0000644000175100001770000001031514660106013023530 0ustar runnerdocker#include "drawtypes/layouticonset.hpp" #include "common/test.hpp" using namespace std; using namespace polybar; using namespace polybar::drawtypes; TEST(LayoutIconSet, get) { layouticonset_t layout_icons = make_shared(make_shared