<commit_before>/**
 * @file quickprefs.cpp
 * @brief Quick preferences access panel for bottomtray
 *
 * $LicenseInfo:firstyear=2001&license=viewerlgpl$
 * Second Life Viewer Source Code
 * Copyright (C) 2010, Linden Research, Inc.
 * Copyright (C) 2011, WoLf Loonie @ Second Life
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation;
 * version 2.1 of the License only.
 *
 * This library 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 *
 * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
 * $/LicenseInfo$
 */

#include "llviewerprecompiledheaders.h"

#include "quickprefs.h"
#include "llboost.h"
#include "llcombobox.h"
#include "llwlparamset.h"
#include "llwlparammanager.h"
#include "llwaterparammanager.h"
#include "llfloatereditsky.h"
#include "llmultisliderctrl.h"
#include "lltimectrl.h"
#include "llenvmanager.h"
#include "llviewercontrol.h"

FloaterQuickPrefs::FloaterQuickPrefs(const LLSD& key)
:	LLTransientDockableFloater(NULL,true,key)
{
}

FloaterQuickPrefs::~FloaterQuickPrefs()
{
}

void FloaterQuickPrefs::onOpen(const LLSD& key)
{
}

void FloaterQuickPrefs::initCallbacks(void) {
	LLWLParamManager& param_mgr = LLWLParamManager::instance();
	getChild<LLUICtrl>("WaterPresetsCombo")->setCommitCallback(boost::bind(&FloaterQuickPrefs::onChangeWaterPreset, this, _1));
	getChild<LLUICtrl>("WLPresetsCombo")->setCommitCallback(boost::bind(&FloaterQuickPrefs::onChangeSkyPreset, this, _1));
	getChild<LLUICtrl>("WLPrevPreset")->setCommitCallback(boost::bind(&FloaterQuickPrefs::onClickSkyPrev, this));
	getChild<LLUICtrl>("WLNextPreset")->setCommitCallback(boost::bind(&FloaterQuickPrefs::onClickSkyNext, this));
	getChild<LLUICtrl>("WWPrevPreset")->setCommitCallback(boost::bind(&FloaterQuickPrefs::onClickWaterPrev, this));
	getChild<LLUICtrl>("WWNextPreset")->setCommitCallback(boost::bind(&FloaterQuickPrefs::onClickWaterNext, this));
	getChild<LLUICtrl>("UseRegionWL")->setCommitCallback(boost::bind(&FloaterQuickPrefs::onClickRegionWL, this));
	getChild<LLUICtrl>("WLSunPos")->setCommitCallback(boost::bind(&FloaterQuickPrefs::onSunMoved, this, _1, &param_mgr.mLightnorm));
}

BOOL FloaterQuickPrefs::postBuild()
{
	mWaterPresetsCombo = getChild<LLComboBox>("WaterPresetsCombo");
	mWLPresetsCombo = getChild<LLComboBox>("WLPresetsCombo");
	mWLSunPos = getChild<LLMultiSliderCtrl>("WLSunPos");

	LLEnvManagerNew& env_mgr = LLEnvManagerNew::instance();
	if (mWaterPresetsCombo != NULL)
	{

		std::list<std::string> user_presets, system_presets;
		LLWaterParamManager::instance().getPresetNames(user_presets, system_presets);

		// Add user presets first.
		for (std::list<std::string>::const_iterator mIt = user_presets.begin(); mIt != user_presets.end(); ++mIt)
		{
				if((*mIt).length()>0) mWaterPresetsCombo->add(*mIt);
		}

		if (user_presets.size() > 0)
		{
			mWaterPresetsCombo->addSeparator();
		}

		// Add system presets.
		for (std::list<std::string>::const_iterator mIt = system_presets.begin(); mIt != system_presets.end(); ++mIt)
		{
				if((*mIt).length()>0) mWaterPresetsCombo->add(*mIt);
		}
		mWaterPresetsCombo->selectByValue(env_mgr.getWaterPresetName());
	}

	if (mWLPresetsCombo != NULL)
	{
		LLWLParamManager::preset_name_list_t user_presets, sys_presets, region_presets;
		LLWLParamManager::instance().getPresetNames(region_presets, user_presets, sys_presets);

		// Add user presets.
		for (LLWLParamManager::preset_name_list_t::const_iterator it = user_presets.begin(); it != user_presets.end(); ++it)
		{
			if((*it).length()>0) mWLPresetsCombo->add(*it);
		}

		if (!user_presets.empty())
		{
			mWLPresetsCombo->addSeparator();
		}

		// Add system presets.
		for (LLWLParamManager::preset_name_list_t::const_iterator it = sys_presets.begin(); it != sys_presets.end(); ++it)
		{
			if((*it).length()>0) mWLPresetsCombo->add(*it);
		}
		mWLPresetsCombo->selectByValue(env_mgr.getSkyPresetName());
	}

	mWLSunPos->addSlider(12.f);
	initCallbacks();

	return LLDockableFloater::postBuild();
}

void FloaterQuickPrefs::onChangeWaterPreset(LLUICtrl* ctrl)
{
	std::string data = ctrl->getValue().asString();
	if(!data.empty())
	{
		LLEnvManagerNew::instance().setUseWaterPreset(data, (bool)gSavedSettings.getBOOL("FSInterpolateWater"));
		LLWaterParamManager::instance().getParamSet(data, LLWaterParamManager::instance().mCurParams);
	}
}

void FloaterQuickPrefs::onChangeSkyPreset(LLUICtrl* ctrl)
{
	std::string data = ctrl->getValue().asString();
	if(!data.empty())
	{
		LLEnvManagerNew::instance().setUseSkyPreset(data, (bool)gSavedSettings.getBOOL("FSInterpolateSky"));
		LLWLParamManager::instance().getParamSet(LLWLParamKey(data, LLEnvKey::SCOPE_LOCAL), LLWLParamManager::instance().mCurParams);
	}
}

void FloaterQuickPrefs::deactivateAnimator()
{
	LLWLParamManager::instance().mAnimator.deactivate();
}

void FloaterQuickPrefs::onClickWaterPrev()
{
	LLWaterParamManager& mgr = LLWaterParamManager::instance();
	LLWaterParamSet& currentParams = mgr.mCurParams;

	std::map<std::string, LLWaterParamSet> param_list = LLWaterParamManager::instance().getPresets();

	// find place of current param
	std::map<std::string, LLWaterParamSet>::iterator mIt = param_list.find(currentParams.mName);

	// if at the beginning, loop
	if(mIt == param_list.begin())
	{
		std::map<std::string, LLWaterParamSet>::iterator last = param_list.end();
		last--;
		mIt = last;
	}
	else
	{
		mIt--;
	}

	deactivateAnimator();

	mWaterPresetsCombo->setSimple(mIt->first);
	LLEnvManagerNew::instance().setUseWaterPreset(mIt->first, (bool)gSavedSettings.getBOOL("FSInterpolateWater"));
	mgr.getParamSet(mIt->first, mgr.mCurParams);
}

void FloaterQuickPrefs::onClickWaterNext()
{
	LLWaterParamManager& mgr = LLWaterParamManager::instance();
	LLWaterParamSet& currentParams = mgr.mCurParams;

	std::map<std::string, LLWaterParamSet> param_list = mgr.getPresets();

	// find place of current param
	std::map<std::string, LLWaterParamSet>::iterator mIt = param_list.find(currentParams.mName);

	// if at the end, loop
	std::map<std::string, LLWaterParamSet>::iterator last = param_list.end();
	last--;
	if(mIt == param_list.end())
	{
		mIt = param_list.begin();
	}
	else
	{
		mIt++;
	}

	deactivateAnimator();

	mWaterPresetsCombo->setSimple(mIt->first);
	LLEnvManagerNew::instance().setUseWaterPreset(mIt->first, (bool)gSavedSettings.getBOOL("FSInterpolateWater"));
	mgr.getParamSet(mIt->first, mgr.mCurParams);
}

void FloaterQuickPrefs::onClickSkyPrev()
{
	LLWLParamManager& mgr = LLWLParamManager::instance();
	std::map<LLWLParamKey, LLWLParamSet> param_list = mgr.getParamList();

	// find place of current param
	std::map<LLWLParamKey, LLWLParamSet>::iterator mIt;
	mIt = param_list.find(LLWLParamKey(mgr.mCurParams.mName, LLEnvKey::SCOPE_LOCAL));

	// shouldn't happen unless you delete every preset but Default
	if (mIt == param_list.end())
	{
		llwarns << "No more presets left!" << llendl;
		return;
	}

	// if at the beginning, loop
	if (mIt == param_list.begin())
	{
		std::map<LLWLParamKey, LLWLParamSet>::iterator last = param_list.end();
		last--;
		mIt = last;
	}
	else
	{
		mIt--;
	}

	deactivateAnimator();

	mWLPresetsCombo->setSimple(mIt->first.name);
	LLEnvManagerNew::instance().setUseSkyPreset(mIt->first.name, (bool)gSavedSettings.getBOOL("FSInterpolateSky"));
	mgr.getParamSet(mIt->first, mgr.mCurParams);
}

void FloaterQuickPrefs::onClickSkyNext()
{
	LLWLParamManager& mgr = LLWLParamManager::instance();

	std::map<LLWLParamKey, LLWLParamSet> param_list = mgr.getParamList();

	// find place of current param
	std::map<LLWLParamKey, LLWLParamSet>::iterator mIt;
	mIt = param_list.find(LLWLParamKey(mgr.mCurParams.mName, LLEnvKey::SCOPE_LOCAL));

	// shouldn't happen unless you delete every preset but Default
	if (mIt == param_list.end())
	{
		llwarns << "No more presets left!" << llendl;
		return;
	}

	// if at the end, loop
	std::map<LLWLParamKey, LLWLParamSet>::iterator last = param_list.end();
	last--;
	if (mIt == last)
	{
		mIt = param_list.begin();
	}
	else
	{
		mIt++;
	}

	deactivateAnimator();

	mWLPresetsCombo->setSimple(mIt->first.name);
	LLEnvManagerNew::instance().setUseSkyPreset(mIt->first.name, (bool)gSavedSettings.getBOOL("FSInterpolateSky"));
	mgr.getParamSet(mIt->first, mgr.mCurParams);
}

void FloaterQuickPrefs::draw()
{
	syncControls();
	LLFloater::draw();
}

static F32 sun_pos_to_time24(F32 sun_pos)
{
	return fmodf(sun_pos * 24.0f + 6, 24.0f);
}

void FloaterQuickPrefs::syncControls()
{
	bool err;

	LLWLParamManager& param_mgr = LLWLParamManager::instance();

	F32 time24 = sun_pos_to_time24(param_mgr.mCurParams.getFloat("sun_angle", err) / F_TWO_PI);
	mWLSunPos->setCurSliderValue(time24, TRUE);

	std::string current_wlpreset = param_mgr.mCurParams.mName;
	if (mWLPresetsCombo->getValue().asString() != current_wlpreset)
	{
		mWLPresetsCombo->setSimple(current_wlpreset);
	}

	std::string current_waterpreset = LLWaterParamManager::instance().mCurParams.mName;
	if (mWaterPresetsCombo->getValue().asString() != current_waterpreset)
	{
		mWaterPresetsCombo->setSimple(current_waterpreset);
	}
}

void FloaterQuickPrefs::onSunMoved(LLUICtrl* ctrl, void* userdata)
{
	F32 val = mWLSunPos->getCurSliderValue() / 24.0f;

	LLWLParamManager& mgr = LLWLParamManager::instance();
	mgr.mAnimator.setDayTime((F64)val);
	mgr.mAnimator.deactivate();
	mgr.mAnimator.update(mgr.mCurParams);
}

void FloaterQuickPrefs::onClickRegionWL()
{
	mWLPresetsCombo->setSimple(LLStringExplicit("Default"));
	mWaterPresetsCombo->setSimple(LLStringExplicit("Default"));
	LLEnvManagerNew::instance().useRegionSettings();
	LLWLParamManager::instance().getParamSet(LLWLParamKey("Default", LLEnvKey::SCOPE_LOCAL), LLWLParamManager::instance().mCurParams);
}
<commit_msg>FIRE-7766: Crashfix when clicking on next button on last water preset in quickprefs<commit_after>/**
 * @file quickprefs.cpp
 * @brief Quick preferences access panel for bottomtray
 *
 * $LicenseInfo:firstyear=2001&license=viewerlgpl$
 * Second Life Viewer Source Code
 * Copyright (C) 2010, Linden Research, Inc.
 * Copyright (C) 2011, WoLf Loonie @ Second Life
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation;
 * version 2.1 of the License only.
 *
 * This library 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 *
 * Linden Research, Inc., 945 Battery Street, San Francisco, CA  94111  USA
 * $/LicenseInfo$
 */

#include "llviewerprecompiledheaders.h"

#include "quickprefs.h"
#include "llboost.h"
#include "llcombobox.h"
#include "llwlparamset.h"
#include "llwlparammanager.h"
#include "llwaterparammanager.h"
#include "llfloatereditsky.h"
#include "llmultisliderctrl.h"
#include "lltimectrl.h"
#include "llenvmanager.h"
#include "llviewercontrol.h"

FloaterQuickPrefs::FloaterQuickPrefs(const LLSD& key)
:	LLTransientDockableFloater(NULL,true,key)
{
}

FloaterQuickPrefs::~FloaterQuickPrefs()
{
}

void FloaterQuickPrefs::onOpen(const LLSD& key)
{
}

void FloaterQuickPrefs::initCallbacks(void) {
	LLWLParamManager& param_mgr = LLWLParamManager::instance();
	getChild<LLUICtrl>("WaterPresetsCombo")->setCommitCallback(boost::bind(&FloaterQuickPrefs::onChangeWaterPreset, this, _1));
	getChild<LLUICtrl>("WLPresetsCombo")->setCommitCallback(boost::bind(&FloaterQuickPrefs::onChangeSkyPreset, this, _1));
	getChild<LLUICtrl>("WLPrevPreset")->setCommitCallback(boost::bind(&FloaterQuickPrefs::onClickSkyPrev, this));
	getChild<LLUICtrl>("WLNextPreset")->setCommitCallback(boost::bind(&FloaterQuickPrefs::onClickSkyNext, this));
	getChild<LLUICtrl>("WWPrevPreset")->setCommitCallback(boost::bind(&FloaterQuickPrefs::onClickWaterPrev, this));
	getChild<LLUICtrl>("WWNextPreset")->setCommitCallback(boost::bind(&FloaterQuickPrefs::onClickWaterNext, this));
	getChild<LLUICtrl>("UseRegionWL")->setCommitCallback(boost::bind(&FloaterQuickPrefs::onClickRegionWL, this));
	getChild<LLUICtrl>("WLSunPos")->setCommitCallback(boost::bind(&FloaterQuickPrefs::onSunMoved, this, _1, &param_mgr.mLightnorm));
}

BOOL FloaterQuickPrefs::postBuild()
{
	mWaterPresetsCombo = getChild<LLComboBox>("WaterPresetsCombo");
	mWLPresetsCombo = getChild<LLComboBox>("WLPresetsCombo");
	mWLSunPos = getChild<LLMultiSliderCtrl>("WLSunPos");

	LLEnvManagerNew& env_mgr = LLEnvManagerNew::instance();
	if (mWaterPresetsCombo != NULL)
	{

		std::list<std::string> user_presets, system_presets;
		LLWaterParamManager::instance().getPresetNames(user_presets, system_presets);

		// Add user presets first.
		for (std::list<std::string>::const_iterator mIt = user_presets.begin(); mIt != user_presets.end(); ++mIt)
		{
				if((*mIt).length()>0) mWaterPresetsCombo->add(*mIt);
		}

		if (user_presets.size() > 0)
		{
			mWaterPresetsCombo->addSeparator();
		}

		// Add system presets.
		for (std::list<std::string>::const_iterator mIt = system_presets.begin(); mIt != system_presets.end(); ++mIt)
		{
				if((*mIt).length()>0) mWaterPresetsCombo->add(*mIt);
		}
		mWaterPresetsCombo->selectByValue(env_mgr.getWaterPresetName());
	}

	if (mWLPresetsCombo != NULL)
	{
		LLWLParamManager::preset_name_list_t user_presets, sys_presets, region_presets;
		LLWLParamManager::instance().getPresetNames(region_presets, user_presets, sys_presets);

		// Add user presets.
		for (LLWLParamManager::preset_name_list_t::const_iterator it = user_presets.begin(); it != user_presets.end(); ++it)
		{
			if((*it).length()>0) mWLPresetsCombo->add(*it);
		}

		if (!user_presets.empty())
		{
			mWLPresetsCombo->addSeparator();
		}

		// Add system presets.
		for (LLWLParamManager::preset_name_list_t::const_iterator it = sys_presets.begin(); it != sys_presets.end(); ++it)
		{
			if((*it).length()>0) mWLPresetsCombo->add(*it);
		}
		mWLPresetsCombo->selectByValue(env_mgr.getSkyPresetName());
	}

	mWLSunPos->addSlider(12.f);
	initCallbacks();

	return LLDockableFloater::postBuild();
}

void FloaterQuickPrefs::onChangeWaterPreset(LLUICtrl* ctrl)
{
	std::string data = ctrl->getValue().asString();
	if(!data.empty())
	{
		LLEnvManagerNew::instance().setUseWaterPreset(data, (bool)gSavedSettings.getBOOL("FSInterpolateWater"));
		LLWaterParamManager::instance().getParamSet(data, LLWaterParamManager::instance().mCurParams);
	}
}

void FloaterQuickPrefs::onChangeSkyPreset(LLUICtrl* ctrl)
{
	std::string data = ctrl->getValue().asString();
	if(!data.empty())
	{
		LLEnvManagerNew::instance().setUseSkyPreset(data, (bool)gSavedSettings.getBOOL("FSInterpolateSky"));
		LLWLParamManager::instance().getParamSet(LLWLParamKey(data, LLEnvKey::SCOPE_LOCAL), LLWLParamManager::instance().mCurParams);
	}
}

void FloaterQuickPrefs::deactivateAnimator()
{
	LLWLParamManager::instance().mAnimator.deactivate();
}

void FloaterQuickPrefs::onClickWaterPrev()
{
	LLWaterParamManager& mgr = LLWaterParamManager::instance();
	LLWaterParamSet& currentParams = mgr.mCurParams;

	std::map<std::string, LLWaterParamSet> param_list = LLWaterParamManager::instance().getPresets();

	// find place of current param
	std::map<std::string, LLWaterParamSet>::iterator mIt = param_list.find(currentParams.mName);

	// shouldn't happen unless you delete every preset but Default
	if (mIt == param_list.end())
	{
		llwarns << "No more presets left!" << llendl;
		return;
	}

	// if at the beginning, loop
	if (mIt == param_list.begin())
	{
		std::map<std::string, LLWaterParamSet>::iterator last = param_list.end();
		last--;
		mIt = last;
	}
	else
	{
		mIt--;
	}

	deactivateAnimator();

	mWaterPresetsCombo->setSimple(mIt->first);
	LLEnvManagerNew::instance().setUseWaterPreset(mIt->first, (bool)gSavedSettings.getBOOL("FSInterpolateWater"));
	mgr.getParamSet(mIt->first, mgr.mCurParams);
}

void FloaterQuickPrefs::onClickWaterNext()
{
	LLWaterParamManager& mgr = LLWaterParamManager::instance();
	LLWaterParamSet& currentParams = mgr.mCurParams;

	std::map<std::string, LLWaterParamSet> param_list = mgr.getPresets();

	// find place of current param
	std::map<std::string, LLWaterParamSet>::iterator mIt = param_list.find(currentParams.mName);

	// shouldn't happen unless you delete every preset but Default
	if (mIt == param_list.end())
	{
		llwarns << "No more presets left!" << llendl;
		return;
	}

	// if at the end, loop
	std::map<std::string, LLWaterParamSet>::iterator last = param_list.end();
	last--;
	if (mIt == last)
	{
		mIt = param_list.begin();
	}
	else
	{
		mIt++;
	}

	deactivateAnimator();

	mWaterPresetsCombo->setSimple(mIt->first);
	LLEnvManagerNew::instance().setUseWaterPreset(mIt->first, (bool)gSavedSettings.getBOOL("FSInterpolateWater"));
	mgr.getParamSet(mIt->first, mgr.mCurParams);
}

void FloaterQuickPrefs::onClickSkyPrev()
{
	LLWLParamManager& mgr = LLWLParamManager::instance();
	std::map<LLWLParamKey, LLWLParamSet> param_list = mgr.getParamList();

	// find place of current param
	std::map<LLWLParamKey, LLWLParamSet>::iterator mIt;
	mIt = param_list.find(LLWLParamKey(mgr.mCurParams.mName, LLEnvKey::SCOPE_LOCAL));

	// shouldn't happen unless you delete every preset but Default
	if (mIt == param_list.end())
	{
		llwarns << "No more presets left!" << llendl;
		return;
	}

	// if at the beginning, loop
	if (mIt == param_list.begin())
	{
		std::map<LLWLParamKey, LLWLParamSet>::iterator last = param_list.end();
		last--;
		mIt = last;
	}
	else
	{
		mIt--;
	}

	deactivateAnimator();

	mWLPresetsCombo->setSimple(mIt->first.name);
	LLEnvManagerNew::instance().setUseSkyPreset(mIt->first.name, (bool)gSavedSettings.getBOOL("FSInterpolateSky"));
	mgr.getParamSet(mIt->first, mgr.mCurParams);
}

void FloaterQuickPrefs::onClickSkyNext()
{
	LLWLParamManager& mgr = LLWLParamManager::instance();

	std::map<LLWLParamKey, LLWLParamSet> param_list = mgr.getParamList();

	// find place of current param
	std::map<LLWLParamKey, LLWLParamSet>::iterator mIt;
	mIt = param_list.find(LLWLParamKey(mgr.mCurParams.mName, LLEnvKey::SCOPE_LOCAL));

	// shouldn't happen unless you delete every preset but Default
	if (mIt == param_list.end())
	{
		llwarns << "No more presets left!" << llendl;
		return;
	}

	// if at the end, loop
	std::map<LLWLParamKey, LLWLParamSet>::iterator last = param_list.end();
	last--;
	if (mIt == last)
	{
		mIt = param_list.begin();
	}
	else
	{
		mIt++;
	}

	deactivateAnimator();

	mWLPresetsCombo->setSimple(mIt->first.name);
	LLEnvManagerNew::instance().setUseSkyPreset(mIt->first.name, (bool)gSavedSettings.getBOOL("FSInterpolateSky"));
	mgr.getParamSet(mIt->first, mgr.mCurParams);
}

void FloaterQuickPrefs::draw()
{
	syncControls();
	LLFloater::draw();
}

static F32 sun_pos_to_time24(F32 sun_pos)
{
	return fmodf(sun_pos * 24.0f + 6, 24.0f);
}

void FloaterQuickPrefs::syncControls()
{
	bool err;

	LLWLParamManager& param_mgr = LLWLParamManager::instance();

	F32 time24 = sun_pos_to_time24(param_mgr.mCurParams.getFloat("sun_angle", err) / F_TWO_PI);
	mWLSunPos->setCurSliderValue(time24, TRUE);

	std::string current_wlpreset = param_mgr.mCurParams.mName;
	if (mWLPresetsCombo->getValue().asString() != current_wlpreset)
	{
		mWLPresetsCombo->setSimple(current_wlpreset);
	}

	std::string current_waterpreset = LLWaterParamManager::instance().mCurParams.mName;
	if (mWaterPresetsCombo->getValue().asString() != current_waterpreset)
	{
		mWaterPresetsCombo->setSimple(current_waterpreset);
	}
}

void FloaterQuickPrefs::onSunMoved(LLUICtrl* ctrl, void* userdata)
{
	F32 val = mWLSunPos->getCurSliderValue() / 24.0f;

	LLWLParamManager& mgr = LLWLParamManager::instance();
	mgr.mAnimator.setDayTime((F64)val);
	mgr.mAnimator.deactivate();
	mgr.mAnimator.update(mgr.mCurParams);
}

void FloaterQuickPrefs::onClickRegionWL()
{
	mWLPresetsCombo->setSimple(LLStringExplicit("Default"));
	mWaterPresetsCombo->setSimple(LLStringExplicit("Default"));
	LLEnvManagerNew::instance().useRegionSettings();
	LLWLParamManager::instance().getParamSet(LLWLParamKey("Default", LLEnvKey::SCOPE_LOCAL), LLWLParamManager::instance().mCurParams);
}
<|endoftext|>


<commit_before>// Copyright (c) 2014-2019 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include <chainparams.h>
#include <net.h>
#include <signet.h>
#include <validation.h>

#include <test/util/setup_common.h>

#include <boost/signals2/signal.hpp>
#include <boost/test/unit_test.hpp>

BOOST_FIXTURE_TEST_SUITE(validation_tests, TestingSetup)

static void TestBlockSubsidyHalvings(const Consensus::Params& consensusParams)
{
    int maxHalvings = 64;
    CAmount nInitialSubsidy = 50 * COIN;

    CAmount nPreviousSubsidy = nInitialSubsidy * 2; // for height == 0
    BOOST_CHECK_EQUAL(nPreviousSubsidy, nInitialSubsidy * 2);
    for (int nHalvings = 0; nHalvings < maxHalvings; nHalvings++) {
        int nHeight = nHalvings * consensusParams.nSubsidyHalvingInterval;
        CAmount nSubsidy = GetBlockSubsidy(nHeight, consensusParams);
        BOOST_CHECK(nSubsidy <= nInitialSubsidy);
        BOOST_CHECK_EQUAL(nSubsidy, nPreviousSubsidy / 2);
        nPreviousSubsidy = nSubsidy;
    }
    BOOST_CHECK_EQUAL(GetBlockSubsidy(maxHalvings * consensusParams.nSubsidyHalvingInterval, consensusParams), 0);
}

static void TestBlockSubsidyHalvings(int nSubsidyHalvingInterval)
{
    Consensus::Params consensusParams;
    consensusParams.nSubsidyHalvingInterval = nSubsidyHalvingInterval;
    TestBlockSubsidyHalvings(consensusParams);
}

BOOST_AUTO_TEST_CASE(block_subsidy_test)
{
    const auto chainParams = CreateChainParams(*m_node.args, CBaseChainParams::MAIN);
    TestBlockSubsidyHalvings(chainParams->GetConsensus()); // As in main
    TestBlockSubsidyHalvings(150); // As in regtest
    TestBlockSubsidyHalvings(1000); // Just another interval
}

BOOST_AUTO_TEST_CASE(subsidy_limit_test)
{
    const auto chainParams = CreateChainParams(*m_node.args, CBaseChainParams::MAIN);
    CAmount nSum = 0;
    for (int nHeight = 0; nHeight < 14000000; nHeight += 1000) {
        CAmount nSubsidy = GetBlockSubsidy(nHeight, chainParams->GetConsensus());
        BOOST_CHECK(nSubsidy <= 50 * COIN);
        nSum += nSubsidy * 1000;
        BOOST_CHECK(MoneyRange(nSum));
    }
    BOOST_CHECK_EQUAL(nSum, CAmount{2099999997690000});
}

BOOST_AUTO_TEST_CASE(signet_parse_tests)
{
    ArgsManager signet_argsman;
    signet_argsman.ForceSetArg("-signetchallenge", "51"); // set challenge to OP_TRUE
    const auto signet_params = CreateChainParams(signet_argsman, CBaseChainParams::SIGNET);
    CBlock block;
    BOOST_CHECK(signet_params->GetConsensus().signet_challenge == std::vector<uint8_t>{{OP_TRUE}});
    CScript challenge{OP_TRUE};

    // empty block is invalid
    BOOST_CHECK(!SignetTxs::Create(block, challenge));
    BOOST_CHECK(!CheckSignetBlockSolution(block, signet_params->GetConsensus()));

    // no witness commitment
    CMutableTransaction cb;
    cb.vout.emplace_back(0, CScript{});
    block.vtx.push_back(MakeTransactionRef(cb));
    block.vtx.push_back(MakeTransactionRef(cb)); // Add dummy tx to excercise merkle root code
    BOOST_CHECK(!SignetTxs::Create(block, challenge));
    BOOST_CHECK(!CheckSignetBlockSolution(block, signet_params->GetConsensus()));

    // no header is treated valid
    std::vector<uint8_t> witness_commitment_section_141{0xaa, 0x21, 0xa9, 0xed};
    for (int i = 0; i < 32; ++i) {
        witness_commitment_section_141.push_back(0xff);
    }
    cb.vout.at(0).scriptPubKey = CScript{} << OP_RETURN << witness_commitment_section_141;
    block.vtx.at(0) = MakeTransactionRef(cb);
    BOOST_CHECK(SignetTxs::Create(block, challenge));
    BOOST_CHECK(CheckSignetBlockSolution(block, signet_params->GetConsensus()));

    // no data after header, valid
    std::vector<uint8_t> witness_commitment_section_325{0xec, 0xc7, 0xda, 0xa2};
    cb.vout.at(0).scriptPubKey = CScript{} << OP_RETURN << witness_commitment_section_141 << witness_commitment_section_325;
    block.vtx.at(0) = MakeTransactionRef(cb);
    BOOST_CHECK(SignetTxs::Create(block, challenge));
    BOOST_CHECK(CheckSignetBlockSolution(block, signet_params->GetConsensus()));

    // Premature end of data, invalid
    witness_commitment_section_325.push_back(0x01);
    witness_commitment_section_325.push_back(0x51);
    cb.vout.at(0).scriptPubKey = CScript{} << OP_RETURN << witness_commitment_section_141 << witness_commitment_section_325;
    block.vtx.at(0) = MakeTransactionRef(cb);
    BOOST_CHECK(!SignetTxs::Create(block, challenge));
    BOOST_CHECK(!CheckSignetBlockSolution(block, signet_params->GetConsensus()));

    // has data, valid
    witness_commitment_section_325.push_back(0x00);
    cb.vout.at(0).scriptPubKey = CScript{} << OP_RETURN << witness_commitment_section_141 << witness_commitment_section_325;
    block.vtx.at(0) = MakeTransactionRef(cb);
    BOOST_CHECK(SignetTxs::Create(block, challenge));
    BOOST_CHECK(CheckSignetBlockSolution(block, signet_params->GetConsensus()));

    // Extraneous data, invalid
    witness_commitment_section_325.push_back(0x00);
    cb.vout.at(0).scriptPubKey = CScript{} << OP_RETURN << witness_commitment_section_141 << witness_commitment_section_325;
    block.vtx.at(0) = MakeTransactionRef(cb);
    BOOST_CHECK(!SignetTxs::Create(block, challenge));
    BOOST_CHECK(!CheckSignetBlockSolution(block, signet_params->GetConsensus()));
}

static bool ReturnFalse() { return false; }
static bool ReturnTrue() { return true; }

BOOST_AUTO_TEST_CASE(test_combiner_all)
{
    boost::signals2::signal<bool (), CombinerAll> Test;
    BOOST_CHECK(Test());
    Test.connect(&ReturnFalse);
    BOOST_CHECK(!Test());
    Test.connect(&ReturnTrue);
    BOOST_CHECK(!Test());
    Test.disconnect(&ReturnFalse);
    BOOST_CHECK(Test());
    Test.disconnect(&ReturnTrue);
    BOOST_CHECK(Test());
}
BOOST_AUTO_TEST_SUITE_END()
<commit_msg>refactor: fix -Wbraced-scalar-init warning in validation tests<commit_after>// Copyright (c) 2014-2019 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include <chainparams.h>
#include <net.h>
#include <signet.h>
#include <validation.h>

#include <test/util/setup_common.h>

#include <boost/signals2/signal.hpp>
#include <boost/test/unit_test.hpp>

BOOST_FIXTURE_TEST_SUITE(validation_tests, TestingSetup)

static void TestBlockSubsidyHalvings(const Consensus::Params& consensusParams)
{
    int maxHalvings = 64;
    CAmount nInitialSubsidy = 50 * COIN;

    CAmount nPreviousSubsidy = nInitialSubsidy * 2; // for height == 0
    BOOST_CHECK_EQUAL(nPreviousSubsidy, nInitialSubsidy * 2);
    for (int nHalvings = 0; nHalvings < maxHalvings; nHalvings++) {
        int nHeight = nHalvings * consensusParams.nSubsidyHalvingInterval;
        CAmount nSubsidy = GetBlockSubsidy(nHeight, consensusParams);
        BOOST_CHECK(nSubsidy <= nInitialSubsidy);
        BOOST_CHECK_EQUAL(nSubsidy, nPreviousSubsidy / 2);
        nPreviousSubsidy = nSubsidy;
    }
    BOOST_CHECK_EQUAL(GetBlockSubsidy(maxHalvings * consensusParams.nSubsidyHalvingInterval, consensusParams), 0);
}

static void TestBlockSubsidyHalvings(int nSubsidyHalvingInterval)
{
    Consensus::Params consensusParams;
    consensusParams.nSubsidyHalvingInterval = nSubsidyHalvingInterval;
    TestBlockSubsidyHalvings(consensusParams);
}

BOOST_AUTO_TEST_CASE(block_subsidy_test)
{
    const auto chainParams = CreateChainParams(*m_node.args, CBaseChainParams::MAIN);
    TestBlockSubsidyHalvings(chainParams->GetConsensus()); // As in main
    TestBlockSubsidyHalvings(150); // As in regtest
    TestBlockSubsidyHalvings(1000); // Just another interval
}

BOOST_AUTO_TEST_CASE(subsidy_limit_test)
{
    const auto chainParams = CreateChainParams(*m_node.args, CBaseChainParams::MAIN);
    CAmount nSum = 0;
    for (int nHeight = 0; nHeight < 14000000; nHeight += 1000) {
        CAmount nSubsidy = GetBlockSubsidy(nHeight, chainParams->GetConsensus());
        BOOST_CHECK(nSubsidy <= 50 * COIN);
        nSum += nSubsidy * 1000;
        BOOST_CHECK(MoneyRange(nSum));
    }
    BOOST_CHECK_EQUAL(nSum, CAmount{2099999997690000});
}

BOOST_AUTO_TEST_CASE(signet_parse_tests)
{
    ArgsManager signet_argsman;
    signet_argsman.ForceSetArg("-signetchallenge", "51"); // set challenge to OP_TRUE
    const auto signet_params = CreateChainParams(signet_argsman, CBaseChainParams::SIGNET);
    CBlock block;
    BOOST_CHECK(signet_params->GetConsensus().signet_challenge == std::vector<uint8_t>{OP_TRUE});
    CScript challenge{OP_TRUE};

    // empty block is invalid
    BOOST_CHECK(!SignetTxs::Create(block, challenge));
    BOOST_CHECK(!CheckSignetBlockSolution(block, signet_params->GetConsensus()));

    // no witness commitment
    CMutableTransaction cb;
    cb.vout.emplace_back(0, CScript{});
    block.vtx.push_back(MakeTransactionRef(cb));
    block.vtx.push_back(MakeTransactionRef(cb)); // Add dummy tx to excercise merkle root code
    BOOST_CHECK(!SignetTxs::Create(block, challenge));
    BOOST_CHECK(!CheckSignetBlockSolution(block, signet_params->GetConsensus()));

    // no header is treated valid
    std::vector<uint8_t> witness_commitment_section_141{0xaa, 0x21, 0xa9, 0xed};
    for (int i = 0; i < 32; ++i) {
        witness_commitment_section_141.push_back(0xff);
    }
    cb.vout.at(0).scriptPubKey = CScript{} << OP_RETURN << witness_commitment_section_141;
    block.vtx.at(0) = MakeTransactionRef(cb);
    BOOST_CHECK(SignetTxs::Create(block, challenge));
    BOOST_CHECK(CheckSignetBlockSolution(block, signet_params->GetConsensus()));

    // no data after header, valid
    std::vector<uint8_t> witness_commitment_section_325{0xec, 0xc7, 0xda, 0xa2};
    cb.vout.at(0).scriptPubKey = CScript{} << OP_RETURN << witness_commitment_section_141 << witness_commitment_section_325;
    block.vtx.at(0) = MakeTransactionRef(cb);
    BOOST_CHECK(SignetTxs::Create(block, challenge));
    BOOST_CHECK(CheckSignetBlockSolution(block, signet_params->GetConsensus()));

    // Premature end of data, invalid
    witness_commitment_section_325.push_back(0x01);
    witness_commitment_section_325.push_back(0x51);
    cb.vout.at(0).scriptPubKey = CScript{} << OP_RETURN << witness_commitment_section_141 << witness_commitment_section_325;
    block.vtx.at(0) = MakeTransactionRef(cb);
    BOOST_CHECK(!SignetTxs::Create(block, challenge));
    BOOST_CHECK(!CheckSignetBlockSolution(block, signet_params->GetConsensus()));

    // has data, valid
    witness_commitment_section_325.push_back(0x00);
    cb.vout.at(0).scriptPubKey = CScript{} << OP_RETURN << witness_commitment_section_141 << witness_commitment_section_325;
    block.vtx.at(0) = MakeTransactionRef(cb);
    BOOST_CHECK(SignetTxs::Create(block, challenge));
    BOOST_CHECK(CheckSignetBlockSolution(block, signet_params->GetConsensus()));

    // Extraneous data, invalid
    witness_commitment_section_325.push_back(0x00);
    cb.vout.at(0).scriptPubKey = CScript{} << OP_RETURN << witness_commitment_section_141 << witness_commitment_section_325;
    block.vtx.at(0) = MakeTransactionRef(cb);
    BOOST_CHECK(!SignetTxs::Create(block, challenge));
    BOOST_CHECK(!CheckSignetBlockSolution(block, signet_params->GetConsensus()));
}

static bool ReturnFalse() { return false; }
static bool ReturnTrue() { return true; }

BOOST_AUTO_TEST_CASE(test_combiner_all)
{
    boost::signals2::signal<bool (), CombinerAll> Test;
    BOOST_CHECK(Test());
    Test.connect(&ReturnFalse);
    BOOST_CHECK(!Test());
    Test.connect(&ReturnTrue);
    BOOST_CHECK(!Test());
    Test.disconnect(&ReturnFalse);
    BOOST_CHECK(Test());
    Test.disconnect(&ReturnTrue);
    BOOST_CHECK(Test());
}
BOOST_AUTO_TEST_SUITE_END()
<|endoftext|>


<commit_before>/*
 * This file is part of Maliit Plugins
 *
 * Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). All rights reserved.
 *
 * Contact: Mohammad Anwari <Mohammad.Anwari@nokia.com>
 *
 * Redistribution and use in source and binary forms, with or without modification,
 * are permitted provided that the following conditions are met:
 *
 * Redistributions of source code must retain the above copyright notice, this list
 * of conditions and the following disclaimer.
 * Redistributions in binary form must reproduce the above copyright notice, this list
 * of conditions and the following disclaimer in the documentation and/or other materials
 * provided with the distribution.
 * Neither the name of Nokia Corporation nor the names of its contributors may be
 * used to endorse or promote products derived from this software without specific
 * prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
 * THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 */

#include "utils.h"

#include "models/area.h"
#include "models/key.h"
#include "models/keyarea.h"
#include "models/layout.h"
#include "models/text.h"
#include "view/glass.h"
#include "view/setup.h"
#include "logic/wordengine.h"
#include "plugin/editor.h"
#include "inputmethodhostprobe.h"

#include <maliit/plugins/testsurfacefactory.h>

#include <QtCore>
#include <QtTest>
#include <QWidget>
#include <QList>
#include <QMouseEvent>

using namespace MaliitKeyboard;
Q_DECLARE_METATYPE(Layout::Orientation)
Q_DECLARE_METATYPE(QList<QMouseEvent*>)

namespace {
const int g_size = 48;
const int g_divider = 3;

QPoint keyOriginLookup(const QString &name)
{
    static const int distance = g_size / g_divider;

    if (name == "a") {
        return QPoint(0, 0);
    } else if (name == "b") {
        return QPoint(distance, 0);
    } else if (name == "b") {
        return QPoint(distance, 0);
    } else if (name == "c") {
        return QPoint(0, distance);
    } else if (name == "d") {
        return QPoint(distance, distance);
    } else if (name == "space") {
        return QPoint(distance * 2, 0);
    } else if (name == "return") {
        return QPoint(distance * 2, distance);
    }

    return QPoint();
}

Key createKey(Key::Action action,
              const QString &text)
{
    static const QSize size(g_size / g_divider, g_size / g_divider);

    Key result;
    result.setAction(action);
    result.setOrigin(keyOriginLookup(text));
    result.rArea().setSize(size);
    result.rLabel().setText(text);

    return result;
}

// Populate KeyArea with six keys, a, b, c, d, space and return. Notice how the KeyArea
// covers the whole widget. Key width and height equals g_size / g_divider.
// .-----------.
// | a | b |<s>|
// |---|---|---|
// | c | d |<r>|
// `-----------'
KeyArea createAbcdArea()
{
    KeyArea key_area;
    Area area;
    area.setSize(QSize(g_size, g_size));
    key_area.setArea(area);

    key_area.rKeys().append(createKey(Key::ActionInsert, "a"));
    key_area.rKeys().append(createKey(Key::ActionInsert, "b"));
    key_area.rKeys().append(createKey(Key::ActionInsert, "c"));
    key_area.rKeys().append(createKey(Key::ActionInsert, "d"));
    key_area.rKeys().append(createKey(Key::ActionSpace,  "space"));
    key_area.rKeys().append(createKey(Key::ActionReturn, "return"));

    return key_area;
}

QList<QMouseEvent *> createPressReleaseEvent(const QPoint &origin,
                                             Layout::Orientation orientation)
{
    static const int offset(g_size / (g_divider * 2));

    QList<QMouseEvent *> result;
    QPoint pos = (orientation == Layout::Landscape) ? QPoint(origin.x() + offset, origin.y() + offset)
                                                    : QPoint(origin.y() + offset, g_size - (origin.x() + offset));

    result.append(new QMouseEvent(QKeyEvent::MouseButtonPress, pos, Qt::LeftButton, Qt::LeftButton, Qt::NoModifier));
    result.append(new QMouseEvent(QKeyEvent::MouseButtonRelease, pos, Qt::LeftButton, Qt::LeftButton, Qt::NoModifier));

    return result;
}
}

class TestPreeditString
    : public QObject
{
    Q_OBJECT

private:
    typedef QList<Maliit::PreeditTextFormat> FormatList;

    Q_SLOT void initTestCase()
    {
        qRegisterMetaType<QList<QMouseEvent*> >();
        qRegisterMetaType<Layout::Orientation>();
        qRegisterMetaType<FormatList>();
    }

    Q_SLOT void test_data()
    {
        QTest::addColumn<Layout::Orientation>("orientation");
        QTest::addColumn<QList<QMouseEvent*> >("mouse_events");
        QTest::addColumn<QString>("expected_last_preedit_string");
        QTest::addColumn<QString>("expected_commit_string");
        QTest::addColumn<FormatList>("expected_preedit_format");

        for (int orientation = 0; orientation < 1; ++orientation) {
            // FIXME: here should be 2          ^
            // FIXME: tests fail for portrait layouts
            const Layout::Orientation layout_orientation(orientation == 0 ? Layout::Landscape
                                                                          : Layout::Portrait);
            QTest::newRow("No mouse events: expect empty commit string.")
                << layout_orientation
                << (QList<QMouseEvent *>())
                << "" << "" << FormatList();

            QTest::newRow("Only return pressed: expect empty commit string.")
                << layout_orientation
                << (QList<QMouseEvent *>() << createPressReleaseEvent(keyOriginLookup("return"), layout_orientation))
                << "" << "" << FormatList();

            QTest::newRow("Release outside of widget: expect empty commit string.")
                << layout_orientation
                << (QList<QMouseEvent *>() << createPressReleaseEvent(QPoint(g_size * 2, g_size * 2), layout_orientation)
                                           << createPressReleaseEvent(keyOriginLookup("return"), layout_orientation))
                << "" << "" << FormatList();

            QTest::newRow("Release button over key 'a': expect commit string 'a'.")
                << layout_orientation
                << (QList<QMouseEvent *>() << createPressReleaseEvent(keyOriginLookup("a"), layout_orientation)
                                           << createPressReleaseEvent(keyOriginLookup("return"), layout_orientation))
                << "a" << "a" << (FormatList() << Maliit::PreeditTextFormat(0, 1, Maliit::PreeditDefault));

            QTest::newRow("Release button over key 'a', but no commit: expect empty commit string.")
                << layout_orientation
                << (QList<QMouseEvent *>() << createPressReleaseEvent(keyOriginLookup("a"), layout_orientation))
                << "a" << "" << (FormatList() << Maliit::PreeditTextFormat(0, 1, Maliit::PreeditDefault));

            QTest::newRow("Release button over keys 'c, b, d, a': expect commit string 'cbda'.")
                << layout_orientation
                << (QList<QMouseEvent *>() << createPressReleaseEvent(keyOriginLookup("c"), layout_orientation)
                                           << createPressReleaseEvent(keyOriginLookup("b"), layout_orientation)
                                           << createPressReleaseEvent(keyOriginLookup("d"), layout_orientation)
                                           << createPressReleaseEvent(keyOriginLookup("a"), layout_orientation)
                                           << createPressReleaseEvent(keyOriginLookup("space"), layout_orientation))
                << "cbda" << "cbda " << (FormatList() << Maliit::PreeditTextFormat(0, 4, Maliit::PreeditDefault));

            QTest::newRow("Typing two words: expect commit string 'ab cd', with last preedit being 'cd'.")
                << layout_orientation
                << (QList<QMouseEvent *>() << createPressReleaseEvent(keyOriginLookup("a"), layout_orientation)
                                           << createPressReleaseEvent(keyOriginLookup("b"), layout_orientation)
                                           << createPressReleaseEvent(keyOriginLookup("space"), layout_orientation)
                                           << createPressReleaseEvent(keyOriginLookup("c"), layout_orientation)
                                           << createPressReleaseEvent(keyOriginLookup("d"), layout_orientation)
                                           << createPressReleaseEvent(keyOriginLookup("return"), layout_orientation))
                << "cd" << "ab cd" << (FormatList() << Maliit::PreeditTextFormat(0, 2, Maliit::PreeditDefault));

        }
    }

    Q_SLOT void test()
    {
        // FIXME: mikhas: We should have tests for the preedit &
        // preedit correctness stuff, and how it blends with word
        // prediction. I guess you will need to add
        // WordEngine::setSpellChecker() API so that you can inject a
        // fake spellchecker, for the tests. Otherwise, the test would
        // have to be skipped when there's no hunspell/presage, which
        // I wouldn't like to have.

        QFETCH(Layout::Orientation, orientation);
        QFETCH(QList<QMouseEvent*>, mouse_events);
        QFETCH(QString, expected_last_preedit_string);
        QFETCH(QString, expected_commit_string);
        QFETCH(QList<Maliit::PreeditTextFormat>, expected_preedit_format);

        Glass glass;
        Editor editor(EditorOptions(), new Model::Text, new Logic::WordEngine, 0);
        InputMethodHostProbe host;
        SharedLayout layout(new Layout);
        QSharedPointer<Maliit::Plugins::AbstractGraphicsViewSurface> surface(Maliit::Plugins::createTestGraphicsViewSurface());
        QSharedPointer<Maliit::Plugins::AbstractGraphicsViewSurface> extended_surface(Maliit::Plugins::createTestGraphicsViewSurface(surface));

        // geometry stuff is usually done by maliit-server, so we need
        // to do it manually here:
        //surface->view()->viewport()->setGeometry(0, 0, g_size, g_size);
        surface->view()->setSceneRect(0, 0, g_size, g_size);
        surface->scene()->setSceneRect(0, 0, g_size, g_size);
        glass.setSurface(surface);
        glass.setExtendedSurface(extended_surface);
        glass.addLayout(layout);
        editor.setHost(&host);
        layout->setOrientation(orientation);
        editor.setPreeditEnabled(true);

        Setup::connectGlassToTextEditor(&glass, &editor);
        const KeyArea &key_area(createAbcdArea());

        layout->setExtendedPanel(key_area);
        layout->setActivePanel(Layout::ExtendedPanel);

        Q_FOREACH (QMouseEvent *ev, mouse_events) {
            QApplication::instance()->postEvent(surface->view()->viewport(), ev);
        }

        TestUtils::waitForSignal(&glass, SIGNAL(keyReleased(Key,SharedLayout)));
        QCOMPARE(host.lastPreeditString(), expected_last_preedit_string);
        QCOMPARE(host.commitStringHistory(), expected_commit_string);
        QCOMPARE(host.lastPreeditTextFormatList(), expected_preedit_format);
    }
};

QTEST_MAIN(TestPreeditString)
#include "main.moc"
<commit_msg>Remove duplicate "if"<commit_after>/*
 * This file is part of Maliit Plugins
 *
 * Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). All rights reserved.
 *
 * Contact: Mohammad Anwari <Mohammad.Anwari@nokia.com>
 *
 * Redistribution and use in source and binary forms, with or without modification,
 * are permitted provided that the following conditions are met:
 *
 * Redistributions of source code must retain the above copyright notice, this list
 * of conditions and the following disclaimer.
 * Redistributions in binary form must reproduce the above copyright notice, this list
 * of conditions and the following disclaimer in the documentation and/or other materials
 * provided with the distribution.
 * Neither the name of Nokia Corporation nor the names of its contributors may be
 * used to endorse or promote products derived from this software without specific
 * prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
 * THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 */

#include "utils.h"

#include "models/area.h"
#include "models/key.h"
#include "models/keyarea.h"
#include "models/layout.h"
#include "models/text.h"
#include "view/glass.h"
#include "view/setup.h"
#include "logic/wordengine.h"
#include "plugin/editor.h"
#include "inputmethodhostprobe.h"

#include <maliit/plugins/testsurfacefactory.h>

#include <QtCore>
#include <QtTest>
#include <QWidget>
#include <QList>
#include <QMouseEvent>

using namespace MaliitKeyboard;
Q_DECLARE_METATYPE(Layout::Orientation)
Q_DECLARE_METATYPE(QList<QMouseEvent*>)

namespace {
const int g_size = 48;
const int g_divider = 3;

QPoint keyOriginLookup(const QString &name)
{
    static const int distance = g_size / g_divider;

    if (name == "a") {
        return QPoint(0, 0);
    } else if (name == "b") {
        return QPoint(distance, 0);
    } else if (name == "c") {
        return QPoint(0, distance);
    } else if (name == "d") {
        return QPoint(distance, distance);
    } else if (name == "space") {
        return QPoint(distance * 2, 0);
    } else if (name == "return") {
        return QPoint(distance * 2, distance);
    }

    return QPoint();
}

Key createKey(Key::Action action,
              const QString &text)
{
    static const QSize size(g_size / g_divider, g_size / g_divider);

    Key result;
    result.setAction(action);
    result.setOrigin(keyOriginLookup(text));
    result.rArea().setSize(size);
    result.rLabel().setText(text);

    return result;
}

// Populate KeyArea with six keys, a, b, c, d, space and return. Notice how the KeyArea
// covers the whole widget. Key width and height equals g_size / g_divider.
// .-----------.
// | a | b |<s>|
// |---|---|---|
// | c | d |<r>|
// `-----------'
KeyArea createAbcdArea()
{
    KeyArea key_area;
    Area area;
    area.setSize(QSize(g_size, g_size));
    key_area.setArea(area);

    key_area.rKeys().append(createKey(Key::ActionInsert, "a"));
    key_area.rKeys().append(createKey(Key::ActionInsert, "b"));
    key_area.rKeys().append(createKey(Key::ActionInsert, "c"));
    key_area.rKeys().append(createKey(Key::ActionInsert, "d"));
    key_area.rKeys().append(createKey(Key::ActionSpace,  "space"));
    key_area.rKeys().append(createKey(Key::ActionReturn, "return"));

    return key_area;
}

QList<QMouseEvent *> createPressReleaseEvent(const QPoint &origin,
                                             Layout::Orientation orientation)
{
    static const int offset(g_size / (g_divider * 2));

    QList<QMouseEvent *> result;
    QPoint pos = (orientation == Layout::Landscape) ? QPoint(origin.x() + offset, origin.y() + offset)
                                                    : QPoint(origin.y() + offset, g_size - (origin.x() + offset));

    result.append(new QMouseEvent(QKeyEvent::MouseButtonPress, pos, Qt::LeftButton, Qt::LeftButton, Qt::NoModifier));
    result.append(new QMouseEvent(QKeyEvent::MouseButtonRelease, pos, Qt::LeftButton, Qt::LeftButton, Qt::NoModifier));

    return result;
}
}

class TestPreeditString
    : public QObject
{
    Q_OBJECT

private:
    typedef QList<Maliit::PreeditTextFormat> FormatList;

    Q_SLOT void initTestCase()
    {
        qRegisterMetaType<QList<QMouseEvent*> >();
        qRegisterMetaType<Layout::Orientation>();
        qRegisterMetaType<FormatList>();
    }

    Q_SLOT void test_data()
    {
        QTest::addColumn<Layout::Orientation>("orientation");
        QTest::addColumn<QList<QMouseEvent*> >("mouse_events");
        QTest::addColumn<QString>("expected_last_preedit_string");
        QTest::addColumn<QString>("expected_commit_string");
        QTest::addColumn<FormatList>("expected_preedit_format");

        for (int orientation = 0; orientation < 1; ++orientation) {
            // FIXME: here should be 2          ^
            // FIXME: tests fail for portrait layouts
            const Layout::Orientation layout_orientation(orientation == 0 ? Layout::Landscape
                                                                          : Layout::Portrait);
            QTest::newRow("No mouse events: expect empty commit string.")
                << layout_orientation
                << (QList<QMouseEvent *>())
                << "" << "" << FormatList();

            QTest::newRow("Only return pressed: expect empty commit string.")
                << layout_orientation
                << (QList<QMouseEvent *>() << createPressReleaseEvent(keyOriginLookup("return"), layout_orientation))
                << "" << "" << FormatList();

            QTest::newRow("Release outside of widget: expect empty commit string.")
                << layout_orientation
                << (QList<QMouseEvent *>() << createPressReleaseEvent(QPoint(g_size * 2, g_size * 2), layout_orientation)
                                           << createPressReleaseEvent(keyOriginLookup("return"), layout_orientation))
                << "" << "" << FormatList();

            QTest::newRow("Release button over key 'a': expect commit string 'a'.")
                << layout_orientation
                << (QList<QMouseEvent *>() << createPressReleaseEvent(keyOriginLookup("a"), layout_orientation)
                                           << createPressReleaseEvent(keyOriginLookup("return"), layout_orientation))
                << "a" << "a" << (FormatList() << Maliit::PreeditTextFormat(0, 1, Maliit::PreeditDefault));

            QTest::newRow("Release button over key 'a', but no commit: expect empty commit string.")
                << layout_orientation
                << (QList<QMouseEvent *>() << createPressReleaseEvent(keyOriginLookup("a"), layout_orientation))
                << "a" << "" << (FormatList() << Maliit::PreeditTextFormat(0, 1, Maliit::PreeditDefault));

            QTest::newRow("Release button over keys 'c, b, d, a': expect commit string 'cbda'.")
                << layout_orientation
                << (QList<QMouseEvent *>() << createPressReleaseEvent(keyOriginLookup("c"), layout_orientation)
                                           << createPressReleaseEvent(keyOriginLookup("b"), layout_orientation)
                                           << createPressReleaseEvent(keyOriginLookup("d"), layout_orientation)
                                           << createPressReleaseEvent(keyOriginLookup("a"), layout_orientation)
                                           << createPressReleaseEvent(keyOriginLookup("space"), layout_orientation))
                << "cbda" << "cbda " << (FormatList() << Maliit::PreeditTextFormat(0, 4, Maliit::PreeditDefault));

            QTest::newRow("Typing two words: expect commit string 'ab cd', with last preedit being 'cd'.")
                << layout_orientation
                << (QList<QMouseEvent *>() << createPressReleaseEvent(keyOriginLookup("a"), layout_orientation)
                                           << createPressReleaseEvent(keyOriginLookup("b"), layout_orientation)
                                           << createPressReleaseEvent(keyOriginLookup("space"), layout_orientation)
                                           << createPressReleaseEvent(keyOriginLookup("c"), layout_orientation)
                                           << createPressReleaseEvent(keyOriginLookup("d"), layout_orientation)
                                           << createPressReleaseEvent(keyOriginLookup("return"), layout_orientation))
                << "cd" << "ab cd" << (FormatList() << Maliit::PreeditTextFormat(0, 2, Maliit::PreeditDefault));

        }
    }

    Q_SLOT void test()
    {
        // FIXME: mikhas: We should have tests for the preedit &
        // preedit correctness stuff, and how it blends with word
        // prediction. I guess you will need to add
        // WordEngine::setSpellChecker() API so that you can inject a
        // fake spellchecker, for the tests. Otherwise, the test would
        // have to be skipped when there's no hunspell/presage, which
        // I wouldn't like to have.

        QFETCH(Layout::Orientation, orientation);
        QFETCH(QList<QMouseEvent*>, mouse_events);
        QFETCH(QString, expected_last_preedit_string);
        QFETCH(QString, expected_commit_string);
        QFETCH(QList<Maliit::PreeditTextFormat>, expected_preedit_format);

        Glass glass;
        Editor editor(EditorOptions(), new Model::Text, new Logic::WordEngine, 0);
        InputMethodHostProbe host;
        SharedLayout layout(new Layout);
        QSharedPointer<Maliit::Plugins::AbstractGraphicsViewSurface> surface(Maliit::Plugins::createTestGraphicsViewSurface());
        QSharedPointer<Maliit::Plugins::AbstractGraphicsViewSurface> extended_surface(Maliit::Plugins::createTestGraphicsViewSurface(surface));

        // geometry stuff is usually done by maliit-server, so we need
        // to do it manually here:
        //surface->view()->viewport()->setGeometry(0, 0, g_size, g_size);
        surface->view()->setSceneRect(0, 0, g_size, g_size);
        surface->scene()->setSceneRect(0, 0, g_size, g_size);
        glass.setSurface(surface);
        glass.setExtendedSurface(extended_surface);
        glass.addLayout(layout);
        editor.setHost(&host);
        layout->setOrientation(orientation);
        editor.setPreeditEnabled(true);

        Setup::connectGlassToTextEditor(&glass, &editor);
        const KeyArea &key_area(createAbcdArea());

        layout->setExtendedPanel(key_area);
        layout->setActivePanel(Layout::ExtendedPanel);

        Q_FOREACH (QMouseEvent *ev, mouse_events) {
            QApplication::instance()->postEvent(surface->view()->viewport(), ev);
        }

        TestUtils::waitForSignal(&glass, SIGNAL(keyReleased(Key,SharedLayout)));
        QCOMPARE(host.lastPreeditString(), expected_last_preedit_string);
        QCOMPARE(host.commitStringHistory(), expected_commit_string);
        QCOMPARE(host.lastPreeditTextFormatList(), expected_preedit_format);
    }
};

QTEST_MAIN(TestPreeditString)
#include "main.moc"
<|endoftext|>


<commit_before>#include <blackhole/blackhole.hpp>
#include <blackhole/formatter/string.hpp>
#include <blackhole/frontend/syslog.hpp>
#include <blackhole/scoped_attributes.hpp>
#include <blackhole/sink/null.hpp>
#include <blackhole/sink/stream.hpp>
#include <blackhole/sink/syslog.hpp>

#include "global.hpp"

using namespace blackhole;

namespace blackhole { namespace sink {

template<>
struct priority_traits<level> {
    static inline
    priority_t map(testing::level lvl) {
        switch (lvl) {
        case testing::level::debug:
            return priority_t::debug;
        case testing::level::info:
            return priority_t::info;
        case testing::level::warn:
            return priority_t::warning;
        case testing::level::error:
            return priority_t::err;
        }

        return priority_t::debug;
    }
};

} } // namespace blackhole::sink

TEST(Functional, SyslogConfiguredVerboseLogger) {
    verbose_logger_t<level> log(level::debug);

    typedef formatter::string_t formatter_type;
    typedef sink::syslog_t<level> sink_type;

    auto formatter = aux::util::make_unique<formatter_type>("%(message)s [%(...L)s]");
    auto sink = aux::util::make_unique<sink_type>("testing");
    auto frontend = aux::util::make_unique<frontend_t<formatter_type, sink_type>>(std::move(formatter), std::move(sink));
    log.add_frontend(std::move(frontend));

    record_t record = log.open_record(level::error);
    if (record.valid()) {
        record.insert(keyword::message() = utils::format("Some message from: '%s'!", "Hell"));
        log.push(std::move(record));
    }
}

TEST(Functional, Manual) {
    using aux::util::make_unique;

    typedef formatter::string_t                   formatter_type;
    typedef sink::null_t                          sink_type;
    typedef frontend_t<formatter_type, sink_type> frontend_type;
    typedef verbose_logger_t<level>               logger_type;

    verbose_logger_t<testing::level> log(testing::debug);

    // Factory starts here...
    auto formatter = make_unique<formatter_type>("[]: %(message)s [%(...)s]");
    auto sink      = make_unique<sink_type>();
    auto frontend  = make_unique<frontend_type>(std::move(formatter), std::move(sink));

    // ... till here.
    log.add_frontend(std::move(frontend));

    // Next lines can be hidden via logging macro.
    record_t record = log.open_record(testing::level::error);
    if (record.valid()) {
        record.insert(keyword::message() = utils::format("Some message from: '%s'!", "Hell"));
        // Here we can add another attributes, but just push the record.
        log.push(std::move(record));
    }
}

TEST(Functional, LoggerShouldProperlyRouteAttributesByScope) {
    /*
     * We define full Blackhole's util stack: logger, wrapper, scoped attributes
     * and user specific attributes.
     * We expect, that all external attributes appear in variadic placeholder.
     * External attributes are:
     *  - Logger attached.
     *  - Wrapper attached.
     *  - Scoped.
     *  - User defined (via macro)
     */
    using aux::util::make_unique;

    typedef formatter::string_t                   formatter_type;
    typedef sink::stream_t                        sink_type;
    typedef frontend_t<formatter_type, sink_type> frontend_type;
    typedef verbose_logger_t<level>               logger_type;

    std::ostringstream stream;
    logger_type log(level::debug);

    auto formatter = make_unique<formatter_type>("[%(severity)s]: %(message)s %(...:[:])s");
    auto sink      = make_unique<sink_type>(stream);
    auto frontend  = make_unique<frontend_type>(std::move(formatter), std::move(sink));
    log.add_frontend(std::move(frontend));

    wrapper_t<logger_type> wrapper(log, attribute::set_t({{ "w1", attribute_t(42) }}));

    scoped_attributes_t scope(wrapper, attribute::set_t({{ "s1", attribute_t(10) }}));

    BH_LOG(wrapper, level::debug, "message is so %s", "message")("u1", "value");

    auto actual = stream.str();
    EXPECT_THAT(actual, AnyOf(
        Eq("[0]: message is so message [w1: 42, s1: 10, u1: value]\n"),
        Eq("[0]: message is so message [w1: 42, u1: value, s1: 10]\n"),
        Eq("[0]: message is so message [u1: value, s1: 10, w1: 42]\n"),
        Eq("[0]: message is so message [u1: value, w1: 42, s1: 10]\n"),
        Eq("[0]: message is so message [s1: 10, u1: value, w1: 42]\n"),
        Eq("[0]: message is so message [s1: 10, w1: 42, u1: value]\n")
    ));
}
<commit_msg>[Unit Testing] More refactoring.<commit_after>#include <blackhole/blackhole.hpp>
#include <blackhole/formatter/string.hpp>
#include <blackhole/frontend/syslog.hpp>
#include <blackhole/scoped_attributes.hpp>
#include <blackhole/sink/null.hpp>
#include <blackhole/sink/stream.hpp>
#include <blackhole/sink/syslog.hpp>

#include "global.hpp"

using namespace blackhole;

namespace blackhole { namespace sink {

template<>
struct priority_traits<level> {
    static inline
    priority_t map(testing::level lvl) {
        switch (lvl) {
        case testing::level::debug:
            return priority_t::debug;
        case testing::level::info:
            return priority_t::info;
        case testing::level::warn:
            return priority_t::warning;
        case testing::level::error:
            return priority_t::err;
        }

        return priority_t::debug;
    }
};

} } // namespace blackhole::sink

TEST(Functional, SyslogConfiguredVerboseLogger) {
    using aux::util::make_unique;

    typedef formatter::string_t                   formatter_type;
    typedef sink::syslog_t<level>                 sink_type;
    typedef frontend_t<formatter_type, sink_type> frontend_type;
    typedef verbose_logger_t<level>               logger_type;

    logger_type log(testing::debug);

    auto formatter = make_unique<formatter_type>("%(message)s [%(...L)s]");
    auto sink      = make_unique<sink_type>("testing");
    auto frontend  = make_unique<frontend_type>(std::move(formatter), std::move(sink));
    log.add_frontend(std::move(frontend));

    record_t record = log.open_record(level::error);
    if (record.valid()) {
        record.insert(keyword::message() = utils::format("Some message from: '%s'!", "Hell"));
        log.push(std::move(record));
    }
}

TEST(Functional, Manual) {
    using aux::util::make_unique;

    typedef formatter::string_t                   formatter_type;
    typedef sink::null_t                          sink_type;
    typedef frontend_t<formatter_type, sink_type> frontend_type;
    typedef verbose_logger_t<level>               logger_type;

    verbose_logger_t<testing::level> log(testing::debug);

    // Factory starts here...
    auto formatter = make_unique<formatter_type>("[]: %(message)s [%(...)s]");
    auto sink      = make_unique<sink_type>();
    auto frontend  = make_unique<frontend_type>(std::move(formatter), std::move(sink));

    // ... till here.
    log.add_frontend(std::move(frontend));

    // Next lines can be hidden via logging macro.
    record_t record = log.open_record(testing::level::error);
    if (record.valid()) {
        record.insert(keyword::message() = utils::format("Some message from: '%s'!", "Hell"));
        // Here we can add another attributes, but just push the record.
        log.push(std::move(record));
    }
}

TEST(Functional, LoggerShouldProperlyRouteAttributesByScope) {
    /*
     * We define full Blackhole's util stack: logger, wrapper, scoped attributes
     * and user specific attributes.
     * We expect, that all external attributes appear in variadic placeholder.
     * External attributes are:
     *  - Logger attached.
     *  - Wrapper attached.
     *  - Scoped.
     *  - User defined (via macro)
     */
    using aux::util::make_unique;

    typedef formatter::string_t                   formatter_type;
    typedef sink::stream_t                        sink_type;
    typedef frontend_t<formatter_type, sink_type> frontend_type;
    typedef verbose_logger_t<level>               logger_type;

    std::ostringstream stream;
    logger_type log(level::debug);

    auto formatter = make_unique<formatter_type>("[%(severity)s]: %(message)s %(...:[:])s");
    auto sink      = make_unique<sink_type>(stream);
    auto frontend  = make_unique<frontend_type>(std::move(formatter), std::move(sink));
    log.add_frontend(std::move(frontend));

    wrapper_t<logger_type> wrapper(log, attribute::set_t({{ "w1", attribute_t(42) }}));

    scoped_attributes_t scope(wrapper, attribute::set_t({{ "s1", attribute_t(10) }}));

    BH_LOG(wrapper, level::debug, "message is so %s", "message")("u1", "value");

    auto actual = stream.str();
    EXPECT_THAT(actual, AnyOf(
        Eq("[0]: message is so message [w1: 42, s1: 10, u1: value]\n"),
        Eq("[0]: message is so message [w1: 42, u1: value, s1: 10]\n"),
        Eq("[0]: message is so message [u1: value, s1: 10, w1: 42]\n"),
        Eq("[0]: message is so message [u1: value, w1: 42, s1: 10]\n"),
        Eq("[0]: message is so message [s1: 10, u1: value, w1: 42]\n"),
        Eq("[0]: message is so message [s1: 10, w1: 42, u1: value]\n")
    ));
}
<|endoftext|>


<commit_before>/*
 * Copyright 2009-2018 The VOTCA Development Team (http://www.votca.org)
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */

#define BOOST_TEST_MAIN

#define BOOST_TEST_MODULE cubicspline_test
#include <boost/test/unit_test.hpp>
#include <votca/tools/cubicspline.h>
#include <iostream>

using namespace votca::tools;

BOOST_AUTO_TEST_SUITE(cubicspline_test)

BOOST_AUTO_TEST_CASE(cubicspline_fit_test) {

  int size=80;
  Eigen::VectorXd x=Eigen::VectorXd::Zero(size);
  Eigen::VectorXd y=Eigen::VectorXd::Zero(size);
  for (int i=0;i<size;++i){
    x(i)=0.25*i;
    y(i)=std::sin(x(i));
  }
  CubicSpline cspline;
  cspline.setBCInt(0);
  cspline.GenerateGrid(0.4,0.6,0.1);
  cspline.Fit(x,y);
  Eigen::VectorXd Fref=Eigen::VectorXd::Zero(3);
  Eigen::VectorXd F2ref=Eigen::VectorXd::Zero(3);
  Fref(0)=0.313364;
  Fref(1)=0.309062;
  Fref(2)=0.304759;
  F2ref(0)=0;
  F2ref(1)=-4.10698e-05;
  F2ref(2)=-7.3746e-17;
  Eigen::VectorXd F=cspline.getSplineF();
  Eigen::VectorXd F2=cspline.getSplineF2();

  bool equal1=Fref.isApprox(F,1e-5);
  if(!equal1){
    std::cout<<"result F"<<std::endl;
  std::cout<<F<<std::endl;
   std::cout<<"ref F"<<std::endl;
  std::cout<<Fref<<std::endl;
  }
  BOOST_CHECK_EQUAL(equal1, true);

  bool equal2=F2ref.isApprox(F2,1e-5);

  if(!equal2){
    std::cout<<"result F2"<<std::endl;
  std::cout<<F2<<std::endl;
   std::cout<<"ref F2"<<std::endl;
  std::cout<<F2ref<<std::endl;
  }
  BOOST_CHECK_EQUAL(equal2, true);

}

BOOST_AUTO_TEST_CASE(cubicspline_matrix_test) {

  CubicSpline cspline;
  cspline.setBCInt(0);
  cspline.GenerateGrid(0.4,0.6,0.1);
  Eigen::MatrixXd A=Eigen::MatrixXd::Zero(1,6);
  Eigen::MatrixXd Aref=Eigen::MatrixXd::Zero(1,6);

  Aref(0,0)=-4.5;
  Aref(0,1)=5.5;
  Aref(0,2)=0.0;
  Aref(0,3)=0.0058333333333;
  Aref(0,4)=-0.010833333333;
  Aref(0,5)=0.0;

  cspline.AddToFitMatrix(A,0.5,0,0,1.0,1.0);

  bool equalMatrix=Aref.isApprox(A,1e-5);
  if(!equalMatrix){
    std::cout<<"result A"<<std::endl;
    std::cout<<A<<std::endl;
    std::cout<<"ref A"<<std::endl;
    std::cout<<Aref<<std::endl;
  }
  BOOST_CHECK_EQUAL(equalMatrix, true);
}

BOOST_AUTO_TEST_SUITE_END()
<commit_msg>corrected unit test  test_cubicspline.cc<commit_after>/*
 * Copyright 2009-2018 The VOTCA Development Team (http://www.votca.org)
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */

#define BOOST_TEST_MAIN

#define BOOST_TEST_MODULE cubicspline_test
#include <boost/test/unit_test.hpp>
#include <votca/tools/cubicspline.h>
#include <iostream>

using namespace votca::tools;

BOOST_AUTO_TEST_SUITE(cubicspline_test)

BOOST_AUTO_TEST_CASE(cubicspline_fit_test) {

  int size=80;
  Eigen::VectorXd x=Eigen::VectorXd::Zero(size);
  Eigen::VectorXd y=Eigen::VectorXd::Zero(size);
  for (int i=0;i<size;++i){
    x(i)=0.25*i;
    y(i)=std::sin(x(i));
  }
  CubicSpline cspline;
  cspline.setBCInt(0);
  cspline.GenerateGrid(0.4,0.6,0.1);
  cspline.Fit(x,y);
  Eigen::VectorXd Fref=Eigen::VectorXd::Zero(3);
  Eigen::VectorXd F2ref=Eigen::VectorXd::Zero(3);
  Fref(0)=0.313364;
  Fref(1)=0.309062;
  Fref(2)=0.304759;
  F2ref(0)=0;
  F2ref(1)=-4.10698e-05;
  F2ref(2)=-7.3746e-17;
  Eigen::VectorXd F=cspline.getSplineF();
  Eigen::VectorXd F2=cspline.getSplineF2();

  bool equal1=Fref.isApprox(F,1e-5);
  if(!equal1){
    std::cout<<"result F"<<std::endl;
  std::cout<<F<<std::endl;
   std::cout<<"ref F"<<std::endl;
  std::cout<<Fref<<std::endl;
  }
  BOOST_CHECK_EQUAL(equal1, true);

  bool equal2=F2ref.isApprox(F2,1e-5);

  if(!equal2){
    std::cout<<"result F2"<<std::endl;
  std::cout<<F2<<std::endl;
   std::cout<<"ref F2"<<std::endl;
  std::cout<<F2ref<<std::endl;
  }
  BOOST_CHECK_EQUAL(equal2, true);

}

BOOST_AUTO_TEST_CASE(cubicspline_matrix_test) {

  CubicSpline cspline;
  cspline.setBCInt(0);
  cspline.GenerateGrid(0.4,0.6,0.1);
  Eigen::MatrixXd A=Eigen::MatrixXd::Zero(1,6);
  Eigen::MatrixXd Aref=Eigen::MatrixXd::Zero(1,6);

  Aref(0,0)=0.0;
  Aref(0,1)=-9.0;
  Aref(0,2)=10.0;
  Aref(0,3)=0.0;
  Aref(0,4)=-0.03333333;
  Aref(0,5)=-0.01666667;

  cspline.AddToFitMatrix(A,0.5,0,0,1.0,1.0);

  bool equalMatrix=Aref.isApprox(A,1e-5);
  if(!equalMatrix){
    std::cout<<"result A"<<std::endl;
    std::cout<<A<<std::endl;
    std::cout<<"ref A"<<std::endl;
    std::cout<<Aref<<std::endl;
  }
  BOOST_CHECK_EQUAL(equalMatrix, true);
}

BOOST_AUTO_TEST_SUITE_END()
<|endoftext|>


<commit_before>// Copyright (c) 2017-2021 offa
// Copyright 2011 Ciaran McHale.
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions.
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
// BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.

//--------
// #include's
//--------
#include "Config2Cpp.h"
#include "danek/Configuration.h"
#include "danek/PatternMatch.h"
#include "danek/SchemaValidator.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

using namespace danek;

void calculateRuleForName(const Configuration* cfg, const char* name, const char* uName,
                          const StringVector& wildcardedNamesAndTypes, StringBuffer& rule)
{
    rule.clear();
    int len = wildcardedNamesAndTypes.size();
    for (int i = 0; i < len; i += 3)
    {
        const char* keyword = wildcardedNamesAndTypes[i + 0].c_str(); // @optional or @required
        const char* wildcardedName = wildcardedNamesAndTypes[i + 1].c_str();
        const char* type = wildcardedNamesAndTypes[i + 2].c_str();
        if (patternMatch(uName, wildcardedName))
        {
            rule << keyword << " " << uName << " = " << type;
            return;
        }
    }

    //--------
    // We couldn's determine the type from the wildcarded_names_and_types
    // table. So we fall back to using heuristics to guess a good type.
    //--------
    if (cfg->type("", name) == ConfType::Scope)
    {
        rule << uName << " = scope";
    }
    else if (cfg->type("", name) == ConfType::List)
    {
        rule << uName << " = list[string]";
    }
    else
    {
        const char* str = cfg->lookupString("", name);
        if (cfg->isBoolean(str))
        {
            rule << uName << " = boolean";
        }
        else if (cfg->isInt(str))
        {
            rule << uName << " = int";
        }
        else if (cfg->isFloat(str))
        {
            rule << uName << " = float";
        }
        else if (cfg->isDurationSeconds(str))
        {
            rule << uName << " = durationSeconds";
        }
        else if (cfg->isDurationMilliseconds(str))
        {
            rule << uName << " = durationMilliseconds";
        }
        else if (cfg->isDurationMicroseconds(str))
        {
            rule << uName << " = durationMicroseconds";
        }
        else if (cfg->isMemorySizeBytes(str))
        {
            rule << uName << " = memorySizeBytes";
        }
        else if (cfg->isMemorySizeKB(str))
        {
            rule << uName << " = memorySizeKB";
        }
        else if (cfg->isMemorySizeMB(str))
        {
            rule << uName << " = memorySizeMB";
        }
        else
        {
            rule << uName << " = string";
        }
    }
}

bool doesVectorcontainString(const StringVector& vec, const char* str)
{
    int len = vec.size();
    for (int i = 0; i < len; ++i)
    {
        if (strcmp(vec[i].c_str(), str) == 0)
        {
            return true;
        }
    }
    return false;
}

void calculateSchema(const Configuration* cfg, const StringVector& namesList, const StringVector& recipeUserTypes,
                     const StringVector& wildcardedNamesAndTypes, const StringVector& recipeIgnoreRules, StringVector& schema)
{
    StringBuffer rule;
    StringBuffer buf;
    StringVector uidNames;

    schema.clear();

    for (const auto& str : recipeIgnoreRules)
    {
        schema.push_back(str);
    }

    for (const auto& str : recipeUserTypes)
    {
        schema.push_back(str);
    }

    int len = namesList.size();
    for (int i = 0; i < len; ++i)
    {
        const char* name = namesList[i].c_str();
        if (strstr(name, "uid-") == nullptr)
        {
            calculateRuleForName(cfg, name, name, wildcardedNamesAndTypes, rule);
            schema.push_back(rule.str());
        }
        else
        {
            const auto uName = cfg->unexpandUid(name, buf);
            if (!doesVectorcontainString(uidNames, uName.c_str()))
            {
                uidNames.push_back(uName);
                calculateRuleForName(cfg, name, uName.c_str(), wildcardedNamesAndTypes, rule);
                schema.push_back(rule.str());
            }
        }
    }
}

bool doesPatternMatchAnyUnexpandedNameInList(const Configuration* cfg, const char* pattern, const StringVector& namesList)
{
    StringBuffer buf;

    int len = namesList.size();
    for (int i = 0; i < len; ++i)
    {
        const auto uName = cfg->unexpandUid(namesList[i].c_str(), buf);
        if (patternMatch(uName.c_str(), pattern))
        {
            return true;
        }
    }
    return false;
}

void checkForUnmatchedPatterns(const Configuration* cfg, const StringVector& namesList,
                               const StringVector& wildcardedNamesAndTypes, StringVector& unmatchedPatterns)
{
    unmatchedPatterns.clear();
    //--------
    // Check if there is a wildcarded name that does not match anything
    //--------
    int len = wildcardedNamesAndTypes.size();
    for (int i = 0; i < len; i += 3)
    {
        const char* wildcardedName = wildcardedNamesAndTypes[i + 1].c_str();
        if (!doesPatternMatchAnyUnexpandedNameInList(cfg, wildcardedName, namesList))
        {
            unmatchedPatterns.push_back(wildcardedName);
        }
    }
}

//----------------------------------------------------------------------
// File: main()
//
// Description: Mainline of "config2cpp"
//----------------------------------------------------------------------

int main(int argc, char** argv)
{
    Config2Cpp util("config2cpp");
    StringVector namesList;
    StringVector recipeUserTypes;
    StringVector wildcardedNamesAndTypes;
    StringVector recipeIgnoreRules;
    StringVector unmatchedPatterns;
    StringVector schema;
    SchemaValidator sv;

    bool ok = util.parseCmdLineArgs(argc, argv);

    Configuration* cfg = Configuration::create();
    Configuration* schemaCfg = Configuration::create();
    if (ok && util.wantSchema())
    {
        try
        {
            cfg->parse(util.cfgFileName());
            cfg->listFullyScopedNames("", "", ConfType::ScopesAndVars, true, namesList);
            if (util.schemaOverrideCfg() != nullptr)
            {
                const char* overrideSchema[] = {
                    "@typedef keyword = enum[\"@optional\", \"@required\"]", "user_types = list[string]",
                    "wildcarded_names_and_types = table[keyword,keyword, "
                    "string,wildcarded-name, string,type]",
                    "ignore_rules = list[string]",
                    nullptr // null-terminated array
                };

                schemaCfg->parse(util.schemaOverrideCfg());
                const char* scope = util.schemaOverrideScope();
                sv.parseSchema(overrideSchema);
                sv.validate(schemaCfg, scope, "");
                schemaCfg->lookupList(scope, "user_types", recipeUserTypes);
                schemaCfg->lookupList(scope, "wildcarded_names_and_types", wildcardedNamesAndTypes);
                schemaCfg->lookupList(scope, "ignore_rules", recipeIgnoreRules);
            }
            calculateSchema(cfg, namesList, recipeUserTypes, wildcardedNamesAndTypes, recipeIgnoreRules, schema);
            checkForUnmatchedPatterns(cfg, namesList, wildcardedNamesAndTypes, unmatchedPatterns);
        }
        catch (const ConfigurationException& ex)
        {
            fprintf(stderr, "%s\n", ex.what());
            ok = false;
        }
        int len = unmatchedPatterns.size();
        if (len != 0)
        {
            fprintf(stderr, "%s %s\n", "Error: the following patterns in the schema", "recipe did not match anything");
            for (int i = 0; i < len; i++)
            {
                fprintf(stderr, "\t'%s'\n", unmatchedPatterns[i].c_str());
            }
            ok = false;
        }
    }

    if (ok)
    {
        const auto data = schema.get();
        std::vector<const char*> buffer; // Deprecated conversion; kept for compatibility

        for (const auto& str : data)
        {
            buffer.push_back(&str.front());
        }

        ok = util.generateFiles(buffer.data(), buffer.size());
    }

    cfg->destroy();
    schemaCfg->destroy();

    return (ok ? 0 : 1);
}
<commit_msg>Loop replaced with algorithm.<commit_after>// Copyright (c) 2017-2021 offa
// Copyright 2011 Ciaran McHale.
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions.
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
// BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
// ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
// CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.

//--------
// #include's
//--------
#include "Config2Cpp.h"
#include "danek/Configuration.h"
#include "danek/PatternMatch.h"
#include "danek/SchemaValidator.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

using namespace danek;

void calculateRuleForName(const Configuration* cfg, const char* name, const char* uName,
                          const StringVector& wildcardedNamesAndTypes, StringBuffer& rule)
{
    rule.clear();
    int len = wildcardedNamesAndTypes.size();
    for (int i = 0; i < len; i += 3)
    {
        const char* keyword = wildcardedNamesAndTypes[i + 0].c_str(); // @optional or @required
        const char* wildcardedName = wildcardedNamesAndTypes[i + 1].c_str();
        const char* type = wildcardedNamesAndTypes[i + 2].c_str();
        if (patternMatch(uName, wildcardedName))
        {
            rule << keyword << " " << uName << " = " << type;
            return;
        }
    }

    //--------
    // We couldn's determine the type from the wildcarded_names_and_types
    // table. So we fall back to using heuristics to guess a good type.
    //--------
    if (cfg->type("", name) == ConfType::Scope)
    {
        rule << uName << " = scope";
    }
    else if (cfg->type("", name) == ConfType::List)
    {
        rule << uName << " = list[string]";
    }
    else
    {
        const char* str = cfg->lookupString("", name);
        if (cfg->isBoolean(str))
        {
            rule << uName << " = boolean";
        }
        else if (cfg->isInt(str))
        {
            rule << uName << " = int";
        }
        else if (cfg->isFloat(str))
        {
            rule << uName << " = float";
        }
        else if (cfg->isDurationSeconds(str))
        {
            rule << uName << " = durationSeconds";
        }
        else if (cfg->isDurationMilliseconds(str))
        {
            rule << uName << " = durationMilliseconds";
        }
        else if (cfg->isDurationMicroseconds(str))
        {
            rule << uName << " = durationMicroseconds";
        }
        else if (cfg->isMemorySizeBytes(str))
        {
            rule << uName << " = memorySizeBytes";
        }
        else if (cfg->isMemorySizeKB(str))
        {
            rule << uName << " = memorySizeKB";
        }
        else if (cfg->isMemorySizeMB(str))
        {
            rule << uName << " = memorySizeMB";
        }
        else
        {
            rule << uName << " = string";
        }
    }
}

bool doesVectorcontainString(const StringVector& vec, const char* str)
{
    int len = vec.size();
    for (int i = 0; i < len; ++i)
    {
        if (strcmp(vec[i].c_str(), str) == 0)
        {
            return true;
        }
    }
    return false;
}

void calculateSchema(const Configuration* cfg, const StringVector& namesList, const StringVector& recipeUserTypes,
                     const StringVector& wildcardedNamesAndTypes, const StringVector& recipeIgnoreRules, StringVector& schema)
{
    StringBuffer rule;
    StringBuffer buf;
    StringVector uidNames;

    schema.clear();

    for (const auto& str : recipeIgnoreRules)
    {
        schema.push_back(str);
    }

    for (const auto& str : recipeUserTypes)
    {
        schema.push_back(str);
    }

    int len = namesList.size();
    for (int i = 0; i < len; ++i)
    {
        const char* name = namesList[i].c_str();
        if (strstr(name, "uid-") == nullptr)
        {
            calculateRuleForName(cfg, name, name, wildcardedNamesAndTypes, rule);
            schema.push_back(rule.str());
        }
        else
        {
            const auto uName = cfg->unexpandUid(name, buf);
            if (!doesVectorcontainString(uidNames, uName.c_str()))
            {
                uidNames.push_back(uName);
                calculateRuleForName(cfg, name, uName.c_str(), wildcardedNamesAndTypes, rule);
                schema.push_back(rule.str());
            }
        }
    }
}

bool doesPatternMatchAnyUnexpandedNameInList(const Configuration* cfg, const char* pattern, const StringVector& namesList)
{
    StringBuffer buf;

    int len = namesList.size();
    for (int i = 0; i < len; ++i)
    {
        const auto uName = cfg->unexpandUid(namesList[i].c_str(), buf);
        if (patternMatch(uName.c_str(), pattern))
        {
            return true;
        }
    }
    return false;
}

void checkForUnmatchedPatterns(const Configuration* cfg, const StringVector& namesList,
                               const StringVector& wildcardedNamesAndTypes, StringVector& unmatchedPatterns)
{
    unmatchedPatterns.clear();
    //--------
    // Check if there is a wildcarded name that does not match anything
    //--------
    int len = wildcardedNamesAndTypes.size();
    for (int i = 0; i < len; i += 3)
    {
        const char* wildcardedName = wildcardedNamesAndTypes[i + 1].c_str();
        if (!doesPatternMatchAnyUnexpandedNameInList(cfg, wildcardedName, namesList))
        {
            unmatchedPatterns.push_back(wildcardedName);
        }
    }
}

//----------------------------------------------------------------------
// File: main()
//
// Description: Mainline of "config2cpp"
//----------------------------------------------------------------------

int main(int argc, char** argv)
{
    Config2Cpp util("config2cpp");
    StringVector namesList;
    StringVector recipeUserTypes;
    StringVector wildcardedNamesAndTypes;
    StringVector recipeIgnoreRules;
    StringVector unmatchedPatterns;
    StringVector schema;
    SchemaValidator sv;

    bool ok = util.parseCmdLineArgs(argc, argv);

    Configuration* cfg = Configuration::create();
    Configuration* schemaCfg = Configuration::create();
    if (ok && util.wantSchema())
    {
        try
        {
            cfg->parse(util.cfgFileName());
            cfg->listFullyScopedNames("", "", ConfType::ScopesAndVars, true, namesList);
            if (util.schemaOverrideCfg() != nullptr)
            {
                const char* overrideSchema[] = {
                    "@typedef keyword = enum[\"@optional\", \"@required\"]", "user_types = list[string]",
                    "wildcarded_names_and_types = table[keyword,keyword, "
                    "string,wildcarded-name, string,type]",
                    "ignore_rules = list[string]",
                    nullptr // null-terminated array
                };

                schemaCfg->parse(util.schemaOverrideCfg());
                const char* scope = util.schemaOverrideScope();
                sv.parseSchema(overrideSchema);
                sv.validate(schemaCfg, scope, "");
                schemaCfg->lookupList(scope, "user_types", recipeUserTypes);
                schemaCfg->lookupList(scope, "wildcarded_names_and_types", wildcardedNamesAndTypes);
                schemaCfg->lookupList(scope, "ignore_rules", recipeIgnoreRules);
            }
            calculateSchema(cfg, namesList, recipeUserTypes, wildcardedNamesAndTypes, recipeIgnoreRules, schema);
            checkForUnmatchedPatterns(cfg, namesList, wildcardedNamesAndTypes, unmatchedPatterns);
        }
        catch (const ConfigurationException& ex)
        {
            fprintf(stderr, "%s\n", ex.what());
            ok = false;
        }
        if (const auto len = unmatchedPatterns.size(); len != 0)
        {
            fprintf(stderr, "%s %s\n", "Error: the following patterns in the schema", "recipe did not match anything");
            std::for_each(std::begin(unmatchedPatterns), std::end(unmatchedPatterns), [](const auto& element) {
                fprintf(stderr, "\t'%s'\n", element.c_str());
            });
            ok = false;
        }
    }

    if (ok)
    {
        const auto data = schema.get();
        std::vector<const char*> buffer; // Deprecated conversion; kept for compatibility

        for (const auto& str : data)
        {
            buffer.push_back(&str.front());
        }

        ok = util.generateFiles(buffer.data(), buffer.size());
    }

    cfg->destroy();
    schemaCfg->destroy();

    return (ok ? 0 : 1);
}
<|endoftext|>