From 2f171eb2fdaf3ab86f5c34c2bc8d3a64de33e951 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89milie=20Feral?= Date: Wed, 1 Apr 2020 11:32:21 +0200 Subject: [PATCH] [python] Add matplotlib test WIP --- python/Makefile | 2 + python/test/execution_environment.cpp | 45 +++++++++++ python/test/execution_environment.h | 15 ++++ python/test/mandelbrot.cpp | 51 +----------- python/test/matplotlib.cpp | 111 ++++++++++++++++++++++++++ 5 files changed, 175 insertions(+), 49 deletions(-) create mode 100644 python/test/execution_environment.cpp create mode 100644 python/test/execution_environment.h create mode 100644 python/test/matplotlib.cpp diff --git a/python/Makefile b/python/Makefile index cb5d5a015..4c0a92323 100644 --- a/python/Makefile +++ b/python/Makefile @@ -189,5 +189,7 @@ $(eval $(call rule_for, \ $(call object_for,$(python_src)): $(BUILD_DIR)/python/port/genhdr/qstrdefs.generated.h tests_src += $(addprefix python/test/,\ + execution_environment.cpp \ mandelbrot.cpp \ + matplotlib.cpp \ ) diff --git a/python/test/execution_environment.cpp b/python/test/execution_environment.cpp new file mode 100644 index 000000000..313176a10 --- /dev/null +++ b/python/test/execution_environment.cpp @@ -0,0 +1,45 @@ +#include "execution_environment.h" +#include +#include +#include + +char TestExecutionEnvironment::s_pythonHeap[TestExecutionEnvironment::s_pythonHeapSize]; + +void TestExecutionEnvironment::printText(const char * text, size_t length) { + quiz_print(text); +} + +// TODO: this will be obsolete when runCode will take a parameter to choose the input type + +void inlineToBeSingleInput(char * buffer, size_t bufferSize, const char * script) { + static const char * openExec = "exec(\""; + static const char * closeExec = "\")"; + assert(strlen(script) + strlen(openExec) + strlen(closeExec) < bufferSize); + char * bufferChar = buffer; + bufferChar += strlcpy(buffer, openExec, bufferSize); + const char * scriptChar = script; + while (*scriptChar != 0) { + assert(bufferChar - buffer + 2 < bufferSize - 1); + if (*scriptChar == '\n') { + // Turn carriage return in {'\', 'n'} to be processed by exec + *bufferChar++ = '\\'; + *bufferChar++ = 'n'; + } else { + *bufferChar++ = *scriptChar; + } + scriptChar++; + } + bufferChar += strlcpy(bufferChar, closeExec, buffer + bufferSize - bufferChar); + assert(bufferChar - buffer < bufferSize); + *bufferChar = 0; +} + +void assert_script_execution_succeeds(const char * script) { + constexpr size_t bufferSize = 500; + char buffer[bufferSize]; + inlineToBeSingleInput(buffer, bufferSize, script); + MicroPython::init(TestExecutionEnvironment::s_pythonHeap, TestExecutionEnvironment::s_pythonHeap + TestExecutionEnvironment::s_pythonHeapSize); + TestExecutionEnvironment env; + env.runCode(buffer); + MicroPython::deinit(); +} diff --git a/python/test/execution_environment.h b/python/test/execution_environment.h new file mode 100644 index 000000000..361e35338 --- /dev/null +++ b/python/test/execution_environment.h @@ -0,0 +1,15 @@ +#include +#include + +class TestExecutionEnvironment : public MicroPython::ExecutionEnvironment { +public: + void printText(const char * text, size_t length) override; + static constexpr int s_pythonHeapSize = Code::App::k_pythonHeapSize; + static char s_pythonHeap[s_pythonHeapSize]; +}; + + +// TODO: this will be obsolete when runCode will take a parameter to choose the input type +void inlineToBeSingleInput(char * buffer, size_t bufferSize, const char * script); + +void assert_script_execution_succeeds(const char * script); diff --git a/python/test/mandelbrot.cpp b/python/test/mandelbrot.cpp index 99e183634..9bc7f088a 100644 --- a/python/test/mandelbrot.cpp +++ b/python/test/mandelbrot.cpp @@ -1,21 +1,5 @@ #include -#include -#include -#include -#include - - -class TestExecutionEnvironment : public MicroPython::ExecutionEnvironment { -public: - void printText(const char * text, size_t length) override; -}; - -void TestExecutionEnvironment::printText(const char * text, size_t length) { - quiz_print(text); -} - -static constexpr int s_pythonHeapSize = Code::App::k_pythonHeapSize; -static char s_pythonHeap[s_pythonHeapSize]; +#include "execution_environment.h" static const char * s_mandelbrotScript = R"(# def mandelbrot(N_iteration): @@ -33,37 +17,6 @@ mandelbrot(2) print('ok') )"; -// TODO: this will be obsolete when runCode will take a parameter to choose the input type - -void inlineToBeSingleInput(char * buffer, size_t bufferSize, const char * script) { - static const char * openExec = "exec(\""; - static const char * closeExec = "\")"; - assert(strlen(script) + strlen(openExec) + strlen(closeExec) < bufferSize); - char * bufferChar = buffer; - bufferChar += strlcpy(buffer, openExec, bufferSize); - const char * scriptChar = script; - while (*scriptChar != 0) { - assert(bufferChar - buffer + 2 < bufferSize - 1); - if (*scriptChar == '\n') { - // Turn carriage return in {'\', 'n'} to be processed by exec - *bufferChar++ = '\\'; - *bufferChar++ = 'n'; - } else { - *bufferChar++ = *scriptChar; - } - scriptChar++; - } - bufferChar += strlcpy(bufferChar, closeExec, buffer + bufferSize - bufferChar); - assert(bufferChar - buffer < bufferSize); - *bufferChar = 0; -} - QUIZ_CASE(python_mandelbrot) { - constexpr size_t bufferSize = 500; - char buffer[bufferSize]; - inlineToBeSingleInput(buffer, bufferSize, s_mandelbrotScript); - MicroPython::init(s_pythonHeap, s_pythonHeap + s_pythonHeapSize); - TestExecutionEnvironment env; - env.runCode(buffer); - MicroPython::deinit(); + assert_script_execution_succeeds(s_mandelbrotScript); } diff --git a/python/test/matplotlib.cpp b/python/test/matplotlib.cpp new file mode 100644 index 000000000..98e55b5e2 --- /dev/null +++ b/python/test/matplotlib.cpp @@ -0,0 +1,111 @@ +#include +#include "execution_environment.h" + +static const char * s_pyplotArrowScript = R"(# +from matplotlib.pyplot import * +arrow(2,3,4,5) +show() +print('ok') +)"; + +static const char * s_pyplotAxisScript = R"(# +from matplotlib.pyplot import * +axis((2,3,4,5)) +axis([2,3,4,5]) +print(axis()) +scatter(0,1) +show() +print('ok') +)"; + +static const char * s_pyplotAxisErrorScript = R"(# +from matplotlib.pyplot import * +axis(2,3,4,5) +print('fail!') +)"; + +static const char * s_pyplotBarScript = R"(# +from matplotlib.pyplot import * +bar([0,2,3],[10,12,23]) +bar([0,2,3],10) +bar([],[]) +bar([1,2,3],[1,2,3],2,3) +bar([1,2,3],[1,2,3],[1,2,3],[1,2,3]) +show() +print('ok') +)"; + +static const char * s_pyplotBarErrorScript = R"(# +from matplotlib.pyplot import * +bar([1,2,3],[1,2,3,4],[1,2,3],[1,2,3]) +show() +print('fail!') +)"; + +static const char * s_pyplotGridScript = R"(# +from matplotlib.pyplot import * +grid(True) +grid() +show() +print('ok') +)"; + +static const char * s_pyplotHistScript = R"(# +from matplotlib.pyplot import * +hist([2,3,4,5,6]) +hist([2,3,4,5,6],23) +hist([2,3,4,5,6],[0,2,3]) +hist([2,3,4,5,6],[0,2,3, 4,5,6,7]) +show() +print('ok') +)"; + +static const char * s_pyplotPlotScript = R"(# +from matplotlib.pyplot import * +plot([2,3,4,5,6]) +plot([2,3,4,5,6],[3,4,5,6,7]) +show() +print('ok') +)"; + +static const char * s_pyplotPlotErrorScript = R"(# +from matplotlib.pyplot import * +plot([2,3,4,5,6],2) +print('Fail!') +)"; + +static const char * s_pyplotScatterScript = R"(# +from matplotlib.pyplot import * +scatter(2,3) +scatter([2,3,4,5,6],[3,4,5,6,7]) +show() +print('ok') +)"; + +static const char * s_pyplotScatterErrorScript = R"(# +from matplotlib.pyplot import * +scatter([2,3,4,5,6],2) +print('Fail!') +)"; + +static const char * s_pyplotTextScript = R"(# +from matplotlib.pyplot import * +text(2,3, "hello") +show() +print('ok') +)"; + +QUIZ_CASE(python_matplotlib_pyplot) { + assert_script_execution_succeeds(s_pyplotArrowScript); + assert_script_execution_succeeds(s_pyplotAxisScript); + assert_script_execution_succeeds(s_pyplotAxisErrorScript); + assert_script_execution_succeeds(s_pyplotBarScript); + assert_script_execution_succeeds(s_pyplotBarErrorScript); + assert_script_execution_succeeds(s_pyplotGridScript); + assert_script_execution_succeeds(s_pyplotHistScript); + assert_script_execution_succeeds(s_pyplotPlotScript); + assert_script_execution_succeeds(s_pyplotPlotErrorScript); + assert_script_execution_succeeds(s_pyplotScatterScript); + assert_script_execution_succeeds(s_pyplotScatterErrorScript); + assert_script_execution_succeeds(s_pyplotTextScript); +}