Commit 59dea67b by ofats Committed by CJ Johnson

Googletest export

Remove scripts for code generating together with related files. PiperOrigin-RevId: 352805926
parent 997c36c1
......@@ -128,15 +128,3 @@ To run the tests, do
make test
All tests should pass.
### Regenerating Source Files
Some of Google Test's source files are generated from templates (not in the C++
sense) using a script. For example, the file
*googlemock/include/gmock/gmock-generated-actions.h.pump* is used to generate
*gmock-generated-actions.h* in the same directory.
You don't need to worry about regenerating the source files unless you need to
modify them. You would then modify the corresponding `.pump` files and run the
'[pump.py](googlemock/scripts/pump.py)' generator script. See the
[Pump Manual](googlemock/docs/pump_manual.md).
<b>P</b>ump is <b>U</b>seful for <b>M</b>eta <b>P</b>rogramming.
[TOC]
# The Problem
Template and macro libraries often need to define many classes, functions, or
macros that vary only (or almost only) in the number of arguments they take.
It's a lot of repetitive, mechanical, and error-prone work.
Our experience is that it's tedious to write custom scripts, which tend to
reflect the structure of the generated code poorly and are often hard to read
and edit. For example, a small change needed in the generated code may require
some non-intuitive, non-trivial changes in the script. This is especially
painful when experimenting with the code.
This script may be useful for generating meta code, for example a series of
macros of FOO1, FOO2, etc. Nevertheless, please make it your last resort
technique by favouring C++ template metaprogramming or variadic macros.
# Our Solution
Pump (for Pump is Useful for Meta Programming, Pretty Useful for Meta
Programming, or Practical Utility for Meta Programming, whichever you prefer) is
a simple meta-programming tool for C++. The idea is that a programmer writes a
`foo.pump` file which contains C++ code plus meta code that manipulates the C++
code. The meta code can handle iterations over a range, nested iterations, local
meta variable definitions, simple arithmetic, and conditional expressions. You
can view it as a small Domain-Specific Language. The meta language is designed
to be non-intrusive (s.t. it won't confuse Emacs' C++ mode, for example) and
concise, making Pump code intuitive and easy to maintain.
## Highlights
* The implementation is in a single Python script and thus ultra portable: no
build or installation is needed and it works cross platforms.
* Pump tries to be smart with respect to
[Google's style guide](https://github.com/google/styleguide): it breaks long
lines (easy to have when they are generated) at acceptable places to fit
within 80 columns and indent the continuation lines correctly.
* The format is human-readable and more concise than XML.
* The format works relatively well with Emacs' C++ mode.
## Examples
The following Pump code (where meta keywords start with `$`, `[[` and `]]` are
meta brackets, and `$$` starts a meta comment that ends with the line):
```
$var n = 3 $$ Defines a meta variable n.
$range i 0..n $$ Declares the range of meta iterator i (inclusive).
$for i [[
$$ Meta loop.
// Foo$i does blah for $i-ary predicates.
$range j 1..i
template <size_t N $for j [[, typename A$j]]>
class Foo$i {
$if i == 0 [[
blah a;
]] $elif i <= 2 [[
blah b;
]] $else [[
blah c;
]]
};
]]
```
will be translated by the Pump compiler to:
```cpp
// Foo0 does blah for 0-ary predicates.
template <size_t N>
class Foo0 {
blah a;
};
// Foo1 does blah for 1-ary predicates.
template <size_t N, typename A1>
class Foo1 {
blah b;
};
// Foo2 does blah for 2-ary predicates.
template <size_t N, typename A1, typename A2>
class Foo2 {
blah b;
};
// Foo3 does blah for 3-ary predicates.
template <size_t N, typename A1, typename A2, typename A3>
class Foo3 {
blah c;
};
```
In another example,
```
$range i 1..n
Func($for i + [[a$i]]);
$$ The text between i and [[ is the separator between iterations.
```
will generate one of the following lines (without the comments), depending on
the value of `n`:
```cpp
Func(); // If n is 0.
Func(a1); // If n is 1.
Func(a1 + a2); // If n is 2.
Func(a1 + a2 + a3); // If n is 3.
// And so on...
```
## Constructs
We support the following meta programming constructs:
| `$var id = exp` | Defines a named constant value. `$id` is |
: : valid until the end of the current meta :
: : lexical block. :
| :------------------------------- | :--------------------------------------- |
| `$range id exp..exp` | Sets the range of an iteration variable, |
: : which can be reused in multiple loops :
: : later. :
| `$for id sep [[ code ]]` | Iteration. The range of `id` must have |
: : been defined earlier. `$id` is valid in :
: : `code`. :
| `$($)` | Generates a single `$` character. |
| `$id` | Value of the named constant or iteration |
: : variable. :
| `$(exp)` | Value of the expression. |
| `$if exp [[ code ]] else_branch` | Conditional. |
| `[[ code ]]` | Meta lexical block. |
| `cpp_code` | Raw C++ code. |
| `$$ comment` | Meta comment. |
**Note:** To give the user some freedom in formatting the Pump source code, Pump
ignores a new-line character if it's right after `$for foo` or next to `[[` or
`]]`. Without this rule you'll often be forced to write very long lines to get
the desired output. Therefore sometimes you may need to insert an extra new-line
in such places for a new-line to show up in your output.
## Grammar
```ebnf
code ::= atomic_code*
atomic_code ::= $var id = exp
| $var id = [[ code ]]
| $range id exp..exp
| $for id sep [[ code ]]
| $($)
| $id
| $(exp)
| $if exp [[ code ]] else_branch
| [[ code ]]
| cpp_code
sep ::= cpp_code | empty_string
else_branch ::= $else [[ code ]]
| $elif exp [[ code ]] else_branch
| empty_string
exp ::= simple_expression_in_Python_syntax
```
## Code
You can find the source code of Pump in
[googlemock/scripts/pump.py](../googlemock/scripts/pump.py). It is still very
unpolished and lacks automated tests, although it has been successfully used
many times. If you find a chance to use it in your project, please let us know
what you think! We also welcome help on improving Pump.
## Real Examples
You can find real-world applications of Pump in
[Google Test](https://github.com/google/googletest/tree/master/googletest) and
[Google Mock](https://github.com/google/googletest/tree/master/googlemock). The
source file `foo.h.pump` generates `foo.h`.
## Tips
* If a meta variable is followed by a letter or digit, you can separate them
using `[[]]`, which inserts an empty string. For example `Foo$j[[]]Helper`
generate `Foo1Helper` when `j` is 1.
* To avoid extra-long Pump source lines, you can break a line anywhere you
want by inserting `[[]]` followed by a new line. Since any new-line
character next to `[[` or `]]` is ignored, the generated code won't contain
this new line.
......@@ -153,7 +153,6 @@ if (gmock_build_tests)
cxx_test(gmock-cardinalities_test gmock_main)
cxx_test(gmock_ex_test gmock_main)
cxx_test(gmock-function-mocker_test gmock_main)
cxx_test(gmock-generated-actions_test gmock_main)
cxx_test(gmock-internal-utils_test gmock_main)
cxx_test(gmock-matchers_test gmock_main)
cxx_test(gmock-more-actions_test gmock_main)
......
// This file was GENERATED by command:
// pump.py gmock-generated-actions.h.pump
// DO NOT EDIT BY HAND!!!
// Copyright 2007, Google Inc.
// All rights reserved.
//
......@@ -38,8 +34,8 @@
// GOOGLETEST_CM0002 DO NOT DELETE
#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_ACTIONS_H_
#define GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_ACTIONS_H_
#ifndef GMOCK_INCLUDE_GMOCK_GMOCK_MORE_ACTIONS_H_
#define GMOCK_INCLUDE_GMOCK_GMOCK_MORE_ACTIONS_H_
#include <memory>
#include <utility>
......@@ -574,4 +570,4 @@ InvokeArgument(Params&&... params) {
} // namespace testing
#endif // GMOCK_INCLUDE_GMOCK_GMOCK_GENERATED_ACTIONS_H_
#endif // GMOCK_INCLUDE_GMOCK_GMOCK_MORE_ACTIONS_H_
......@@ -59,8 +59,8 @@
#include "gmock/gmock-actions.h"
#include "gmock/gmock-cardinalities.h"
#include "gmock/gmock-function-mocker.h"
#include "gmock/gmock-generated-actions.h"
#include "gmock/gmock-matchers.h"
#include "gmock/gmock-more-actions.h"
#include "gmock/gmock-more-matchers.h"
#include "gmock/gmock-nice-strict.h"
#include "gmock/internal/gmock-internal-utils.h"
......
// Copyright 2008, Google Inc.
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// Google Mock - a framework for writing C++ mock classes.
//
// This file contains negative compilation tests for script-generated
// Google Mock actions.
#include "gmock/gmock.h"
using testing::Action;
using testing::Invoke;
using testing::WithArgs;
int Nullary() { return 0; }
int Binary(int a, int b) { return a + b; }
#if defined(TEST_NULLARY_WITH_ARGS)
// Tests that WithArgs(action) doesn't compile.
void Test() {
Action<int(int)> a = WithArgs(Invoke(Nullary));
}
#elif defined(TEST_TOO_FEW_ARGS_FOR_WITH_ARGS)
// Tests that you cannot pass too few arguments to the inner action in
// WithArgs().
void Test() {
Action<int(int, int, int)> a = WithArgs<1>(Invoke(Binary));
}
#elif defined(TEST_TOO_MANY_ARGS_FOR_WITH_ARGS)
// Tests that you cannot pass too many arguments to the inner action in
// WithArgs().
void Test() {
Action<int(int, int, int)> a = WithArgs<1, 2, 0>(Invoke(Binary));
}
#elif defined(TEST_INCOMPATIBLE_ARG_TYPES_FOR_WITH_ARGS)
// Tests that you cannot pass arguments of incompatible types to the
// inner action in WithArgs().
void Test() {
Action<int(int, const char*, int)> a = WithArgs<1, 2>(Invoke(Binary));
}
#elif defined(TEST_WRONG_ARG_TYPE_IN_ACTION_MACRO)
// Tests using an ACTION definition in a mock function whose argument
// types are incompatible.
ACTION(WrongArgType) { return 10/arg0; }
void Test() {
Action<int(const char*)> a = WrongArgType();
}
#elif defined(TEST_WRONG_RETURN_TYPE_IN_ACTION_MACRO)
// Tests using an ACTION definition in a mock function whose return
// types is incompatible.
ACTION(WrongReturnType) { return 10; }
void Test() {
Action<const char*()> a = WrongReturnType();
}
#elif defined(TEST_EXCESSIVE_ARG_IN_ACTION_MACRO)
// Tests using an ACTION definition in a mock function that doesn't
// provide enough arguments.
ACTION(UseExcessiveArg) { return arg0 + arg1; }
void Test() {
Action<int(int)> a = UseExcessiveArg();
}
#elif defined(TEST_ACTION_MACRO_IN_CLASS)
// Tests using ACTION in a class scope.
class Foo {
public:
// This won't compile as C++ doesn't allow defining a method of a
// nested class out-of-line in the enclosing class.
ACTION(Bar) { return arg0; }
};
#elif defined(TEST_ACTION_MACRO_IN_FUNCTION)
// Tests using ACTION in a function body.
void Test() {
// This won't compile as C++ doesn't allow member templates in local
// classes. We may want to revisit this when C++0x is widely
// implemented.
ACTION(Bar) { return arg0; }
}
#elif defined(TEST_SET_ARG_REFEREE_MUST_BE_USED_WITH_REFERENCE)
// Verifies that using SetArgReferee<k>(...) where the k-th argument
// of the mock function is not a reference generates a compiler error.
void Test() {
Action<void(bool, int)> a = testing::SetArgReferee<1>(5);
}
#elif defined(TEST_DELETE_ARG_MUST_BE_USED_WITH_POINTER)
// Verifies that using DeleteArg<k>(...) where the k-th argument of the mock
// function is not a pointer generates a compiler error.
void Test() {
Action<void(int)> a = testing::DeleteArg<0>(); // NOLINT
}
#elif defined(TEST_CANNOT_OVERLOAD_ACTION_TEMPLATE_ON_TEMPLATE_PARAM_NUMBER)
// Tests that ACTION_TEMPLATE cannot be overloaded on the number of
// template parameters alone.
ACTION_TEMPLATE(OverloadedAction,
HAS_1_TEMPLATE_PARAMS(typename, T),
AND_1_VALUE_PARAMS(p)) {}
ACTION_TEMPLATE(OverloadedAction,
HAS_2_TEMPLATE_PARAMS(typename, T1, typename, T2),
AND_1_VALUE_PARAMS(p)) {}
#elif defined(TEST_CANNOT_OVERLOAD_ACTION_AND_ACTION_TEMPLATE_W_SAME_VALUE_PS)
// Tests that ACTION_TEMPLATE and ACTION_P cannot be overloaded when
// they have the same number of value parameters.
ACTION_P(OverloadedAction, p) {}
ACTION_TEMPLATE(OverloadedAction,
HAS_1_TEMPLATE_PARAMS(typename, T),
AND_1_VALUE_PARAMS(p)) {}
#else
// Sanity check - this should compile.
#endif
......@@ -37,7 +37,6 @@
// below list of actual *_test.cc files might change).
#include "test/gmock-actions_test.cc"
#include "test/gmock-cardinalities_test.cc"
#include "test/gmock-generated-actions_test.cc"
#include "test/gmock-internal-utils_test.cc"
#include "test/gmock-matchers_test.cc"
#include "test/gmock-more-actions_test.cc"
......
#!/usr/bin/env python
#
# Copyright 2008, Google Inc.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following disclaimer
# in the documentation and/or other materials provided with the
# distribution.
# * Neither the name of Google Inc. nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
# Google Mock - a framework for writing C++ mock classes.
#
# This file drives the negative compilation tests for script-generated
# Google Mock actions.
"""Driver for the NC tests for script-generated Google Mock actions."""
import os
import sys
IS_LINUX = os.name == "posix" and os.uname()[0] == "Linux"
if not IS_LINUX:
sys.stderr.write(
"WARNING: Negative compilation tests are not supported on this platform")
sys.exit(0)
# Suppresses the 'Import not at the top of the file' lint complaint.
# pylint: disable-msg=C6204
from google3.testing.pybase import fake_target_util
from google3.testing.pybase import googletest
# pylint: enable-msg=C6204
class GMockGeneratedActionTest(googletest.TestCase):
"""Negative compilation tests for generated Google Mock actions."""
# The class body is intentionally empty. The actual test*() methods
# will be defined at run time by a call to
# DefineNegativeCompilationTests() later.
pass
# Defines a list of test specs, where each element is a tuple
# (test name, list of regexes for matching the compiler errors).
TEST_SPECS = [
("NULLARY_WITH_ARGS", [
r"no matching function for call to 'WithArgs",
]),
("TOO_FEW_ARGS_FOR_WITH_ARGS", [
r"no known conversion",
]),
("TOO_MANY_ARGS_FOR_WITH_ARGS", [
r"no known conversion",
]),
("INCOMPATIBLE_ARG_TYPES_FOR_WITH_ARGS", [
r"no known conversion",
]),
("WRONG_ARG_TYPE_IN_ACTION_MACRO", [
r"invalid operands",
]),
(
"WRONG_RETURN_TYPE_IN_ACTION_MACRO",
[
r"invalid conversion", # GCC
r"cannot initialize return object", # Clang
]),
(
"EXCESSIVE_ARG_IN_ACTION_MACRO",
[
r"no match for 'operator\+'", # GCC
r"invalid operands to binary expression", # Clang
]),
(
"ACTION_MACRO_IN_CLASS",
[
r"cannot define member function.*Bar.*within.*Foo", # GCC
r"ACTION\(Bar\)", # Clang
]),
(
"ACTION_MACRO_IN_FUNCTION",
[
r"invalid declaration of member template in local class", # GCC
r"templates cannot be declared inside of a local class", # Clang
]),
("SET_ARG_REFEREE_MUST_BE_USED_WITH_REFERENCE",
[r"Argument must be a reference type"]),
(
"DELETE_ARG_MUST_BE_USED_WITH_POINTER",
[
r"argument given to 'delete', expected pointer", # GCC
r"cannot delete expression of type", # Clang
]),
(
"CANNOT_OVERLOAD_ACTION_TEMPLATE_ON_TEMPLATE_PARAM_NUMBER",
[
r"wrong number of template arguments", # GCC
r"too many template parameters", # Clang
]),
(
"CANNOT_OVERLOAD_ACTION_AND_ACTION_TEMPLATE_W_SAME_VALUE_PS",
[
r"wrong number of template arguments", # GCC
r"too many template parameters", # Clang
]),
("SANITY", None),
]
# Define a test method in GMockGeneratedActionTest for each element in
# TEST_SPECS.
fake_target_util.DefineNegativeCompilationTests(
GMockGeneratedActionTest,
"google3/third_party/googletest/googlemock/test/gmock-generated-actions_nc", # fake target
"gmock-generated-actions_nc.o", # object file
TEST_SPECS)
if __name__ == "__main__":
googletest.main()
#!/usr/bin/env python
#
# Copyright 2010, Google Inc.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following disclaimer
# in the documentation and/or other materials provided with the
# distribution.
# * Neither the name of Google Inc. nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
"""Tests for the Pump meta-programming tool."""
from google3.testing.pybase import googletest
import google3.third_party.googletest.googlemock.scripts.pump
pump = google3.third_party.googletest.googlemock.scripts.pump
Convert = pump.ConvertFromPumpSource
StripMetaComments = pump.StripMetaComments
class PumpTest(googletest.TestCase):
def testConvertsEmptyToEmpty(self):
self.assertEquals('', Convert('').strip())
def testConvertsPlainCodeToSame(self):
self.assertEquals('#include <stdio.h>\n',
Convert('#include <stdio.h>\n'))
def testConvertsLongIWYUPragmaToSame(self):
long_line = '// IWYU pragma: private, include "' + (80*'a') + '.h"\n'
self.assertEquals(long_line, Convert(long_line))
def testConvertsIWYUPragmaWithLeadingSpaceToSame(self):
long_line = ' // IWYU pragma: private, include "' + (80*'a') + '.h"\n'
self.assertEquals(long_line, Convert(long_line))
def testConvertsIWYUPragmaWithSlashStarLeaderToSame(self):
long_line = '/* IWYU pragma: private, include "' + (80*'a') + '.h"\n'
self.assertEquals(long_line, Convert(long_line))
def testConvertsIWYUPragmaWithSlashStarAndSpacesToSame(self):
long_line = ' /* IWYU pragma: private, include "' + (80*'a') + '.h"\n'
self.assertEquals(long_line, Convert(long_line))
def testIgnoresMetaComment(self):
self.assertEquals('',
Convert('$$ This is a Pump meta comment.\n').strip())
def testSimpleVarDeclarationWorks(self):
self.assertEquals('3\n',
Convert('$var m = 3\n'
'$m\n'))
def testVarDeclarationCanReferenceEarlierVar(self):
self.assertEquals('43 != 3;\n',
Convert('$var a = 42\n'
'$var b = a + 1\n'
'$var c = (b - a)*3\n'
'$b != $c;\n'))
def testSimpleLoopWorks(self):
self.assertEquals('1, 2, 3, 4, 5\n',
Convert('$var n = 5\n'
'$range i 1..n\n'
'$for i, [[$i]]\n'))
def testSimpleLoopWithCommentWorks(self):
self.assertEquals('1, 2, 3, 4, 5\n',
Convert('$var n = 5 $$ This is comment 1.\n'
'$range i 1..n $$ This is comment 2.\n'
'$for i, [[$i]]\n'))
def testNonTrivialRangeExpressionsWork(self):
self.assertEquals('1, 2, 3, 4\n',
Convert('$var n = 5\n'
'$range i (n/n)..(n - 1)\n'
'$for i, [[$i]]\n'))
def testLoopWithoutSeparatorWorks(self):
self.assertEquals('a + 1 + 2 + 3;\n',
Convert('$range i 1..3\n'
'a$for i [[ + $i]];\n'))
def testCanGenerateDollarSign(self):
self.assertEquals('$\n', Convert('$($)\n'))
def testCanIterpolateExpressions(self):
self.assertEquals('a[2] = 3;\n',
Convert('$var i = 1\n'
'a[$(i + 1)] = $(i*4 - 1);\n'))
def testConditionalWithoutElseBranchWorks(self):
self.assertEquals('true\n',
Convert('$var n = 5\n'
'$if n > 0 [[true]]\n'))
def testConditionalWithElseBranchWorks(self):
self.assertEquals('true -- really false\n',
Convert('$var n = 5\n'
'$if n > 0 [[true]]\n'
'$else [[false]] -- \n'
'$if n > 10 [[really true]]\n'
'$else [[really false]]\n'))
def testConditionalWithCascadingElseBranchWorks(self):
self.assertEquals('a\n',
Convert('$var n = 5\n'
'$if n > 0 [[a]]\n'
'$elif n > 10 [[b]]\n'
'$else [[c]]\n'))
self.assertEquals('b\n',
Convert('$var n = 5\n'
'$if n > 10 [[a]]\n'
'$elif n > 0 [[b]]\n'
'$else [[c]]\n'))
self.assertEquals('c\n',
Convert('$var n = 5\n'
'$if n > 10 [[a]]\n'
'$elif n > 8 [[b]]\n'
'$else [[c]]\n'))
def testNestedLexicalBlocksWork(self):
self.assertEquals('a = 5;\n',
Convert('$var n = 5\n'
'a = [[$if n > 0 [[$n]]]];\n'))
class StripMetaCommentsTest(googletest.TestCase):
def testReturnsSameStringIfItContainsNoComment(self):
self.assertEquals('', StripMetaComments(''))
self.assertEquals(' blah ', StripMetaComments(' blah '))
self.assertEquals('A single $ is fine.',
StripMetaComments('A single $ is fine.'))
self.assertEquals('multiple\nlines',
StripMetaComments('multiple\nlines'))
def testStripsSimpleComment(self):
self.assertEquals('yes\n', StripMetaComments('yes $$ or no?\n'))
def testStripsSimpleCommentWithMissingNewline(self):
self.assertEquals('yes', StripMetaComments('yes $$ or no?'))
def testStripsPureCommentLinesEntirely(self):
self.assertEquals('yes\n',
StripMetaComments('$$ a pure comment line.\n'
'yes $$ or no?\n'
' $$ another comment line.\n'))
def testStripsCommentsFromMultiLineText(self):
self.assertEquals('multi-\n'
'line\n'
'text is fine.',
StripMetaComments('multi- $$ comment 1\n'
'line\n'
'text is fine. $$ comment 2'))
if __name__ == '__main__':
googletest.main()
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment