API
 
Loading...
Searching...
No Matches
stdMotionStage_test.cpp
Go to the documentation of this file.
1/** \file stdMotionStage_test.cpp
2 * \brief Catch2 tests for the stdMotionStage helper.
3 * \author Jared R. Males (jaredmales@gmail.com)
4 *
5 * \ingroup testing
6 */
7
8#include "../../../../tests/testXWC.hpp"
9
10#include "../../MagAOXApp.hpp"
11#include "../stdMotionStage.hpp"
12
13using namespace MagAOX::app;
14
15namespace libXWCTest
16{
17namespace appTest
18{
19namespace devTest
20{
21
22/** \defgroup stdMotionStage_tests libXWC::app::dev::stdMotionStage Unit Tests
23 * \ingroup app_dev_unit_tests
24 */
25
26/// Test harness for exercising stdMotionStage preset-name callbacks without the INDI validation short-circuit.
27/** \ingroup stdMotionStage_tests
28 */
29class stdMotionStageHarness : public MagAOXApp<false>, public dev::stdMotionStage<stdMotionStageHarness>
30{
32
33 protected:
34 float m_lastMoveTarget{ -1.0f }; ///< Last target passed to moveTo by the helper.
35
36 int m_moveCalls{ 0 }; ///< Number of motion requests issued by the helper.
37
38 static std::string s_lastLogMessage; ///< Most recent text log message captured from stdMotionStage.
39
40 static logPrioT s_lastLogLevel; ///< Most recent log priority captured from stdMotionStage.
41
42 static int s_logCount; ///< Number of captured stdMotionStage log messages.
43
44 public:
45 /// Construct a stdMotionStage test harness with a presetName callback property.
47
48 /// Destroy the stdMotionStage test harness.
50
51 /// Reset the captured stdMotionStage logging state shared across harness instances.
52 static void resetLogState();
53
54 /// Configure the preset-name list and notation used by stdMotionStage.
55 void
56 configurePresets( const std::vector<std::string> &presetNames /**< [in] configured preset names */,
57 const std::string &presetNotation /**< [in] singular preset notation such as preset or filter */
58 );
59
60 /// Apply a presetName request property to the stdMotionStage callback under test.
62 const std::vector<std::pair<std::string, pcf::IndiElement::SwitchStateType>> &elements /**< [in] requested
63 switch
64 elements and
65 states */
66 );
67
68 /// Get the number of move requests accepted by stdMotionStage.
69 int moveCalls() const;
70
71 /// Get the last move target accepted by stdMotionStage.
72 float lastMoveTarget() const;
73
74 /// Get the most recent stdMotionStage text log message captured by the harness.
75 static const std::string &lastLogMessage();
76
77 /// Get the most recent stdMotionStage log priority captured by the harness.
79
80 /// Get the number of stdMotionStage log messages captured by the harness.
81 static int logCount();
82
83 /// Capture stdMotionStage log messages instead of sending them to the normal logger.
84 template <typename logT, int retval = 0>
85 static int log( const typename logT::messageT &msg /**< [in] the logged message */,
86 logPrioT level = logPrio::LOG_DEFAULT /**< [in] the logged priority */
87 );
88
89 /// No-op startup implementation required by MagAOXApp for testing.
90 int appStartup() override;
91
92 /// No-op logic implementation required by MagAOXApp for testing.
93 int appLogic() override;
94
95 /// No-op shutdown implementation required by MagAOXApp for testing.
97
98 /// No-op stop implementation required by stdMotionStage for testing.
99 int stop();
100
101 /// No-op homing implementation required by stdMotionStage for testing.
102 int startHoming();
103
104 /// Return a fixed preset number for testing paths that query the current preset.
105 float presetNumber();
106
107 /// Record a requested move target when stdMotionStage accepts a motion request.
108 int moveTo( float target /**< [in] the accepted move target */ );
109};
110
112
113logPrioT stdMotionStageHarness::s_lastLogLevel = logPrio::LOG_DEFAULT;
114
116
118{
119 m_configName = "stest";
120
121 m_indiP_presetName = pcf::IndiProperty( pcf::IndiProperty::Switch );
122 m_indiP_presetName.setDevice( m_configName );
123 m_indiP_presetName.setName( "presetName" );
124
126}
127
129
136
137void stdMotionStageHarness::configurePresets( const std::vector<std::string> &presetNames,
138 const std::string &presetNotation )
139{
142}
143
145 const std::vector<std::pair<std::string, pcf::IndiElement::SwitchStateType>> &elements )
146{
147 pcf::IndiProperty ip( pcf::IndiProperty::Switch );
148 ip.setDevice( m_configName );
149 ip.setName( "presetName" );
150
151 for( const auto &element : elements )
152 {
153 ip.add( pcf::IndiElement( element.first ) );
154 ip[element.first].setSwitchState( element.second );
155 }
156
158}
159
161{
162 return m_moveCalls;
163}
164
166{
167 return m_lastMoveTarget;
168}
169
171{
172 return s_lastLogMessage;
173}
174
179
181{
182 return s_logCount;
183}
184
185template <typename logT, int retval>
186int stdMotionStageHarness::log( const typename logT::messageT &msg, logPrioT level )
187{
189 logT::msgString( const_cast<uint8_t *>( msg.builder.GetBufferPointer() ), msg.builder.GetSize() );
191 ++s_logCount;
192
193 return retval;
194}
195
197{
198 return 0;
199}
200
202{
203 return 0;
204}
205
207{
208 return 0;
209}
210
212{
213 return 0;
214}
215
217{
218 return 0;
219}
220
222{
223 return 0.0f;
224}
225
227{
229 ++m_moveCalls;
230
231 return 0;
232}
233
234/// Verify stdMotionStage logs and rejects invalid preset-name selections before issuing motion requests.
235/**
236 * \ingroup stdMotionStage_tests
237 */
238TEST_CASE( "stdMotionStage rejects invalid preset-name selections", "[dev::stdMotionStage]" )
239{
240 // clang-format off
241 #ifdef STDMOTIONSTAGE_TEST_DOXYGEN_REF
243 #endif
244 // clang-format on
245
246 SECTION( "quoted preset names are logged and rejected" )
247 {
249
250 app.configurePresets( { "open", "focus" }, "preset" );
252
253 REQUIRE( app.applyPresetNameRequest( { { "\"focus\"", pcf::IndiElement::On } } ) == -1 );
256 REQUIRE( stdMotionStageHarness::lastLogMessage() == "Unknown presetName selected: \"focus\"" );
257 REQUIRE( app.moveCalls() == 0 );
258 REQUIRE( app.lastMoveTarget() == -1.0f );
259 }
260
261 SECTION( "invalid names are rejected even when a valid preset is also selected" )
262 {
264
265 app.configurePresets( { "open", "focus" }, "filter" );
267
269 { { "open", pcf::IndiElement::On }, { "bogus", pcf::IndiElement::On } } ) == -1 );
272 REQUIRE( stdMotionStageHarness::lastLogMessage() == "Unknown filterName selected: bogus" );
273 REQUIRE( app.moveCalls() == 0 );
274 REQUIRE( app.lastMoveTarget() == -1.0f );
275 }
276}
277
278} // namespace devTest
279} // namespace appTest
280} // namespace libXWCTest
The base-class for XWCTk applications.
std::string m_configName
The name of the configuration file (minus .conf).
MagAO-X standard motion stage interface.
std::vector< std::string > m_presetNames
The names of each position on the stage.
std::string m_presetNotation
Notation used to refer to a preset, should be singular, as in "preset" or "filter".
pcf::IndiProperty m_indiP_presetName
The name of the active preset selection.
int newCallBack_m_indiP_presetName(const pcf::IndiProperty &ipRecv)
Callback to process a NEW preset name request.
Test harness for exercising stdMotionStage preset-name callbacks without the INDI validation short-ci...
static int logCount()
Get the number of stdMotionStage log messages captured by the harness.
int stop()
No-op stop implementation required by stdMotionStage for testing.
static std::string s_lastLogMessage
Most recent text log message captured from stdMotionStage.
int appStartup() override
No-op startup implementation required by MagAOXApp for testing.
static void resetLogState()
Reset the captured stdMotionStage logging state shared across harness instances.
stdMotionStageHarness()
Construct a stdMotionStage test harness with a presetName callback property.
void configurePresets(const std::vector< std::string > &presetNames, const std::string &presetNotation)
Configure the preset-name list and notation used by stdMotionStage.
int moveTo(float target)
Record a requested move target when stdMotionStage accepts a motion request.
static logPrioT lastLogLevel()
Get the most recent stdMotionStage log priority captured by the harness.
int startHoming()
No-op homing implementation required by stdMotionStage for testing.
int moveCalls() const
Get the number of move requests accepted by stdMotionStage.
int m_moveCalls
Number of motion requests issued by the helper.
static int log(const typename logT::messageT &msg, logPrioT level=logPrio::LOG_DEFAULT)
Capture stdMotionStage log messages instead of sending them to the normal logger.
static logPrioT s_lastLogLevel
Most recent log priority captured from stdMotionStage.
float m_lastMoveTarget
Last target passed to moveTo by the helper.
int appShutdown() override
No-op shutdown implementation required by MagAOXApp for testing.
float lastMoveTarget() const
Get the last move target accepted by stdMotionStage.
static const std::string & lastLogMessage()
Get the most recent stdMotionStage text log message captured by the harness.
~stdMotionStageHarness() noexcept override
Destroy the stdMotionStage test harness.
float presetNumber()
Return a fixed preset number for testing paths that query the current preset.
static int s_logCount
Number of captured stdMotionStage log messages.
int appLogic() override
No-op logic implementation required by MagAOXApp for testing.
int applyPresetNameRequest(const std::vector< std::pair< std::string, pcf::IndiElement::SwitchStateType > > &elements)
Apply a presetName request property to the stdMotionStage callback under test.
int8_t logPrioT
The type of the log priority code.
Definition logDefs.hpp:21
TEST_CASE("stdMotionStage rejects invalid preset-name selections", "[dev::stdMotionStage]")
Verify stdMotionStage logs and rejects invalid preset-name selections before issuing motion requests.
std::stringstream msg
static constexpr logPrioT LOG_ERROR
An error has occured which the software will attempt to correct.
static constexpr logPrioT LOG_DEFAULT
Used to denote "use the default level for this log type".
Namespace for all libXWC tests.