[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[lmi-commits] [5995] Augment automated GUI test
From: |
Greg Chicares |
Subject: |
[lmi-commits] [5995] Augment automated GUI test |
Date: |
Sat, 25 Oct 2014 14:42:27 +0000 |
Revision: 5995
http://svn.sv.gnu.org/viewvc/?view=rev&root=lmi&revision=5995
Author: chicares
Date: 2014-10-25 14:42:26 +0000 (Sat, 25 Oct 2014)
Log Message:
-----------
Augment automated GUI test
Modified Paths:
--------------
lmi/trunk/ChangeLog
lmi/trunk/Makefile.am
lmi/trunk/main_wx_test.cpp
lmi/trunk/objects.make
lmi/trunk/skeleton.hpp
Added Paths:
-----------
lmi/trunk/wx_test_about_version.cpp
lmi/trunk/wx_test_benchmark_census.cpp
lmi/trunk/wx_test_calculation_summary.cpp
lmi/trunk/wx_test_case.hpp
lmi/trunk/wx_test_config_settings.cpp
lmi/trunk/wx_test_create_open.cpp
lmi/trunk/wx_test_default_input.cpp
lmi/trunk/wx_test_default_update.cpp
lmi/trunk/wx_test_expiry_dates.cpp
lmi/trunk/wx_test_extract.cpp
lmi/trunk/wx_test_input_sequences.cpp
lmi/trunk/wx_test_input_validation.cpp
lmi/trunk/wx_test_mvc_dialog.hpp
lmi/trunk/wx_test_new.hpp
lmi/trunk/wx_test_paste_census.cpp
lmi/trunk/wx_test_pdf_create.cpp
lmi/trunk/wx_test_statusbar.hpp
lmi/trunk/wx_test_validate_output.cpp
Modified: lmi/trunk/ChangeLog
===================================================================
--- lmi/trunk/ChangeLog 2014-10-21 13:58:38 UTC (rev 5994)
+++ lmi/trunk/ChangeLog 2014-10-25 14:42:26 UTC (rev 5995)
@@ -34353,3 +34353,29 @@
expression_template_0_test.cpp
Improve documentation.
+20141025T1442Z <address@hidden> [533]
+
+ Makefile.am
+ main_wx_test.cpp
+ objects.make
+ skeleton.hpp
+ wx_test_about_version.cpp [new file]
+ wx_test_benchmark_census.cpp [new file]
+ wx_test_calculation_summary.cpp [new file]
+ wx_test_case.hpp [new file]
+ wx_test_config_settings.cpp [new file]
+ wx_test_create_open.cpp [new file]
+ wx_test_default_input.cpp [new file]
+ wx_test_default_update.cpp [new file]
+ wx_test_expiry_dates.cpp [new file]
+ wx_test_extract.cpp [new file]
+ wx_test_input_sequences.cpp [new file]
+ wx_test_input_validation.cpp [new file]
+ wx_test_mvc_dialog.hpp [new file]
+ wx_test_new.hpp [new file]
+ wx_test_paste_census.cpp [new file]
+ wx_test_pdf_create.cpp [new file]
+ wx_test_statusbar.hpp [new file]
+ wx_test_validate_output.cpp [new file]
+Augment automated GUI test.
+
Modified: lmi/trunk/Makefile.am
===================================================================
--- lmi/trunk/Makefile.am 2014-10-21 13:58:38 UTC (rev 5994)
+++ lmi/trunk/Makefile.am 2014-10-25 14:42:26 UTC (rev 5995)
@@ -255,6 +255,20 @@
$(BOOST_LIBS)
wx_test_SOURCES = \
+ wx_test_about_version.cpp \
+ wx_test_benchmark_census.cpp \
+ wx_test_calculation_summary.cpp \
+ wx_test_config_settings.cpp \
+ wx_test_create_open.cpp \
+ wx_test_default_input.cpp \
+ wx_test_default_update.cpp \
+ wx_test_expiry_dates.cpp \
+ wx_test_extract.cpp \
+ wx_test_input_sequences.cpp \
+ wx_test_input_validation.cpp \
+ wx_test_paste_census.cpp \
+ wx_test_pdf_create.cpp \
+ wx_test_validate_output.cpp \
main_wx_test.cpp
wx_test_CXXFLAGS = $(AM_CXXFLAGS) $(WX_CXXFLAGS)
wx_test_LDADD = \
Modified: lmi/trunk/main_wx_test.cpp
===================================================================
--- lmi/trunk/main_wx_test.cpp 2014-10-21 13:58:38 UTC (rev 5994)
+++ lmi/trunk/main_wx_test.cpp 2014-10-25 14:42:26 UTC (rev 5995)
@@ -26,73 +26,427 @@
# pragma hdrstop
#endif
-#include "assert_lmi.hpp"
+#include "alert.hpp"
#include "force_linking.hpp"
+#include "handle_exceptions.hpp" // stealth_exception
#include "main_common.hpp" // initialize_application()
#include "msw_workarounds.hpp"
+#include "obstruct_slicing.hpp"
#include "path_utility.hpp" // initialize_filesystem()
#include "skeleton.hpp"
-#include "version.hpp"
+#include "uncopyable_lmi.hpp"
+#include "wx_test_case.hpp"
-#include <wx/dialog.h>
+#include <wx/fileconf.h>
+#include <wx/frame.h>
#include <wx/init.h> // wxEntry()
-#include <wx/testing.h>
-#include <wx/uiaction.h>
+#include <wx/stopwatch.h>
+#include <wx/wfstream.h>
+#include <boost/scoped_ptr.hpp>
+
+#include <algorithm> // std::sort()
+#include <cstring> // std::strcmp()
+#include <exception> // uncaught_exception()
+#include <iostream>
+#include <sstream>
+#include <stdexcept>
+#include <utility> // std::pair
+#include <vector>
+
LMI_FORCE_LINKING_EX_SITU(file_command_wx)
LMI_FORCE_LINKING_EX_SITU(progress_meter_wx)
LMI_FORCE_LINKING_EX_SITU(system_command_wx)
+#if !wxCHECK_VERSION(3,1,0)
+# error wxWidgets 3.1.0 or later is required for the test suite.
+#endif
+
class SkeletonTest;
DECLARE_APP(SkeletonTest)
-class application_test
+/// Implement this normally unimplemented function.
+///
+/// The implementation of this constructor is not provided to prevent
+/// production code from creating objects of this type, but we do need to use
+/// this exception here, for the special testing purposes, so explicitly opt in
+/// into using it by provide this implementation.
+stealth_exception::stealth_exception(std::string const& what_arg)
+ :std::runtime_error(what_arg)
+{}
+
+namespace
{
+
+/// Exception thrown if a wxWidgets assertion fails during the test code
+/// execution. It must inherit from stealth_exception to avoid this exception
+/// being caught, reported and ignored by well-meaning but harmful in this case
+/// exception handling code elsewhere.
+///
+/// Implicitly-declared special member functions do the right thing.
+
+class test_assertion_failure_exception
+ :public stealth_exception
+{
public:
- static void test()
+ test_assertion_failure_exception
+ (wxChar const* msg
+ ,wxChar const* file
+ ,int line
+ ,wxChar const* func
+ )
+ :stealth_exception
+ (wxString::Format
+ ("Assertion failure: %s [file %s, line %d, in %s()]."
+ ,msg
+ ,file
+ ,line
+ ,func
+ ).ToStdString()
+ )
{
- test_about_dialog_version();
}
+};
+/// Run the tests.
+///
+/// This is a simple Meyers singleton.
+class application_test
+ : private lmi::uncopyable <application_test>
+ ,virtual private obstruct_slicing <application_test>
+{
+ public:
+ static application_test& instance();
+
+ // Check the command line for the test-specific options, handle them and
+ // remove them from argv.
+ //
+ // Return false if the program execution shouldn't continue, currently this
+ // is only the case if the "list" option was specified requesting just to
+ // list the available tests.
+ bool process_command_line(int& argc, char* argv[]);
+
+ // Run all the tests that were configured to be executed (all by default).
+ //
+ // This function consumes all the exceptions thrown during its execution
+ // and never throws itself.
+ //
+ // Return the number of tests executed as the first pair component and the
+ // number of failed tests as the second component.
+ std::pair<int, int> run() /* noexcept */;
+
+ // Used by LMI_WX_TEST_CASE() macro to register the individual test cases.
+ void add_test(wx_base_test_case* test);
+
+ // Used by tests to retrieve their configuration parameters.
+ wxConfigBase const& get_config_for(char const* name);
+
private:
- static void test_about_dialog_version();
-};
+ application_test();
-void application_test::test_about_dialog_version()
-{
- struct expect_about_dialog : public wxExpectModalBase<wxDialog>
+ // Sort all tests in alphabetical order of their names.
+ void sort_tests();
+
+ // List all tests on standard output.
+ void list_tests();
+
+ // Include of exclude the given test depending on the value given on the
+ // command line.
+ void process_test_name(char const* name);
+
+ // A test can be explicitly included, explicitly excluded or not
+ // mentioned, in which case it will run if all tests are ran by default.
+ enum test_run
+ {run_yes
+ ,run_no
+ ,run_default
+ };
+
+ /// Contains everything we need to store for an individual test.
+ struct test_descriptor
{
- virtual int OnInvoked(wxDialog* d) const
+ // The pointer must be non-NULL but we don't take ownership of it.
+ test_descriptor(wx_base_test_case* test)
+ :test(test)
+ ,run(run_default)
+ {
+ }
+
+ char const* get_name() const { return test->get_name(); }
+
+ void run_test() const { test->run(); }
+
+ // Comparator used for sorting the tests.
+ static bool Compare
+ (test_descriptor const& t1
+ ,test_descriptor const& t2)
{
- LMI_ASSERT(0 != d);
- LMI_ASSERT(d->GetTitle().EndsWith(LMI_VERSION));
- return wxID_OK;
+ return std::strcmp(t1.get_name(), t2.get_name()) < 0;
}
+
+ wx_base_test_case* test;
+ test_run run;
};
- wxUIActionSimulator z;
- z.KeyDown('h', wxMOD_ALT);
- z.KeyUp ('h', wxMOD_ALT);
- z.KeyDown('a' );
- z.KeyUp ('a' );
- wxTEST_DIALOG
- (wxYield()
- ,expect_about_dialog()
- );
+ std::vector<test_descriptor> tests_;
+
+ boost::scoped_ptr<wxFileConfig> config_;
+
+ bool run_all_;
+};
+
+application_test::application_test()
+ :run_all_(true)
+{
}
+application_test& application_test::instance()
+{
+ static application_test z;
+ return z;
+}
+
+void application_test::process_test_name(char const* name)
+{
+ // A test can be specified either as "test" to run it, or "-test" to avoid
+ // running it, check which one have we got.
+ test_run run;
+ if (name[0] == '-')
+ {
+ run = run_no;
+ name++; // Skip the leading minus sign.
+ }
+ else
+ {
+ // If some test is explicitly requested, all the other ones are
+ // implicitly disabled, otherwise it wouldn't make sense.
+ run_all_ = false;
+ run = run_yes;
+ }
+
+ bool any_tests_matched = false;
+
+ typedef std::vector<test_descriptor>::iterator tdi;
+ for(tdi i = tests_.begin(); i != tests_.end(); ++i)
+ {
+ if (wxString(i->get_name()).Matches(name))
+ {
+ i->run = run;
+ any_tests_matched = true;
+ }
+ }
+
+ if (!any_tests_matched)
+ {
+ warning()
+ << "Test specification '"
+ << name
+ << "', didn't match any tests.\n"
+ << "Use --list command line option to list all tests."
+ << std::flush
+ ;
+ }
+}
+
+// Remove the argument at the given (assumed valid) position from (argc, argv).
+void remove_arg(int n, int& argc, char* argv[])
+{
+ // We include argv[argc] in the elements being copied, this guarantees that
+ // the array remains 0-terminated.
+ std::memmove(argv + n, argv + n + 1, (argc - n)*sizeof(char*));
+
+ argc--;
+}
+
+bool application_test::process_command_line(int& argc, char* argv[])
+{
+ // This variable is used both as a flag indicating that the last option was
+ // the one selecting the test to run and so must be followed by the test
+ // name, but also for the diagnostic message at the end of this function.
+ char const* last_test_option = 0;
+
+ for(int n = 1; n < argc; )
+ {
+ char const* const arg = argv[n];
+
+ if (last_test_option)
+ {
+ last_test_option = 0;
+ process_test_name(arg);
+ remove_arg(n, argc, argv);
+ continue;
+ }
+ else if
+ ( 0 == std::strcmp(arg, "-l")
+ || 0 == std::strcmp(arg, "--list")
+ )
+ {
+ list_tests();
+ return false;
+ }
+ else if
+ ( 0 == std::strcmp(arg, "-t")
+ || 0 == std::strcmp(arg, "--test")
+ )
+ {
+ last_test_option = arg;
+ remove_arg(n, argc, argv);
+ }
+ else
+ {
+ n++;
+ }
+ }
+
+ if (last_test_option)
+ {
+ warning()
+ << "Option '"
+ << last_test_option
+ << "' must be followed by the test name."
+ << std::flush
+ ;
+ }
+
+ return true;
+}
+
+std::pair<int, int> application_test::run()
+{
+ // Always run the tests in the same, predictable order (we may want to add
+ // a "random shuffle" option later, but even then predictable behaviour
+ // should arguably remain the default).
+ sort_tests();
+
+ std::pair<int, int> results(0, 0);
+
+ // Indent the test status reports to make them stand out.
+ char const* const indent = " ";
+
+ typedef std::vector<test_descriptor>::const_iterator ctdi;
+ for(ctdi i = tests_.begin(); i != tests_.end(); ++i)
+ {
+ if ((run_all_ && i->run != run_no) || i->run == run_yes)
+ {
+ std::string error;
+ results.first++;
+
+ try
+ {
+ wxStopWatch sw;
+ i->run_test();
+ wxLogMessage("%s%s: ok (%ldms)", indent, i->get_name(),
sw.Time());
+ }
+ catch(std::exception const& e)
+ {
+ error = e.what();
+ }
+ catch(...)
+ {
+ error = "unknown exception";
+ }
+
+ if (!error.empty())
+ {
+ results.second++;
+
+ // When logging to a log window, it's better to have everything
+ // on a single line to avoid breaking the output structure.
+ wxString one_line_error(error);
+ one_line_error.Replace("\n", " ");
+
+ wxLogMessage
+ ("%s%s: ERROR (%s)"
+ ,indent
+ ,i->get_name()
+ ,one_line_error
+ );
+ }
+ }
+ }
+
+ return results;
+}
+
+void application_test::add_test(wx_base_test_case* test)
+{
+ tests_.push_back(test_descriptor(test));
+}
+
+void application_test::sort_tests()
+{
+ std::sort(tests_.begin(), tests_.end(), test_descriptor::Compare);
+}
+
+void application_test::list_tests()
+{
+ sort_tests();
+
+ std::cerr << "Available tests:\n";
+
+ typedef std::vector<test_descriptor>::const_iterator ctdi;
+ for(ctdi i = tests_.begin(); i != tests_.end(); ++i)
+ {
+ std::cerr << '\t' << i->get_name() << '\n';
+ }
+
+ std::cerr << tests_.size() << " test cases.\n";
+}
+
+wxConfigBase const& application_test::get_config_for(char const* name)
+{
+ if(!config_)
+ {
+ wxFFileInputStream is("wx_test.conf", "r");
+ config_.reset(new wxFileConfig(is));
+ }
+
+ config_->SetPath(wxString("/") + name);
+
+ return *config_;
+}
+
+} // Unnamed namespace.
+
+wx_base_test_case::wx_base_test_case(char const* name)
+ :m_name(name)
+{
+ application_test::instance().add_test(this);
+}
+
+wxConfigBase const& wx_base_test_case::config() const
+{
+ return application_test::instance().get_config_for(get_name());
+}
+
// Application to drive the tests
class SkeletonTest : public Skeleton
{
public:
- SkeletonTest() {}
+ SkeletonTest()
+ :is_running_tests_(false)
+ {
+ }
protected:
// wxApp overrides.
- virtual bool OnInit();
+ virtual bool OnInit ();
+ virtual bool OnExceptionInMainLoop ();
+ virtual bool StoreCurrentException ();
+ virtual void RethrowStoredException ();
+ virtual void OnAssertFailure
+ (wxChar const* file
+ ,int line
+ ,wxChar const* func
+ ,wxChar const* cond
+ ,wxChar const* msg
+ );
private:
void RunTheTests();
+
+ std::string runtime_error_;
+ bool is_running_tests_;
};
IMPLEMENT_APP_NO_MAIN(SkeletonTest)
@@ -112,10 +466,127 @@
return true;
}
+bool SkeletonTest::StoreCurrentException()
+{
+ try
+ {
+ throw;
+ }
+ catch (std::runtime_error const& e)
+ {
+ runtime_error_ = e.what();
+ return true;
+ }
+
+ return false;
+}
+
+void SkeletonTest::RethrowStoredException()
+{
+ if (!runtime_error_.empty())
+ {
+ std::runtime_error const e(runtime_error_);
+ runtime_error_.clear();
+ throw e;
+ }
+}
+
+bool SkeletonTest::OnExceptionInMainLoop()
+{
+ if (is_running_tests_)
+ {
+ // Don't let the base class catch, report and ignore the exceptions
+ // that happen while running the tests, we need to ensure that the test
+ // fails as the result of assert happening during its run.
+ throw;
+ }
+
+ return Skeleton::OnExceptionInMainLoop();
+}
+
+void SkeletonTest::OnAssertFailure
+ (wxChar const* file
+ ,int line
+ ,wxChar const* func
+ ,wxChar const* cond
+ ,wxChar const* msg
+ )
+{
+ // Assertion during a test run counts as test failure but avoid throwing if
+ // another exception is already in flight as this would just result in the
+ // program termination without any useful information about the reason of
+ // the failure whatsoever.
+ if (is_running_tests_ && !std::uncaught_exception())
+ {
+ throw test_assertion_failure_exception(msg ? msg : cond, file, line,
func);
+ }
+ else
+ {
+ Skeleton::OnAssertFailure(file, line, func, cond, msg);
+ }
+}
+
void SkeletonTest::RunTheTests()
{
- application_test::test();
- ExitMainLoop();
+ // Create log window for output that should be checked by the user.
+ class LogWindow : public wxLogWindow
+ {
+ public:
+ LogWindow() : wxLogWindow(NULL, "Log Messages", true, false) {}
+ virtual bool OnFrameClose(wxFrame* frame)
+ {
+ wxTheApp->ExitMainLoop();
+ return wxLogWindow::OnFrameClose(frame);
+ }
+ };
+ LogWindow* const log = new LogWindow();
+
+ wxWindow* const mainWin = GetTopWindow();
+ mainWin->SetFocus();
+
+ wxStopWatch sw;
+ wxLogMessage("Starting automatic tests:");
+
+ // Notice that it is safe to use simple variable assignment here instead of
+ // some RAII-based pattern because of application_test::run() noexcept
+ // guarantee.
+ is_running_tests_ = true;
+ std::pair<int, int> const results = application_test::instance().run();
+ is_running_tests_ = false;
+
+ if (results.first == 0)
+ {
+ wxLogMessage("WARNING: no tests have been executed.");
+ }
+ else if (results.second == 0)
+ {
+ wxLogMessage
+ ("SUCCESS: %d tests successfully completed in %ldms."
+ ,results.first
+ ,sw.Time()
+ );
+ }
+ else
+ {
+ wxLogMessage
+ ("FAILURE: %d out of %d tests failed."
+ ,results.second
+ ,results.first
+ );
+ }
+
+ // We want to show log output after the tests finished running and hide the
+ // app window, which is no longer in use. This doesn't work out of the box,
+ // because the main window is set application's top window and closing it
+ // terminates the app. LogWindow's window, on the other hand, doesn't keep
+ // the app running because it returns false from ShouldPreventAppExit().
+ // This code (together with LogWindow::OnFrameClose above) does the right
+ // thing: close the main window and keep running until the user closes the
+ // log window.
+ log->GetFrame()->Maximize();
+ log->GetFrame()->SetFocus();
+ SetExitOnFrameDelete(false);
+ mainWin->Close();
}
int main(int argc, char* argv[])
@@ -125,6 +596,15 @@
#ifdef LMI_MSW
MswDllPreloader::instance().PreloadDesignatedDlls();
#endif
+
+ // We need to handle test-specific options and remove them from argv before
+ // letting wxEntry() instantiate Skeleton application object that would
+ // give an error for these, unknown to it, options.
+ if (!application_test::instance().process_command_line(argc, argv))
+ {
+ return 0;
+ }
+
return wxEntry(argc, argv);
}
Modified: lmi/trunk/objects.make
===================================================================
--- lmi/trunk/objects.make 2014-10-21 13:58:38 UTC (rev 5994)
+++ lmi/trunk/objects.make 2014-10-25 14:42:26 UTC (rev 5995)
@@ -356,6 +356,20 @@
wx_test_objects := \
main_wx_test.o \
+ wx_test_about_version.o \
+ wx_test_benchmark_census.o \
+ wx_test_calculation_summary.o \
+ wx_test_config_settings.o \
+ wx_test_create_open.o \
+ wx_test_default_input.o \
+ wx_test_default_update.o \
+ wx_test_expiry_dates.o \
+ wx_test_extract.o \
+ wx_test_input_sequences.o \
+ wx_test_input_validation.o \
+ wx_test_paste_census.o \
+ wx_test_pdf_create.o \
+ wx_test_validate_output.o \
ifneq (,$(RC))
lmi_wx_objects += lmi_msw_res.o
Modified: lmi/trunk/skeleton.hpp
===================================================================
--- lmi/trunk/skeleton.hpp 2014-10-21 13:58:38 UTC (rev 5994)
+++ lmi/trunk/skeleton.hpp 2014-10-25 14:42:26 UTC (rev 5995)
@@ -63,7 +63,8 @@
protected:
// wxApp overrides that are further overridden in gui test.
- virtual bool OnInit();
+ virtual bool OnInit ();
+ virtual bool OnExceptionInMainLoop ();
private:
wxMenuBar* AdjustMenus(wxMenuBar*);
@@ -114,9 +115,8 @@
void UponWindowTileVertically (wxCommandEvent&);
// wxApp overrides.
- virtual bool OnExceptionInMainLoop ();
- virtual int OnExit ();
- virtual void OnUnhandledException ();
+ virtual int OnExit ();
+ virtual void OnUnhandledException ();
bool ProcessCommandLine(int argc, char* argv[]);
void UpdateViews();
Added: lmi/trunk/wx_test_about_version.cpp
===================================================================
--- lmi/trunk/wx_test_about_version.cpp (rev 0)
+++ lmi/trunk/wx_test_about_version.cpp 2014-10-25 14:42:26 UTC (rev 5995)
@@ -0,0 +1,58 @@
+// Version number test case for the GUI test suite.
+//
+// Copyright (C) 2014 Gregory W. Chicares.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2 as
+// published by the Free Software Foundation.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software Foundation,
+// Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+//
+// http://savannah.nongnu.org/projects/lmi
+// email: <address@hidden>
+// snail: Chicares, 186 Belle Woods Drive, Glastonbury CT 06033, USA
+
+// $Id$
+
+#ifdef __BORLANDC__
+# include "pchfile.hpp"
+# pragma hdrstop
+#endif
+
+#include "assert_lmi.hpp"
+#include "wx_test_case.hpp"
+#include "version.hpp"
+
+#include <wx/dialog.h>
+#include <wx/testing.h>
+#include <wx/uiaction.h>
+
+LMI_WX_TEST_CASE(about_dialog_version)
+{
+ struct expect_about_dialog : public wxExpectModalBase<wxDialog>
+ {
+ virtual int OnInvoked(wxDialog* d) const
+ {
+ LMI_ASSERT(0 != d);
+ LMI_ASSERT(d->GetTitle().EndsWith(LMI_VERSION));
+ return wxID_OK;
+ }
+ };
+
+ wxUIActionSimulator z;
+ z.KeyDown('h', wxMOD_ALT);
+ z.KeyUp ('h', wxMOD_ALT);
+ z.KeyDown('a' );
+ z.KeyUp ('a' );
+ wxTEST_DIALOG
+ (wxYield()
+ ,expect_about_dialog()
+ );
+}
Property changes on: lmi/trunk/wx_test_about_version.cpp
___________________________________________________________________
Added: svn:keywords
+ Id
Added: lmi/trunk/wx_test_benchmark_census.cpp
===================================================================
--- lmi/trunk/wx_test_benchmark_census.cpp (rev 0)
+++ lmi/trunk/wx_test_benchmark_census.cpp 2014-10-25 14:42:26 UTC (rev
5995)
@@ -0,0 +1,180 @@
+// Test benchmarking census operations.
+//
+// Copyright (C) 2014 Gregory W. Chicares.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2 as
+// published by the Free Software Foundation.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software Foundation,
+// Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+//
+// http://savannah.nongnu.org/projects/lmi
+// email: <address@hidden>
+// snail: Chicares, 186 Belle Woods Drive, Glastonbury CT 06033, USA
+
+// $Id$
+
+#ifdef __BORLANDC__
+# include "pchfile.hpp"
+# pragma hdrstop
+#endif
+
+#include "assert_lmi.hpp"
+#include "wx_test_case.hpp"
+#include "wx_test_statusbar.hpp"
+#include "uncopyable_lmi.hpp"
+
+#include <wx/confbase.h>
+#include <wx/dialog.h>
+#include <wx/frame.h>
+#include <wx/log.h>
+#include <wx/scopeguard.h>
+#include <wx/testing.h>
+#include <wx/uiaction.h>
+
+#include <cmath> // std::fabs()
+
+namespace
+{
+
+class census_benchmark
+ :private lmi::uncopyable<census_benchmark>
+{
+ public:
+ explicit census_benchmark(wxString const& name, wxString const& path)
+ :status_(get_main_window_statusbar())
+ ,name_(name)
+ {
+ wxUIActionSimulator z;
+ z.Char('o', wxMOD_CONTROL); // "File|Open"
+ wxTEST_DIALOG
+ (wxYield()
+ ,wxExpectModal<wxFileDialog>(path)
+ );
+ wxYield();
+ }
+
+ void time_operation
+ (char const* operation
+ ,long time_expected
+ ,char key
+ ,int mod
+ )
+ {
+ wxUIActionSimulator z;
+ z.Char(key, mod);
+ wxYield();
+
+ wxString const status_text = status_.GetStatusText();
+ wxString ms_text;
+ LMI_ASSERT(status_text.EndsWith(" milliseconds", &ms_text));
+
+ long time_real;
+ LMI_ASSERT(ms_text.ToLong(&time_real));
+
+ // Compare the difference with the expected time if it's specified.
+ wxString delta;
+ if (time_expected)
+ {
+ double const diff_in_percents =
+ 100*(time_real - time_expected)
+ / static_cast<double>(time_expected);
+
+ delta.Printf("%+.2f%%", diff_in_percents);
+
+ LMI_ASSERT_WITH_MSG
+ (std::fabs(diff_in_percents) < 10
+ ,wxString::Format
+ (
+ "expected %ldms, but actually took %ldms, i.e. %s"
+ ,time_expected
+ ,time_real
+ ,delta
+ )
+ );
+ }
+ else
+ {
+ delta = "not specified";
+ }
+
+ wxLogMessage
+ ("%s for %s: %ldms elapsed (expected %s)"
+ ,operation
+ ,name_
+ ,time_real
+ ,delta
+ );
+ }
+
+ void close_window()
+ {
+ wxUIActionSimulator z;
+ z.Char('l', wxMOD_CONTROL); // "File|Close"
+ }
+
+ ~census_benchmark()
+ {
+ // Close the census window opened in the ctor itself.
+ close_window();
+ }
+
+ private:
+ wxStatusBar const& status_;
+ wxString const name_;
+};
+
+} // Unnamed namespace.
+
+LMI_WX_TEST_CASE(benchmark_census)
+{
+ wxConfigBase const& c = config();
+
+ // Read the timing parameters.
+ long const time_run = c.ReadLong("time_run", 0);
+ long const time_disk = c.ReadLong("time_disk", 0);
+ long const time_spreadsheet = c.ReadLong("time_spreadsheet", 0);
+
+ // The censuses to benchmark are specified by the subgroups of the config
+ // file, so iterate over all of them.
+ wxString name;
+ long z;
+ for(bool ok = c.GetFirstGroup(name, z); ok; ok = c.GetNextGroup(name, z))
+ {
+ census_benchmark b(name, c.Read(name + "/path"));
+
+ {
+ // Ensure that the window doesn't stay opened (and possibly affects
+ // negatively the subsequent tests) even if this test fails.
+ wxON_BLOCK_EXIT_OBJ0(b, census_benchmark::close_window);
+
+ b.time_operation
+ ("Run case"
+ ,time_run
+ ,'r'
+ ,wxMOD_CONTROL | wxMOD_SHIFT
+ );
+ }
+
+ b.time_operation
+ ("Print to disk"
+ ,time_disk
+ ,'k'
+ ,wxMOD_CONTROL | wxMOD_SHIFT
+ );
+
+ b.time_operation
+ ("Print to spreadsheet"
+ ,time_spreadsheet
+ ,'h'
+ ,wxMOD_CONTROL | wxMOD_SHIFT
+ );
+ }
+}
Property changes on: lmi/trunk/wx_test_benchmark_census.cpp
___________________________________________________________________
Added: svn:keywords
+ Id
Added: lmi/trunk/wx_test_calculation_summary.cpp
===================================================================
--- lmi/trunk/wx_test_calculation_summary.cpp (rev 0)
+++ lmi/trunk/wx_test_calculation_summary.cpp 2014-10-25 14:42:26 UTC (rev
5995)
@@ -0,0 +1,297 @@
+// Test calculation summary features.
+//
+// Copyright (C) 2014 Gregory W. Chicares.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2 as
+// published by the Free Software Foundation.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software Foundation,
+// Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+//
+// http://savannah.nongnu.org/projects/lmi
+// email: <address@hidden>
+// snail: Chicares, 186 Belle Woods Drive, Glastonbury CT 06033, USA
+
+// $Id$
+
+#ifdef __BORLANDC__
+# include "pchfile.hpp"
+# pragma hdrstop
+#endif
+
+#include "assert_lmi.hpp"
+#include "configurable_settings.hpp"
+#include "wx_test_case.hpp"
+#include "wx_test_mvc_dialog.hpp"
+#include "wx_test_new.hpp"
+#include "wx_utility.hpp"
+
+#include <wx/ffile.h>
+#include <wx/html/htmlpars.h>
+#include <wx/html/htmlwin.h>
+#include <wx/testing.h>
+#include <wx/uiaction.h>
+
+#include <cstddef> // std::size_t
+
+namespace
+{
+
+struct name_and_title
+{
+ char const* name;
+ char const* title;
+};
+
+// Names and titles of the columns used by default.
+name_and_title const default_columns_info[] =
+ {{ "PolicyYear" , "Policy Year" }
+ ,{ "Outlay" , "Net Outlay" }
+ ,{ "AcctVal_Current" , "Curr Account Value" }
+ ,{ "CSVNet_Current" , "Curr Net Cash Surr Value" }
+ ,{ "EOYDeathBft_Current" , "Curr EOY Death Benefit" }
+ };
+
+std::size_t const number_of_default_columns
+ = sizeof default_columns_info / sizeof(default_columns_info[0]);
+
+// Names and titles of the columns used when not using the built-in calculation
+// summary.
+name_and_title const custom_columns_info[] =
+ {{ "PolicyYear" , "Policy Year" }
+ ,{ "AttainedAge" , "Attained Age" }
+ ,{ "Outlay" , "Net Outlay" }
+ ,{ "CSVNet_Current" , "Curr Net Cash Surr Value" }
+ ,{ "AcctVal_Current" , "Curr Account Value" }
+ ,{ "CSVNet_Guaranteed" , "Guar Net Cash Surr Value" }
+ ,{ "AcctVal_Guaranteed" , "Guar Account Value" }
+ ,{ "EOYDeathBft_Current" , "Curr EOY Death Benefit" }
+ ,{ "EOYDeathBft_Guaranteed" , "Guar EOY Death Benefit" }
+ ,{ "NetWD" , "Withdrawal" }
+ ,{ "NewCashLoan" , "Annual Loan" }
+ ,{ "LoanIntAccrued_Current" , "Curr Loan Int Accrued" }
+ };
+
+std::size_t const number_of_custom_columns
+ = sizeof custom_columns_info / sizeof(custom_columns_info[0]);
+
+// Special name used when the column is not used at all.
+char const* const magic_null_column_name = "[none]";
+
+// Change the calculation summary settings in the preferences dialog to use, or
+// not use, the built-in defaults.
+void use_builtin_calculation_summary(bool b)
+{
+ wxUIActionSimulator ui;
+ ui.Char('f', wxMOD_CONTROL); // "File|Preferences"
+
+ class ChangeCalculationSummaryInPreferencesDialog
+ :public ExpectMvcDialog
+ {
+ public:
+ ChangeCalculationSummaryInPreferencesDialog
+ (bool use_builtin_summary)
+ :use_builtin_summary_(use_builtin_summary)
+ {
+ }
+
+ virtual void DoRunDialog(MvcController* dialog) const
+ {
+ wxUIActionSimulator ui;
+
+ // Go to the "Use built-in calculation summary" checkbox.
+ ui.Char(WXK_TAB);
+ wxYield();
+
+ // Disable the checkbox initially as we need it to be disabled to
+ // change the values of the column controls.
+ ui.Char('-');
+ wxYield();
+
+ DoUpdateDialogUI(dialog);
+
+ // Update the columns controls when using them.
+ for(std::size_t n = 0; n < number_of_custom_columns; ++n)
+ {
+ ui.Char(WXK_TAB);
+ wxYield();
+
+ wxString const column_name
+ (use_builtin_summary_
+ ? magic_null_column_name
+ : custom_columns_info[n].name
+ );
+
+ LMI_ASSERT(ui.Select(column_name));
+
+ DoUpdateDialogUI(dialog);
+ }
+
+ // Finally return to the initial checkbox.
+ for(std::size_t n = 0; n < number_of_custom_columns; ++n)
+ {
+ ui.Char(WXK_TAB, wxMOD_SHIFT);
+ }
+
+ wxYield();
+
+ // And set it to the desired value.
+ ui.Char(use_builtin_summary_ ? '+' : '-');
+ wxYield();
+ }
+
+ private:
+ bool const use_builtin_summary_;
+ };
+
+ wxTEST_DIALOG
+ (wxYield()
+ ,ChangeCalculationSummaryInPreferencesDialog(b)
+ );
+}
+
+void check_calculation_summary_columns
+ (std::size_t number_of_columns
+ ,name_and_title const columns_info[]
+ )
+{
+ // Create a new illustration.
+ wx_test_new_illustration ill;
+
+ // Find the window displaying HTML contents of the illustration view.
+ wxWindow* const focus = wxWindow::FindFocus();
+ LMI_ASSERT(focus);
+
+ wxHtmlWindow* const htmlwin = dynamic_cast<wxHtmlWindow*>(focus);
+ LMI_ASSERT(htmlwin);
+
+ // And get the HTML from it.
+ wxHtmlParser* const parser = htmlwin->GetParser();
+ LMI_ASSERT(parser);
+ LMI_ASSERT(parser->GetSource());
+
+ wxString const html = *parser->GetSource();
+
+ // We don't need the window any more.
+ ill.close();
+
+ // Find the start of the table after the separating line.
+ size_t pos = html.find("<hr>\n<table");
+ LMI_ASSERT(pos != wxString::npos);
+
+ pos = html.find("\n<td", pos);
+ LMI_ASSERT(pos != wxString::npos);
+
+ pos++; // skip the new line
+
+ // We have found the place where the columns are described in the HTML,
+ // iterate over all of them.
+ for(std::size_t n = 0; n < number_of_columns; ++n)
+ {
+ LMI_ASSERT_EQUAL(wxString(html, pos, 3), "<td");
+
+ pos = html.find(">", pos); // end of the <td> tag
+ LMI_ASSERT(pos != wxString::npos);
+
+ pos++; // <td> tag contents
+
+ size_t const next = html.find("\n", pos); // the next line start
+ LMI_ASSERT(next != wxString::npos);
+
+ // Extract the column title from the rest of the line.
+ wxString title;
+ LMI_ASSERT(wxString(html, pos, next - pos).EndsWith(" </td>", &title));
+
+ LMI_ASSERT_EQUAL(title, columns_info[n].title);
+
+ pos = next + 1;
+ }
+
+ LMI_ASSERT_EQUAL(wxString(html, pos, 5), "</tr>");
+}
+
+// Save the current clipboard contents to a file with the given name,
+// overwriting it if necessary.
+void save_clipboard(wxString const& filename)
+{
+ wxFFile f(filename, "w");
+ LMI_ASSERT(f.IsOpened());
+ LMI_ASSERT(f.Write(wxString(ClipboardEx::GetText())));
+ LMI_ASSERT(f.Close());
+}
+
+// Save the illustration calculation summary and full data to files with the
+// given prefix.
+void save_illustration_data(wxString const& prefix)
+{
+ wxUIActionSimulator ui;
+ ui.Char('c', wxMOD_CONTROL); // "Illustration|Copy calculation summary"
+ wxYield();
+ save_clipboard(prefix + "IllSummary.txt");
+
+ ui.Char('d', wxMOD_CONTROL); // "Illustration|Copy full illustration data"
+ wxYield();
+ save_clipboard(prefix + "IllFull.txt");
+}
+
+} // Unnamed namespace.
+
+LMI_WX_TEST_CASE(calculation_summary)
+{
+ configurable_settings const& settings = configurable_settings::instance();
+
+ use_builtin_calculation_summary(true);
+
+ LMI_ASSERT(settings.calculation_summary_columns().empty());
+ LMI_ASSERT(settings.use_builtin_calculation_summary());
+
+ check_calculation_summary_columns
+ (number_of_default_columns
+ ,default_columns_info
+ );
+
+ use_builtin_calculation_summary(false);
+
+ // Concatenate all the custom column names together. Notice that the
+ // trailing space is intentional as it is present in the configurable
+ // settings file too.
+ std::string all_custom_columns;
+ for(std::size_t n = 0; n < number_of_custom_columns; ++n)
+ {
+ all_custom_columns += custom_columns_info[n].name;
+ all_custom_columns += ' ';
+ }
+
+ LMI_ASSERT_EQUAL(settings.calculation_summary_columns(),
all_custom_columns);
+ LMI_ASSERT(!settings.use_builtin_calculation_summary());
+
+ check_calculation_summary_columns
+ (number_of_custom_columns
+ ,custom_columns_info
+ );
+
+ wxUIActionSimulator ui;
+
+ wx_test_new_illustration ill;
+ save_illustration_data("New");
+ ill.close();
+
+ wx_test_new_census census;
+ ui.Char('r', wxMOD_CONTROL | wxMOD_SHIFT); // "Census|Run case"
+ wxYield();
+
+ save_illustration_data("Calc");
+
+ // Close the illustration opened by "Run case".
+ ui.Char('l', wxMOD_CONTROL); // "File|Close"
+ wxYield();
+
+ census.close();
+}
Property changes on: lmi/trunk/wx_test_calculation_summary.cpp
___________________________________________________________________
Added: svn:keywords
+ Id
Added: lmi/trunk/wx_test_case.hpp
===================================================================
--- lmi/trunk/wx_test_case.hpp (rev 0)
+++ lmi/trunk/wx_test_case.hpp 2014-10-25 14:42:26 UTC (rev 5995)
@@ -0,0 +1,88 @@
+// Supporting framework for wx interface test cases.
+//
+// Copyright (C) 2014 Gregory W. Chicares.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2 as
+// published by the Free Software Foundation.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software Foundation,
+// Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+//
+// http://savannah.nongnu.org/projects/lmi
+// email: <address@hidden>
+// snail: Chicares, 186 Belle Woods Drive, Glastonbury CT 06033, USA
+
+// $Id$
+
+#ifndef wx_test_case_hpp
+#define wx_test_case_hpp
+
+#include "config.hpp"
+
+#include "uncopyable_lmi.hpp"
+
+class wxConfigBase;
+
+/// Base class for the test case objects.
+///
+/// It is only supposed to be used by LMI_WX_TEST_CASE macro and not directly.
+class wx_base_test_case
+ :private lmi::uncopyable<wx_base_test_case>
+{
+ public:
+ /// The function actually executing the test code.
+ ///
+ /// This function should throw an exception to signal any failures.
+ virtual void run() = 0;
+
+ char const* get_name() const { return m_name; }
+
+ // Only required to fix g++ warning about a class having virtual functions
+ // but a non-virtual dtor, as this class is not used polymorphically the
+ // dtor doesn't really need to be virtual.
+ virtual ~wx_base_test_case() { }
+
+ protected:
+ /// The argument must be a literal, as we just store the pointer.
+ explicit wx_base_test_case(char const* name);
+
+ /// Get the object containing test configuration.
+ ///
+ /// The returned object will have the group containing the options for this
+ /// test as its current path for convenience.
+ wxConfigBase const& config() const;
+
+ char const* const m_name;
+};
+
+/// Define a test function and register it with the application tester.
+///
+/// Usage is:
+///
+/// LMI_WX_TEST_CASE(my_test)
+/// {
+/// ... code of the test ...
+/// }
+#define LMI_WX_TEST_CASE(name) \
+class wx_test_case_##name \
+ :public wx_base_test_case \
+{ \
+ public: \
+ wx_test_case_##name() \
+ :wx_base_test_case(#name) \
+ { \
+ } \
+ \
+ virtual void run(); \
+}; \
+static wx_test_case_##name wx_test_case_##name##_instance; \
+void wx_test_case_##name::run()
+
+#endif // wx_test_case_hpp
Property changes on: lmi/trunk/wx_test_case.hpp
___________________________________________________________________
Added: svn:keywords
+ Id
Added: lmi/trunk/wx_test_config_settings.cpp
===================================================================
--- lmi/trunk/wx_test_config_settings.cpp (rev 0)
+++ lmi/trunk/wx_test_config_settings.cpp 2014-10-25 14:42:26 UTC (rev
5995)
@@ -0,0 +1,68 @@
+// Configurable settings test case for the GUI test suite.
+//
+// Copyright (C) 2014 Gregory W. Chicares.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2 as
+// published by the Free Software Foundation.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software Foundation,
+// Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+//
+// http://savannah.nongnu.org/projects/lmi
+// email: <address@hidden>
+// snail: Chicares, 186 Belle Woods Drive, Glastonbury CT 06033, USA
+
+// $Id$
+
+#ifdef __BORLANDC__
+# include "pchfile.hpp"
+# pragma hdrstop
+#endif
+
+#include "assert_lmi.hpp"
+#include "configurable_settings.hpp"
+#include "wx_test_case.hpp"
+
+#include <boost/filesystem/operations.hpp>
+
+LMI_WX_TEST_CASE(configurable_settings)
+{
+ LMI_ASSERT(fs::exists("/etc/opt/lmi/configurable_settings.xml"));
+
+ configurable_settings const& settings = configurable_settings::instance();
+ LMI_ASSERT_EQUAL(settings.libraries_to_preload(), "");
+ LMI_ASSERT_EQUAL(settings.xsl_fo_command(), "CMD /c c:/fop-0.20.5/fop");
+
+ std::string skin = settings.skin_filename();
+ std::string default_input = settings.default_input_filename();
+ LMI_ASSERT_WITH_MSG
+ ( "skin_coli_boli.xrc" == skin
+ || "skin_group_carveout.xrc" == skin
+ || "skin_group_carveout2.xrc" == skin
+ || "reg_d.xrc" == skin
+ ,"unknown skin " << skin
+ );
+ if ("skin_coli_boli.xrc" == skin)
+ {
+ LMI_ASSERT_EQUAL(default_input, "c:/fop-0.20.5/coli_boli_default.ill");
+ }
+ if ("skin_group_carveout.xrc" == skin)
+ {
+ LMI_ASSERT_EQUAL(default_input,
"c:/fop-0.20.5/group_carveout_default.ill");
+ }
+ if ("skin_group_carveout2.xrc" == skin)
+ {
+ LMI_ASSERT_EQUAL(default_input,
"c:/fop-0.20.5/group_carveout_default.ill");
+ }
+ if ("reg_d.xrc" == skin)
+ {
+ LMI_ASSERT_EQUAL(default_input,
"c:/fop-0.20.5/private_placement_default.ill");
+ }
+}
Property changes on: lmi/trunk/wx_test_config_settings.cpp
___________________________________________________________________
Added: svn:keywords
+ Id
Added: lmi/trunk/wx_test_create_open.cpp
===================================================================
--- lmi/trunk/wx_test_create_open.cpp (rev 0)
+++ lmi/trunk/wx_test_create_open.cpp 2014-10-25 14:42:26 UTC (rev 5995)
@@ -0,0 +1,144 @@
+// Test case for creating new files of all types and opening them.
+//
+// Copyright (C) 2014 Gregory W. Chicares.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2 as
+// published by the Free Software Foundation.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software Foundation,
+// Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+//
+// http://savannah.nongnu.org/projects/lmi
+// email: <address@hidden>
+// snail: Chicares, 186 Belle Woods Drive, Glastonbury CT 06033, USA
+
+// $Id$
+
+#ifdef __BORLANDC__
+# include "pchfile.hpp"
+# pragma hdrstop
+#endif
+
+#include "assert_lmi.hpp"
+#include "mvc_controller.hpp"
+#include "wx_test_case.hpp"
+#include "version.hpp"
+
+#include <wx/dialog.h>
+#include <wx/scopeguard.h>
+#include <wx/testing.h>
+#include <wx/uiaction.h>
+
+// Helper of test_new_file_and_save() which tests creating a new file of
+// the type corresponding to the key argument, used to select this type in
+// the "New" popup menu.
+//
+// The last argument indicates whether a dialog is shown when creating a
+// new file of this type (e.g. true for illustrations, false for census).
+// It affects this function behaviour in two ways: first, it needs to be
+// ready for this dialog appearing and, second, "File|Save" menu command is
+// disabled for the files created in this way and "File|Save as" needs to
+// be used instead.
+void do_test_create_open(int key, wxString const& file, bool uses_dialog)
+{
+ LMI_ASSERT(!wxFileExists(file));
+
+ wxUIActionSimulator z;
+ z.Char('n', wxMOD_CONTROL); // new file
+ z.Char(key ); // choose document type
+ if (uses_dialog)
+ {
+ wxTEST_DIALOG
+ (wxYield()
+ ,wxExpectDismissableModal<MvcController>(wxID_OK)
+ );
+ }
+ wxYield();
+
+ z.Char(uses_dialog ? 'a' : 's', wxMOD_CONTROL); // save or save as
+ wxTEST_DIALOG
+ (wxYield()
+ ,wxExpectModal<wxFileDialog>(file)
+ );
+ wxYield();
+
+ LMI_ASSERT(wxFileExists(file));
+ wxON_BLOCK_EXIT1(wxRemoveFile, file);
+
+ z.Char('l', wxMOD_CONTROL); // close document
+ wxYield();
+
+ z.Char('o', wxMOD_CONTROL); // and open it again
+
+ if (uses_dialog)
+ {
+ wxTEST_DIALOG
+ (wxYield()
+ ,wxExpectModal<wxFileDialog>(file)
+ ,wxExpectDismissableModal<MvcController>(wxID_OK)
+ );
+ }
+ else
+ {
+ wxTEST_DIALOG
+ (wxYield()
+ ,wxExpectModal<wxFileDialog>(file)
+ );
+ }
+ wxYield();
+
+ z.Char('l', wxMOD_CONTROL); // close it finally
+ wxYield();
+}
+
+LMI_WX_TEST_CASE(create_open_census)
+{
+ do_test_create_open('c', "testfile.cns", false);
+}
+
+LMI_WX_TEST_CASE(create_open_illustration)
+{
+ do_test_create_open('i', "testfile.ill", true);
+}
+
+LMI_WX_TEST_CASE(create_open_database)
+{
+ do_test_create_open('d', "testfile.database", false);
+}
+
+LMI_WX_TEST_CASE(create_open_policy)
+{
+ do_test_create_open('p', "testfile.policy", false);
+}
+
+LMI_WX_TEST_CASE(create_open_rounding)
+{
+ do_test_create_open('r', "testfile.rounding", false);
+}
+
+LMI_WX_TEST_CASE(create_open_strata)
+{
+ do_test_create_open('s', "testfile.strata", false);
+}
+
+LMI_WX_TEST_CASE(create_open_mec)
+{
+ do_test_create_open('m', "testfile.mec", true);
+}
+
+LMI_WX_TEST_CASE(create_open_gpt)
+{
+ do_test_create_open('g', "testfile.gpt", true);
+}
+
+LMI_WX_TEST_CASE(create_open_text)
+{
+ do_test_create_open('x', "testfile.txt", false);
+}
Property changes on: lmi/trunk/wx_test_create_open.cpp
___________________________________________________________________
Added: svn:keywords
+ Id
Added: lmi/trunk/wx_test_default_input.cpp
===================================================================
--- lmi/trunk/wx_test_default_input.cpp (rev 0)
+++ lmi/trunk/wx_test_default_input.cpp 2014-10-25 14:42:26 UTC (rev 5995)
@@ -0,0 +1,49 @@
+// Default input test case for the GUI test suite.
+//
+// Copyright (C) 2014 Gregory W. Chicares.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2 as
+// published by the Free Software Foundation.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software Foundation,
+// Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+//
+// http://savannah.nongnu.org/projects/lmi
+// email: <address@hidden>
+// snail: Chicares, 186 Belle Woods Drive, Glastonbury CT 06033, USA
+
+// $Id$
+
+#ifdef __BORLANDC__
+# include "pchfile.hpp"
+# pragma hdrstop
+#endif
+
+#include "assert_lmi.hpp"
+#include "calendar_date.hpp"
+#include "illustrator.hpp"
+#include "input.hpp"
+#include "wx_test_case.hpp"
+
+#include <wx/log.h>
+
+LMI_WX_TEST_CASE(default_input)
+{
+ calendar_date const today;
+ calendar_date const first_of_month(today.year(), today.month(), 1);
+
+ Input const& cell = default_cell();
+ calendar_date const effective_date =
exact_cast<tnr_date>(cell["EffectiveDate"])->value();
+ LMI_ASSERT_EQUAL(effective_date, first_of_month);
+
+ std::string const general_account_date =
exact_cast<numeric_sequence>(cell["GeneralAccountRate"])->value();
+ LMI_ASSERT(!general_account_date.empty());
+ wxLogMessage("GeneralAccountRate is \"%s\"", general_account_date.c_str());
+}
Property changes on: lmi/trunk/wx_test_default_input.cpp
___________________________________________________________________
Added: svn:keywords
+ Id
Added: lmi/trunk/wx_test_default_update.cpp
===================================================================
--- lmi/trunk/wx_test_default_update.cpp (rev 0)
+++ lmi/trunk/wx_test_default_update.cpp 2014-10-25 14:42:26 UTC (rev
5995)
@@ -0,0 +1,97 @@
+// Check that the default file can be opened and modified.
+//
+// Copyright (C) 2014 Gregory W. Chicares.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2 as
+// published by the Free Software Foundation.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software Foundation,
+// Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+//
+// http://savannah.nongnu.org/projects/lmi
+// email: <address@hidden>
+// snail: Chicares, 186 Belle Woods Drive, Glastonbury CT 06033, USA
+
+// $Id$
+
+#ifdef __BORLANDC__
+# include "pchfile.hpp"
+# pragma hdrstop
+#endif
+
+#include "assert_lmi.hpp"
+#include "configurable_settings.hpp"
+#include "wx_test_case.hpp"
+#include "wx_test_mvc_dialog.hpp"
+#include "wx_test_statusbar.hpp"
+
+#include <wx/testing.h>
+#include <wx/uiaction.h>
+
+#include <boost/filesystem/operations.hpp>
+
+LMI_WX_TEST_CASE(default_update)
+{
+ wxUIActionSimulator ui;
+
+ // Change the "MEC Avoidance" option in the first page of the defaults
+ // dialog.
+ ui.Char('t', wxMOD_CONTROL); // "File|Default"
+
+ struct change_mac_in_defaults_dialog
+ :public ExpectMvcDialog
+ {
+ virtual void DoRunDialog(MvcController* dialog) const
+ {
+ wxUIActionSimulator ui;
+
+ // Go to the first page: as the dialog remembers its last opened
+ // page, it might not open on it.
+ ui.Char(WXK_HOME);
+ wxYield();
+
+ // Select the first button of the "MEC Avoidance" radio box.
+ ui.Char(WXK_TAB);
+ ui.Char(WXK_TAB);
+ wxYield();
+
+ // Change its value: it doesn't matter which button is selected,
+ // pressing the down arrow will always toggle the selection in a
+ // radio box with two buttons.
+ ui.Char(WXK_DOWN);
+ wxYield();
+ }
+ };
+
+ wxTEST_DIALOG
+ (wxYield()
+ ,change_mac_in_defaults_dialog()
+ );
+
+ // Save the default document.
+ ui.Char('s', wxMOD_CONTROL); // "File|Save"
+ wxYield();
+
+ // Verify that the expected message about saving it was given.
+ std::string const
+ filename = configurable_settings::instance().default_input_filename();
+
+ LMI_ASSERT_EQUAL
+ (get_main_window_statusbar_text()
+ ,wxString::Format("Saved '%s'.", filename)
+ );
+
+ // Close the document now that it's not needed any more.
+ ui.Char('l', wxMOD_CONTROL); // "File|Close"
+ wxYield();
+
+ // Finally also check that the file actually exists.
+ LMI_ASSERT(fs::exists(filename));
+}
Property changes on: lmi/trunk/wx_test_default_update.cpp
___________________________________________________________________
Added: svn:keywords
+ Id
Added: lmi/trunk/wx_test_expiry_dates.cpp
===================================================================
--- lmi/trunk/wx_test_expiry_dates.cpp (rev 0)
+++ lmi/trunk/wx_test_expiry_dates.cpp 2014-10-25 14:42:26 UTC (rev 5995)
@@ -0,0 +1,78 @@
+// Expire dates test case for the GUI test suite.
+//
+// Copyright (C) 2014 Gregory W. Chicares.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2 as
+// published by the Free Software Foundation.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software Foundation,
+// Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+//
+// http://savannah.nongnu.org/projects/lmi
+// email: <address@hidden>
+// snail: Chicares, 186 Belle Woods Drive, Glastonbury CT 06033, USA
+
+// $Id$
+
+#ifdef __BORLANDC__
+# include "pchfile.hpp"
+# pragma hdrstop
+#endif
+
+#include "assert_lmi.hpp"
+#include "calendar_date.hpp"
+#include "global_settings.hpp"
+#include "wx_test_case.hpp"
+#include "version.hpp"
+
+#include <boost/filesystem/fstream.hpp>
+#include <boost/filesystem/operations.hpp>
+
+LMI_WX_TEST_CASE(expiry_dates)
+{
+ fs::path expiry_path(global_settings::instance().data_directory() /
"expiry");
+ fs::ifstream is(expiry_path);
+ LMI_ASSERT(is);
+
+ calendar_date begin(last_yyyy_date ());
+ calendar_date end (gregorian_epoch());
+ is >> begin >> end;
+ LMI_ASSERT(is);
+ LMI_ASSERT(is.eof());
+
+ // The begin date must either be the first of month itself or a date in the
+ // previous month, in which case we're interested in the end of the
+ // following month and not the same one.
+ int year = begin.year();
+ int month = begin.month();
+ int days_in_month;
+
+ if(begin.day() == 1)
+ {
+ days_in_month = begin.days_in_month();
+ }
+ else
+ {
+ if(month == 12)
+ {
+ month = 1;
+ year++;
+ }
+ else
+ {
+ month++;
+ }
+
+ days_in_month = calendar_date(year, month, 1).days_in_month();
+ }
+
+ calendar_date const end_of_month(year, month, days_in_month);
+ LMI_ASSERT_EQUAL(end, end_of_month);
+}
Property changes on: lmi/trunk/wx_test_expiry_dates.cpp
___________________________________________________________________
Added: svn:keywords
+ Id
Added: lmi/trunk/wx_test_extract.cpp
===================================================================
--- lmi/trunk/wx_test_extract.cpp (rev 0)
+++ lmi/trunk/wx_test_extract.cpp 2014-10-25 14:42:26 UTC (rev 5995)
@@ -0,0 +1,74 @@
+// Test extract file formats.
+//
+// Copyright (C) 2014 Gregory W. Chicares.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2 as
+// published by the Free Software Foundation.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software Foundation,
+// Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+//
+// http://savannah.nongnu.org/projects/lmi
+// email: <address@hidden>
+// snail: Chicares, 186 Belle Woods Drive, Glastonbury CT 06033, USA
+
+// $Id$
+
+#ifdef __BORLANDC__
+# include "pchfile.hpp"
+# pragma hdrstop
+#endif
+
+#include "assert_lmi.hpp"
+#include "configurable_settings.hpp"
+#include "mvc_controller.hpp"
+#include "wx_test_case.hpp"
+
+#include <wx/filename.h>
+#include <wx/testing.h>
+#include <wx/uiaction.h>
+
+#include <stdexcept>
+
+LMI_WX_TEST_CASE(extract)
+{
+ wxUIActionSimulator ui;
+ ui.Char('o', wxMOD_CONTROL); // "File|Open"
+
+ wxFileName fn(configurable_settings::instance().default_input_filename());
+ fn.SetFullName("ExtractV6.ill");
+ wxTEST_DIALOG
+ (wxYield()
+ ,wxExpectModal<wxFileDialog>(fn.GetFullPath())
+ ,wxExpectModal<wxMessageDialog>(wxOK) // Dismiss first warning.
+ ,wxExpectModal<wxMessageDialog>(wxOK) // And the second one.
+ ,wxExpectDismissableModal<MvcController>(wxID_OK) // Accept defaults.
+ );
+
+ ui.Char('l', wxMOD_CONTROL); // "File|Close"
+ wxTEST_DIALOG
+ (wxYield()
+ ,wxExpectModal<wxMessageDialog>(wxNO) // Don't save changes.
+ );
+
+ ui.Char('o', wxMOD_CONTROL); // "File|Open"
+
+ fn.SetFullName("ExtractV5.cns");
+ wxTEST_DIALOG
+ (wxYield()
+ ,wxExpectModal<wxFileDialog>(fn.GetFullPath())
+ ,wxExpectModal<wxMessageDialog>(wxOK) // Dismiss first warning.
+ ,wxExpectModal<wxMessageDialog>(wxOK) // And the second one.
+ ,wxExpectModal<wxMessageDialog>(wxOK) // And the third one.
+ );
+
+ ui.Char('l', wxMOD_CONTROL); // "File|Close"
+ wxYield();
+}
Property changes on: lmi/trunk/wx_test_extract.cpp
___________________________________________________________________
Added: svn:keywords
+ Id
Added: lmi/trunk/wx_test_input_sequences.cpp
===================================================================
--- lmi/trunk/wx_test_input_sequences.cpp (rev 0)
+++ lmi/trunk/wx_test_input_sequences.cpp 2014-10-25 14:42:26 UTC (rev
5995)
@@ -0,0 +1,62 @@
+// Test running the input sequences case.
+//
+// Copyright (C) 2014 Gregory W. Chicares.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2 as
+// published by the Free Software Foundation.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software Foundation,
+// Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+//
+// http://savannah.nongnu.org/projects/lmi
+// email: <address@hidden>
+// snail: Chicares, 186 Belle Woods Drive, Glastonbury CT 06033, USA
+
+// $Id$
+
+#ifdef __BORLANDC__
+# include "pchfile.hpp"
+# pragma hdrstop
+#endif
+
+#include "assert_lmi.hpp"
+#include "configurable_settings.hpp"
+#include "wx_test_case.hpp"
+
+#include <wx/filename.h>
+#include <wx/testing.h>
+#include <wx/uiaction.h>
+
+LMI_WX_TEST_CASE(input_sequences)
+{
+ // Construct the path of the file to open, it's supposed to be in the same
+ // directory as the default input filename.
+ wxFileName fn(configurable_settings::instance().default_input_filename());
+ fn.SetFullName("InputSequences.cns");
+
+ wxUIActionSimulator ui;
+
+ ui.Char('o', wxMOD_CONTROL); // "File|Open"
+ wxTEST_DIALOG
+ (wxYield()
+ ,wxExpectModal<wxFileDialog>(fn.GetFullPath())
+ );
+
+ ui.Char('r', wxMOD_CONTROL | wxMOD_SHIFT); // "Census|Run case"
+ wxYield();
+
+ // Close the illustration opened by "Run case".
+ ui.Char('l', wxMOD_CONTROL); // "File|Close"
+ wxYield();
+
+ // And the census itself as well.
+ ui.Char('l', wxMOD_CONTROL); // "File|Close"
+ wxYield();
+}
Property changes on: lmi/trunk/wx_test_input_sequences.cpp
___________________________________________________________________
Added: svn:keywords
+ Id
Added: lmi/trunk/wx_test_input_validation.cpp
===================================================================
--- lmi/trunk/wx_test_input_validation.cpp (rev 0)
+++ lmi/trunk/wx_test_input_validation.cpp 2014-10-25 14:42:26 UTC (rev
5995)
@@ -0,0 +1,82 @@
+// Test validation of input ranges in a census.
+//
+// Copyright (C) 2014 Gregory W. Chicares.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2 as
+// published by the Free Software Foundation.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software Foundation,
+// Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+//
+// http://savannah.nongnu.org/projects/lmi
+// email: <address@hidden>
+// snail: Chicares, 186 Belle Woods Drive, Glastonbury CT 06033, USA
+
+// $Id$
+
+#ifdef __BORLANDC__
+# include "pchfile.hpp"
+# pragma hdrstop
+#endif
+
+#include "assert_lmi.hpp"
+#include "configurable_settings.hpp"
+#include "wx_test_case.hpp"
+
+#include <wx/filename.h>
+#include <wx/testing.h>
+#include <wx/uiaction.h>
+
+#include <stdexcept>
+
+LMI_WX_TEST_CASE(input_validation)
+{
+ wxUIActionSimulator ui;
+ ui.Char('o', wxMOD_CONTROL); // "File|Open"
+
+ wxFileName fn(configurable_settings::instance().default_input_filename());
+ fn.SetFullName("CoiMultiplier.cns");
+ wxTEST_DIALOG
+ (wxYield()
+ ,wxExpectModal<wxFileDialog>(fn.GetFullPath())
+ );
+
+ ui.Char('r', wxMOD_CONTROL | wxMOD_SHIFT); // "Census|Run case"
+
+ // Test that the expected exception is generated.
+ bool error_detected = false;
+ try
+ {
+ wxYield();
+ }
+ catch(std::runtime_error& e)
+ {
+ error_detected = true;
+
+ // The error message contains a line of the form "[file %s, line %d]"
+ // at the end which we want to ignore, as the line number and possibly
+ // the file name can change and are irrelevant to this check anyhow, so
+ // find this line presence and ignore it in comparison.
+ std::string const error_message = e.what();
+ std::string::size_type loc_pos = error_message.find("\n[file");
+ LMI_ASSERT(loc_pos != std::string::npos);
+
+ LMI_ASSERT_EQUAL
+ (error_message.substr(0, loc_pos),
+ "Input validation problems for '':\n"
+ "COI multiplier entered is '0', but it must contain at least one
number other than zero.\n"
+ );
+ }
+
+ ui.Char('l', wxMOD_CONTROL); // "File|Close"
+ wxYield();
+
+ LMI_ASSERT(error_detected);
+}
Property changes on: lmi/trunk/wx_test_input_validation.cpp
___________________________________________________________________
Added: svn:keywords
+ Id
Added: lmi/trunk/wx_test_mvc_dialog.hpp
===================================================================
--- lmi/trunk/wx_test_mvc_dialog.hpp (rev 0)
+++ lmi/trunk/wx_test_mvc_dialog.hpp 2014-10-25 14:42:26 UTC (rev 5995)
@@ -0,0 +1,82 @@
+// Helper for testing MvcController dialogs.
+//
+// Copyright (C) 2014 Gregory W. Chicares.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2 as
+// published by the Free Software Foundation.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software Foundation,
+// Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+//
+// http://savannah.nongnu.org/projects/lmi
+// email: <address@hidden>
+// snail: Chicares, 186 Belle Woods Drive, Glastonbury CT 06033, USA
+
+// $Id$
+
+#ifndef wx_test_mvc_dialog_hpp
+#define wx_test_mvc_dialog_hpp
+
+#include "config.hpp"
+
+#include "mvc_controller.hpp"
+
+#include <wx/scopeguard.h>
+#include <wx/testing.h>
+
+/// Abstract base class for the concrete expectations defining the actions to
+/// perform when a given MvcController-derived dialog is shown.
+///
+/// The main reason for this class existence is the unusual reliance of
+/// MvcController on wxEVT_UPDATE_UI events for its functionality. As these
+/// events are not sent from inside wxYield(), which is used throughout the
+/// automatic tests, the dialog is not updated (i.e. the controls inside it
+/// are not enabled when they should be, the corresponding program variables
+/// are not updated when GUI controls change, and so on) unless we send these
+/// events ourselves and this class helps with doing it.
+
+class ExpectMvcDialog
+ :public wxExpectModalBase<MvcController>
+{
+ public:
+ virtual int OnInvoked(MvcController* dialog) const
+ {
+ // Bring the dialog up.
+ dialog->Show();
+ wxYield();
+
+ // Perform whichever actions are needed.
+ DoRunDialog(dialog);
+
+ // And ensure that the model data is updated at the end.
+ DoUpdateDialogUI(dialog);
+
+ return wxID_OK;
+ }
+
+ protected:
+ // The method to be implemented in the derived classes for simulating the
+ // user actions that need to be performed in this dialog.
+ //
+ // DoUpdateDialogUI() should be used after simulating any action updating
+ // the state of the dialog.
+ virtual void DoRunDialog(MvcController* dialog) const = 0;
+
+ // Ensure that the dialog state takes into account all the events simulated
+ // so far by explicitly letting it process a wxUpdateUIEvent.
+ void DoUpdateDialogUI(MvcController* dialog) const
+ {
+ wxUpdateUIEvent event(dialog->GetId());
+ event.SetEventObject(dialog);
+ dialog->ProcessWindowEvent(event);
+ }
+};
+
+#endif // wx_test_mvc_dialog_hpp
Property changes on: lmi/trunk/wx_test_mvc_dialog.hpp
___________________________________________________________________
Added: svn:keywords
+ Id
Added: lmi/trunk/wx_test_new.hpp
===================================================================
--- lmi/trunk/wx_test_new.hpp (rev 0)
+++ lmi/trunk/wx_test_new.hpp 2014-10-25 14:42:26 UTC (rev 5995)
@@ -0,0 +1,166 @@
+// Helper for creating new documents in unattended GUI tests.
+//
+// Copyright (C) 2014 Gregory W. Chicares.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2 as
+// published by the Free Software Foundation.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software Foundation,
+// Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+//
+// http://savannah.nongnu.org/projects/lmi
+// email: <address@hidden>
+// snail: Chicares, 186 Belle Woods Drive, Glastonbury CT 06033, USA
+
+// $Id$
+
+#ifndef wx_test_new_hpp
+#define wx_test_new_hpp
+
+#include "config.hpp"
+
+#include "mvc_controller.hpp"
+#include "uncopyable_lmi.hpp"
+
+#include <wx/log.h>
+#include <wx/testing.h>
+#include <wx/uiaction.h>
+
+/// Helper base class for classes testing creation of specific new documents.
+///
+/// This class provides methods for closing the current document, optionally
+/// discarding the changes done to it.
+///
+/// Unfortunately it is impossible to close the document automatically from
+/// this class dtor as doing this may result in an exception and throwing from
+/// dtors is too dangerous, generally speaking (and not allowed at all by
+/// default since C++11), to prefer it to an approach involving explicit calls
+/// to close().
+
+class wx_test_new_document_base
+ :private lmi::uncopyable<wx_test_new_document_base>
+{
+ public:
+ wx_test_new_document_base()
+ :opened_(false)
+ {
+ }
+
+ ~wx_test_new_document_base()
+ {
+ // As we don't want to throw an exception from the dtor, all we can do
+ // is to complain to the user directly.
+ if(opened_)
+ {
+ wxSafeShowMessage
+ ("Programming error"
+ ,"A document created during unattended test hasn't been
closed, "
+ "please report this."
+ );
+ }
+ }
+
+ // Close the document window, the document must not be modified.
+ void close()
+ {
+ do_close();
+
+ wxYield();
+ }
+
+ // Close the document window, the document must have been modified and the
+ // changes to it will be discarded.
+ void close_discard_changes()
+ {
+ do_close();
+
+ wxTEST_DIALOG(wxYield(), wxExpectModal<wxMessageDialog>(wxNO));
+ }
+
+ protected:
+ // This method should be called by the derived classes when the document
+ // window is really opened.
+ void set_opened() { opened_ = true; }
+
+ private:
+ // Common part of different close() methods.
+ void do_close()
+ {
+ // If we started closing the document, we should reset the flag: even
+ // if closing it fails, we shouldn't complain about forgetting to close
+ // it as we clearly didn't forget to do it.
+ opened_ = false;
+
+ wxUIActionSimulator ui;
+ ui.Char('l', wxMOD_CONTROL); // "File|Close"
+ }
+
+ bool opened_;
+};
+
+/// Represents a new illustration document.
+///
+/// Instantiating an object of this class simulates creating a new
illustration.
+/// Its close() method must be called before destroying an object of this class
+/// to ensure that it doesn't stay open.
+
+class wx_test_new_illustration
+ :public wx_test_new_document_base
+{
+ public:
+ // Default constructor creates an illustration with the default parameters.
+ wx_test_new_illustration()
+ {
+ do_new_illustration(wxExpectDismissableModal<MvcController>(wxID_OK));
+ }
+
+ // This constructor takes a class responsible for handling the illustration
+ // parameters dialog and may modify it in any desired way before accepting.
+ wx_test_new_illustration(wxModalExpectation const& e)
+ {
+ do_new_illustration(e);
+ }
+
+ private:
+ // Common part of both constructors.
+ void do_new_illustration(wxModalExpectation const& e)
+ {
+ wxUIActionSimulator ui;
+ ui.Char('n', wxMOD_CONTROL); // "File|New"
+ ui.Char('i'); // "Illustration"
+
+ wxTEST_DIALOG(wxYield(), e);
+
+ set_opened();
+ }
+};
+
+/// Represents a new census document.
+///
+/// Instantiating an object of this class simulates creating a new census
+/// document. As with illustrations, close() method must be called before
+/// destroying it.
+
+class wx_test_new_census
+ :public wx_test_new_document_base
+{
+ public:
+ wx_test_new_census()
+ {
+ wxUIActionSimulator ui;
+ ui.Char('n', wxMOD_CONTROL); // "File|New"
+ ui.Char('c'); // "Census"
+ wxYield();
+
+ set_opened();
+ }
+};
+
+#endif // wx_test_new_hpp
Property changes on: lmi/trunk/wx_test_new.hpp
___________________________________________________________________
Added: svn:keywords
+ Id
Added: lmi/trunk/wx_test_paste_census.cpp
===================================================================
--- lmi/trunk/wx_test_paste_census.cpp (rev 0)
+++ lmi/trunk/wx_test_paste_census.cpp 2014-10-25 14:42:26 UTC (rev 5995)
@@ -0,0 +1,232 @@
+// Test pasting data into a census.
+//
+// Copyright (C) 2014 Gregory W. Chicares.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2 as
+// published by the Free Software Foundation.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software Foundation,
+// Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+//
+// http://savannah.nongnu.org/projects/lmi
+// email: <address@hidden>
+// snail: Chicares, 186 Belle Woods Drive, Glastonbury CT 06033, USA
+
+// $Id$
+
+#ifdef __BORLANDC__
+# include "pchfile.hpp"
+# pragma hdrstop
+#endif
+
+#include "assert_lmi.hpp"
+#include "data_directory.hpp"
+#include "wx_test_case.hpp"
+#include "wx_test_mvc_dialog.hpp"
+#include "wx_test_new.hpp"
+#include "wx_utility.hpp"
+
+#include <wx/app.h>
+#include <wx/dataview.h>
+#include <wx/dialog.h>
+#include <wx/ffile.h>
+#include <wx/filefn.h>
+#include <wx/html/htmlpars.h>
+#include <wx/mdi.h>
+#include <wx/radiobox.h>
+#include <wx/testing.h>
+#include <wx/uiaction.h>
+
+namespace
+{
+
+// Helper function to get the census data to be pasted.
+wxString get_census_data()
+{
+ // Get the census example from help. This is an HTML file but we don't have
+ // an HTML parser and HTML is not valid XML, so it can't be parsed as such.
+ // Instead we just rely on the very particular format of this file: right
+ // now it contains the census data between the only occurrences of <pre>
+ // and </pre> tags in it, so locate them and take everything inside.
+
+ wxFFile f(AddDataDir("pasting_to_a_census.html"));
+ LMI_ASSERT(f.IsOpened());
+
+ wxString html;
+ LMI_ASSERT(f.ReadAll(&html));
+
+ size_t const pos_pre = html.find("<pre>\n");
+ LMI_ASSERT(pos_pre != wxString::npos);
+
+ size_t const pos_pre_end = html.find("</pre>", pos_pre);
+ LMI_ASSERT(pos_pre_end != wxString::npos);
+
+ size_t const pos_pre_start = pos_pre + strlen("<pre>\n");
+ wxString const text_pre = html.substr
+ (pos_pre_start
+ , pos_pre_end - pos_pre_start
+ );
+
+ // We're not done yet, we need to deal with the HTML entities. Do use HTML
+ // parsing code in wxWidgets for this at least.
+ return wxHtmlEntitiesParser().Parse(text_pre);
+}
+
+// Helper function to find the wxDataViewCtrl used for the census display.
+//
+// Precondition: the currently active window must be a CensusView.
+wxDataViewCtrl* find_census_list_window()
+{
+ wxWindow* const top_window = wxTheApp->GetTopWindow();
+ LMI_ASSERT(top_window);
+
+ wxMDIParentFrame* const
+ parent_frame = dynamic_cast<wxMDIParentFrame*>(top_window);
+ LMI_ASSERT(parent_frame);
+
+ wxMDIChildFrame* const child_frame = parent_frame->GetActiveChild();
+ LMI_ASSERT(child_frame);
+
+ wxWindowList const& census_children = child_frame->GetChildren();
+ wxWindowList::const_iterator z = census_children.begin();
+ LMI_ASSERT(z != census_children.end());
+
+ wxDataViewCtrl* const dvc = dynamic_cast<wxDataViewCtrl*>(*z);
+ LMI_ASSERT(dvc);
+
+ return dvc;
+}
+
+// Retrieve the list model from list window.
+//
+// Precondition: this wxDataViewCtrl must actually use a list model.
+wxDataViewListModel* get_census_list_model(wxDataViewCtrl* dvc)
+{
+ wxDataViewModel* const model = dvc->GetModel();
+ LMI_ASSERT(model);
+
+ wxDataViewListModel* const
+ list_model = dynamic_cast<wxDataViewListModel*>(model);
+ LMI_ASSERT(list_model);
+
+ return list_model;
+}
+
+// Check for the presence of the column with the given name.
+bool does_list_have_column(wxDataViewCtrl* dvc, wxString const& name)
+{
+ unsigned int const num_columns = dvc->GetColumnCount();
+ for(unsigned int n = 0; n < num_columns; ++n)
+ {
+ if (dvc->GetColumn(n)->GetTitle() == name)
+ {
+ return true;
+ }
+ }
+ return false;
+}
+
+} // Unnamed namespace.
+
+LMI_WX_TEST_CASE(paste_census)
+{
+ // Put the data to paste on clipboard.
+ ClipboardEx::SetText(get_census_data().ToStdString());
+
+ // Create a new census.
+ wx_test_new_census census;
+
+ // Paste data into it.
+ wxUIActionSimulator ui;
+ ui.Char('s', wxMOD_CONTROL | wxMOD_SHIFT); // "Census|Paste census data"
+ wxYield();
+
+ // Find the model containing the cells and check that it was filled in
+ // correctly.
+ wxDataViewCtrl* const list_window = find_census_list_window();
+ wxDataViewListModel* const list_model = get_census_list_model(list_window);
+ LMI_ASSERT_EQUAL(list_model->GetCount(), 7);
+
+ static char const* column_title = "Underwriting Class";
+ LMI_ASSERT(does_list_have_column(list_window, column_title));
+
+ // Change the case defaults to get rid of the underwriting class.
+ ui.Char('e', wxMOD_CONTROL | wxMOD_SHIFT); // "Census|Edit case defaults"
+
+ struct change_class_in_case_defaults_dialog
+ :public ExpectMvcDialog
+ {
+ virtual void DoRunDialog(MvcController* dialog) const
+ {
+ wxUIActionSimulator ui;
+
+ // Go to the third page: as the dialog remembers its last opened
+ // page, ensure that we start from the first one.
+ ui.Char(WXK_HOME);
+ ui.Char(WXK_RIGHT);
+ ui.Char(WXK_RIGHT);
+ wxYield();
+
+ // We can't find directly the radio button we're interested in,
+ // because it's not a real wxWindow, so we need to find the radio
+ // box containing it.
+ wxWindow* const class_window = wxWindow::FindWindowByName
+ ("UnderwritingClass"
+ ,dialog
+ );
+ LMI_ASSERT(class_window);
+
+ wxRadioBox* const
+ class_radiobox = dynamic_cast<wxRadioBox*>(class_window);
+ LMI_ASSERT(class_radiobox);
+
+ // It's difficult to select the radiobox using just
+ // wxUIActionSimulator as there is no keyboard shortcut to navigate
+ // to it and emulating a mouse click on it is tricky as we don't
+ // want to change its selection by clicking on the item, so do it
+ // programmatically, the effect should be absolutely the same.
+ class_radiobox->SetFocus();
+ wxYield();
+
+ ui.Char(WXK_UP); // Select the first, "Preferred", radio button.
+ wxYield();
+
+ LMI_ASSERT_EQUAL(class_radiobox->GetSelection(), 0);
+ }
+ };
+
+ // The menu command above should have opened the "Case defaults" dialog and
+ // our code dealing with it above is supposed to result in an appearance of
+ // "Apply all changes to every cell?" message box for which we provide an
+ // affirmative answer.
+ wxTEST_DIALOG
+ (wxYield()
+ ,change_class_in_case_defaults_dialog()
+ ,wxExpectModal<wxMessageDialog>(wxYES)
+ );
+
+ // Check that we still have the same cells but that now the underwriting
+ // class column has disappeared as its value has been fixed.
+ LMI_ASSERT_EQUAL(list_model->GetCount(), 7);
+ LMI_ASSERT(!does_list_have_column(list_window, column_title));
+
+ // Finally save the census with the pasted data for later inspection.
+ static char const* census_file_name = "PasteCensus.cns";
+
+ ui.Char('a', wxMOD_CONTROL); // "File|Save as"
+ wxTEST_DIALOG
+ (wxYield()
+ ,wxExpectModal<wxFileDialog>(census_file_name)
+ );
+
+ LMI_ASSERT(wxFileExists(census_file_name));
+
+ census.close();
+}
Property changes on: lmi/trunk/wx_test_paste_census.cpp
___________________________________________________________________
Added: svn:keywords
+ Id
Added: lmi/trunk/wx_test_pdf_create.cpp
===================================================================
--- lmi/trunk/wx_test_pdf_create.cpp (rev 0)
+++ lmi/trunk/wx_test_pdf_create.cpp 2014-10-25 14:42:26 UTC (rev 5995)
@@ -0,0 +1,142 @@
+// Test creating PDF output for census and illustration documents.
+//
+// Copyright (C) 2014 Gregory W. Chicares.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2 as
+// published by the Free Software Foundation.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software Foundation,
+// Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+//
+// http://savannah.nongnu.org/projects/lmi
+// email: <address@hidden>
+// snail: Chicares, 186 Belle Woods Drive, Glastonbury CT 06033, USA
+
+// $Id$
+
+#ifdef __BORLANDC__
+# include "pchfile.hpp"
+# pragma hdrstop
+#endif
+
+#include "assert_lmi.hpp"
+#include "configurable_settings.hpp"
+#include "wx_test_case.hpp"
+#include "wx_test_new.hpp"
+
+#include <wx/docview.h>
+#include <wx/testing.h>
+#include <wx/uiaction.h>
+
+#include <boost/filesystem/operations.hpp>
+
+namespace
+{
+
+// Get the name used for the last created document: it depends on the tests
+// that had been ran previously, so get it from the document itself.
+std::string get_current_document_name()
+{
+ wxDocManager const* const docm = wxDocManager::GetDocumentManager();
+ LMI_ASSERT(docm);
+ wxDocument const* const doc = docm->GetCurrentDocument();
+ LMI_ASSERT(doc);
+
+ return doc->GetUserReadableName().ToStdString();
+}
+
+// Build the path for the output PDF with the given base name.
+fs::path make_pdf_path(std::string const& base_name)
+{
+ fs::path pdf_path(configurable_settings::instance().print_directory());
+ pdf_path /= base_name + ".pdf";
+
+ return pdf_path;
+}
+
+// Return the suffix used for the FO files created by printing the census.
+std::string fo_suffix(int n)
+{
+ return wxString::Format(".%09d", n).ToStdString();
+}
+
+} // Unnamed namespace.
+
+LMI_WX_TEST_CASE(pdf_illustration)
+{
+ // Create a new illustration.
+ wx_test_new_illustration ill;
+
+ // Ensure that the output file doesn't exist in the first place.
+ fs::path const pdf_path(make_pdf_path(get_current_document_name()));
+ fs::remove(pdf_path);
+
+ // Launch the PDF creation as side effect of previewing it.
+ wxUIActionSimulator ui;
+ ui.Char('v', wxMOD_CONTROL); // "File|Print preview"
+ wxYield();
+
+ // Close the illustration, we don't need it any more.
+ ill.close();
+
+ // Finally check for the expected output file existence.
+ LMI_ASSERT(fs::exists(pdf_path));
+
+ // Don't remove it here, the PDF file is still opened in the PDF reader and
+ // can't be removed before it is closed.
+}
+
+LMI_WX_TEST_CASE(pdf_census)
+{
+ // Create a new census.
+ wx_test_new_census census;
+
+ // Add some cells to the census (it starts with one already).
+ wxUIActionSimulator ui;
+ static const int num_cells = 3;
+ for(int n = 0; n < num_cells - 1; ++n)
+ {
+ ui.Char('+', wxMOD_CONTROL); // "Census|Add cell".
+ wxYield();
+ }
+
+ // Remove the expected output files to avoid false positives if they are
+ // already present and not created by the test.
+ std::string const name = get_current_document_name();
+
+ fs::path const
+ composite_pdf_path(make_pdf_path(name + ".composite" + fo_suffix(0)));
+ fs::remove(composite_pdf_path);
+
+ fs::path cell_pdf_paths[num_cells];
+ for(int n = 0; n < num_cells; ++n)
+ {
+ cell_pdf_paths[n] = make_pdf_path(name + fo_suffix(n + 1));
+ fs::remove(cell_pdf_paths[n]);
+ }
+
+ // Print the census to disk.
+ ui.Char('k', wxMOD_CONTROL | wxMOD_SHIFT); // "Census|Print case to disk"
+ wxYield();
+
+ // Close the census, we don't need it any more, and answer "No" to the
+ // message box asking whether it should be saved.
+ census.close_discard_changes();
+
+ // Check the existence of the files and, unlike in the illustration case,
+ // also delete them as they are not opened in any external viewer.
+ LMI_ASSERT(fs::exists(composite_pdf_path));
+ fs::remove(composite_pdf_path);
+ for(int n = 0; n < num_cells; ++n)
+ {
+ LMI_ASSERT(fs::exists(cell_pdf_paths[n]));
+ fs::remove(cell_pdf_paths[n]);
+ }
+}
Property changes on: lmi/trunk/wx_test_pdf_create.cpp
___________________________________________________________________
Added: svn:keywords
+ Id
Added: lmi/trunk/wx_test_statusbar.hpp
===================================================================
--- lmi/trunk/wx_test_statusbar.hpp (rev 0)
+++ lmi/trunk/wx_test_statusbar.hpp 2014-10-25 14:42:26 UTC (rev 5995)
@@ -0,0 +1,60 @@
+// Helpers for checking status bar contents in unattended GUI tests.
+//
+// Copyright (C) 2014 Gregory W. Chicares.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2 as
+// published by the Free Software Foundation.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software Foundation,
+// Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+//
+// http://savannah.nongnu.org/projects/lmi
+// email: <address@hidden>
+// snail: Chicares, 186 Belle Woods Drive, Glastonbury CT 06033, USA
+
+// $Id$
+
+#ifndef wx_test_statusbar_hpp
+#define wx_test_statusbar_hpp
+
+#include "config.hpp"
+
+#include "assert_lmi.hpp"
+
+#include <wx/app.h>
+#include <wx/frame.h>
+#include <wx/statusbr.h>
+
+/// Return the status bar of the main window throwing an exception if anything
+/// goes wrong.
+
+inline wxStatusBar const& get_main_window_statusbar()
+{
+ wxWindow* const mainWin = wxTheApp->GetTopWindow();
+ LMI_ASSERT(mainWin);
+
+ wxFrame* const frame = wxDynamicCast(mainWin, wxFrame);
+ LMI_ASSERT(frame);
+
+ wxStatusBar* const status = frame->GetStatusBar();
+ LMI_ASSERT(status);
+
+ return *status;
+}
+
+/// Return the contents of the status of the main window throwing an exception
+/// if it can't be retrieved.
+
+inline wxString get_main_window_statusbar_text()
+{
+ return get_main_window_statusbar().GetStatusText();
+}
+
+#endif // wx_test_statusbar_hpp
Property changes on: lmi/trunk/wx_test_statusbar.hpp
___________________________________________________________________
Added: svn:keywords
+ Id
Added: lmi/trunk/wx_test_validate_output.cpp
===================================================================
--- lmi/trunk/wx_test_validate_output.cpp (rev 0)
+++ lmi/trunk/wx_test_validate_output.cpp 2014-10-25 14:42:26 UTC (rev
5995)
@@ -0,0 +1,193 @@
+// Validate existence and naming conventions of output files.
+//
+// Copyright (C) 2014 Gregory W. Chicares.
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2 as
+// published by the Free Software Foundation.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software Foundation,
+// Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+//
+// http://savannah.nongnu.org/projects/lmi
+// email: <address@hidden>
+// snail: Chicares, 186 Belle Woods Drive, Glastonbury CT 06033, USA
+
+// $Id$
+
+#ifdef __BORLANDC__
+# include "pchfile.hpp"
+# pragma hdrstop
+#endif
+
+#include "assert_lmi.hpp"
+#include "configurable_settings.hpp"
+#include "mvc_controller.hpp"
+#include "uncopyable_lmi.hpp"
+#include "wx_test_case.hpp"
+#include "wx_test_mvc_dialog.hpp"
+#include "wx_test_new.hpp"
+
+#include <wx/filename.h>
+#include <wx/testing.h>
+#include <wx/uiaction.h>
+
+#include <boost/filesystem/operations.hpp>
+
+namespace
+{
+
+/// Class helping to check for the expected output file existence.
+///
+/// This class takes care of ensuring that the file doesn't exist when it is
+/// constructed and provides a way to check for the existence of the file
+/// later. It also cleans up the file when it is destroyed.
+
+class output_file_existence_checker
+ :private lmi::uncopyable<output_file_existence_checker>
+{
+ public:
+ output_file_existence_checker(std::string const& path)
+ :path_(path)
+ {
+ fs::remove(path_);
+ }
+
+ void assert_exists() const
+ {
+ LMI_ASSERT(fs::exists(path_));
+ }
+
+ ~output_file_existence_checker()
+ {
+ try
+ {
+ fs::remove(path_);
+ }
+ catch(...)
+ {
+ }
+ }
+
+ private:
+ fs::path path_;
+};
+
+} // Unnamed namespace.
+
+LMI_WX_TEST_CASE(validate_output_illustration)
+{
+ std::string const&
+ ext = configurable_settings::instance().spreadsheet_file_extension();
+
+ // Build the path existence of which we're going to check and ensure that
+ // it doesn't exist before the start of the test.
+ output_file_existence_checker unnamed_trace("unnamed.monthly_trace" + ext);
+
+ struct enter_comment_in_illustration_dialog
+ :public ExpectMvcDialog
+ {
+ virtual void DoRunDialog(MvcController* dialog) const
+ {
+ wxUIActionSimulator ui;
+
+ // Go to the first page: as the dialog remembers its last opened
+ // page, ensure that we are always on the one we need.
+ ui.Char(WXK_HOME);
+ wxYield();
+
+ // It is difficult to focus the text entry that we're interested
+ // directly from keyboard, so cheat a little and focus it
+ // programmatically.
+ wxWindow* const comments = wxWindow::FindWindowByName
+ ("Comments"
+ ,dialog
+ );
+ LMI_ASSERT(comments);
+
+ comments->SetFocus();
+ wxYield();
+
+ ui.Text("idiosyncrasyZ");
+ wxYield();
+ }
+ };
+
+ // Create a new illustration with the special comment.
+
+ // Double parentheses circumvent the most vexing parse.
+ wx_test_new_illustration ill((enter_comment_in_illustration_dialog()));
+ ill.close_discard_changes();
+
+ // And check that this resulted in the creation of the expected file.
+ unnamed_trace.assert_exists();
+
+ // Open an existing illustration already containing the same comment.
+ wxUIActionSimulator ui;
+
+ output_file_existence_checker
+ existing_trace("MonthlyTrace.monthly_trace" + ext);
+
+ wxFileName fn(configurable_settings::instance().default_input_filename());
+ fn.SetFullName("MonthlyTrace.ill");
+
+ ui.Char('o', wxMOD_CONTROL); // "File|Open"
+ wxTEST_DIALOG
+ (wxYield()
+ ,wxExpectModal<wxFileDialog>(fn.GetFullPath())
+ ,wxExpectModal<wxMessageDialog>(wxID_OK) // Ignore warning.
+ ,wxExpectDismissableModal<MvcController>(wxID_OK) // Accept defaults.
+ );
+
+ ui.Char('l', wxMOD_CONTROL); // "File|Close"
+ wxTEST_DIALOG(wxYield(), wxExpectModal<wxMessageDialog>(wxNO));
+
+ existing_trace.assert_exists();
+}
+
+LMI_WX_TEST_CASE(validate_output_mec)
+{
+ std::string const&
+ ext = configurable_settings::instance().spreadsheet_file_extension();
+
+ // Test creation of the output file when opening a new MEC testing
document.
+ output_file_existence_checker unnamed_output("unnamed.mec" + ext);
+
+ wxUIActionSimulator ui;
+ ui.Char('n', wxMOD_CONTROL); // "File|New"
+ ui.Char('m'); // "MEC testing"
+
+ wxTEST_DIALOG
+ (wxYield()
+ ,wxExpectDismissableModal<MvcController>(wxID_OK)
+ );
+
+ ui.Char('l', wxMOD_CONTROL); // "File|Close"
+ wxYield();
+
+ unnamed_output.assert_exists();
+
+ // And when opening an existing one.
+ output_file_existence_checker existing_output("MecTesting.mec" + ext);
+
+ wxFileName fn(configurable_settings::instance().default_input_filename());
+ fn.SetFullName("MecTesting.mec");
+
+ ui.Char('o', wxMOD_CONTROL); // "File|Open"
+ wxTEST_DIALOG
+ (wxYield()
+ ,wxExpectModal<wxFileDialog>(fn.GetFullPath())
+ ,wxExpectDismissableModal<MvcController>(wxID_OK) // Accept defaults.
+ );
+
+ ui.Char('l', wxMOD_CONTROL); // "File|Close"
+ wxYield();
+
+ existing_output.assert_exists();
+}
Property changes on: lmi/trunk/wx_test_validate_output.cpp
___________________________________________________________________
Added: svn:keywords
+ Id
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [lmi-commits] [5995] Augment automated GUI test,
Greg Chicares <=