Skip to content

Instantly share code, notes, and snippets.

@tomthorogood
Created October 9, 2012 20:45
Show Gist options
  • Select an option

  • Save tomthorogood/3861294 to your computer and use it in GitHub Desktop.

Select an option

Save tomthorogood/3861294 to your computer and use it in GitHub Desktop.
Sample Mogu Test
/* The following is a demonstration of creating a test suite in the Mogu framework. There are some utility functions that allow you to hand-tool Mogu widgets for testing.
The following test will demonstrate checking the parsed string "|WidgetName| $value$", valid Mogu syntax in the Borel distribution. Having this string in your database should be parsed to the current text value of the widget registered as "WidgetName".
For instance, if you had the following:
```python
widgets["testwidget"] = \
{
type : text,
content : "Hello, World!",
name: "WidgetName"
}
```
The following assumption would be true:
`"Hello, World!" = "|WidgetName| $value$"`
In order to test this assumption, we would first have to create a Test implementation. However, before we do that, let's create the actual evaluation we need to run. This will be a function that calls the bare minimum number of methods. The evaluation must take in a va_list* as its only argument, and must return a TestValue:
*/
TestValue namedStateTest(va_list* args)
{
/* First, we have to extract the minimum data. In this case, it will be
* the string to be parsed and the widget to be parsed against.
*/
std::string str_to_be_parsed = va_arg(args, const char*); //va_arg requires a const char*, not a string
Goo::Moldable* widget = va_arg(args, Goo::Moldable*); //Only the pointer to a C++ object can be converted this way
Nodes::NodeValue v; //Will hold the results of the parsing.
Parsers::NodeValueParser(
str_to_be_parsed //As its first arg, the parser requires the string it needs to be parsed
, &v //It also requires a container to place the results into
, widget //Because we're testing the widget state, we need to give the parser the widget itself
);
/*The constructor of the parser handles everything. Now, we just need to get our results and send them back. */
TestValue result(v.getString() /* The 'value' state will always be a string */
return result;
}
/* Now that we have our evaluation, and we know what we need to pass into it, we can create our Test class. This class could
be used for ANY evaluation that expects a string as a result, and accepts a string and a widget pointer as its arguments. */
#include <TurnLeft/Tests/TestSuite.h>
#include <tests/WtTestSetup.h>
class WidgetValueTest : public Test
{
WTestApp* app;
Goo::Moldable* testwidget;
std::string& parseablevalue;
public:
WidgetValueTest(
Goo::MoldableTemplate* tpl // The hand-tooled template that will create the widget
, std::string& _value // The string that will be parsed against the widget
, std::string tname // The name of your test
, TestValue* expected // The expected result
, Evaluation* evaluation // A function pointer to the actual evaluation being run
, ResultType::type r_type // The type of result you expect (c_str,c_int,c_flt)
)
: Test (tname, r_type, expected, evaluation), parseablevalue(_value)
{
app = createWtTest(); //from WtTestSetup.h
testwidget = addTextWidget(*app, tpl); // Adds a text widget into the root() container of `app`
}
~WidgetValueTest() { delete app;}
virtual bool run()
{
__result = *__evaluation->run(
2 /*number of arguments you're passing*/
, parseablevalue.c_str() /*You must pass a const char* instead of a string, because of the way va_arg works. */
, testwidget) /* The pointer to the widget you've just added. */
.getResult();
return compareResults();
}
};
/* Now, all that's left is to tie everything together. */.
std::string testThatWidget()
{
TestSuite suite("NodeValueParser Suite");
/* Let's set up our test values */
std::string __hello = "Hello, World!";
std::string __hello_name = "HelloWidget";
std::string __hello_r = "|HelloWidget| $value$";
TestValue expected_result(__hello);
Evaluation test_evaluation(&namedStateTest); //Give the evaluation a pointer to our small test function
/* Now we need to do some of Mogu's work for it, and set all the variables we need in our widget template.
* This is functionally equivalent to setting it up in the database per the above example, but will not
* interfere with anything already in your database
*/
Goo::MoldableTemplate* tpl = new Goo::MoldableTemplate(); //This has to be a pointer for our purposes, as Mogu will delete it when it's finished with it.
tpl->content = __hello; /* content : "Hello, World!" */
tpl->type = Enums::WidgetTypes::text /* type : "{text}" */
tpl->name = __hello_name; /* name : "HelloWidget" */
tpl->flags |= Enums::WidgetTypes::is_named; /* Let Mogu know it needs to grab the widget's name. */
/* Now, we need to create our test object */
WidgetValueTest t1(
tpl
, __hello_r
, "Enter a descriptive test name here"
, &expected_result
, &test_evaluation
, ResultType::t_str
);
suite.add_test(&t1);
suite.run();
return suite.report();
}
/* Then, calling the testThatWidget() function would return a nice output showing the name of the test, expected value, actual value, and the pass rates of all tests in the suite (there is only one test in the suite we just craeted). We could easily add more tests with different values, edge cases, etc. to the above suite, and know that Mogu is going to be able to handle our new widget setup.
Happy hacking!
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment