Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unit test that a class is non copyable, and other compile-time properties

Is there a way to test compile-time errors, but without actually generating the error? For example, if I create a class which is non-copyable, I'd like to test the fact that trying to copy it will generate a compiler error, but I'd still like to execute the other runtime tests.

struct Foo {
    int value_;
    Foo(int value) : value_(value) {}
  private:
    Foo(const Foo&);
    const Foo& operator=(const Foo&);
};

int main()
{
    Foo f(12);
    assert(f.value_ == 12);
    assert(IS_COMPILER_ERROR(Foo copy(f);));
} // Would like this to compile and run fine.

I guess this can't be done as simply as that, but is there an idiomatic way to do this, or should I roll my own solution (maybe using scripts compiling separate tests files and testing the results?)?

N.B.: I took non-copyable only to illustrate my point, so I'm not interested in answers about using boost::noncopyable and such.

like image 260
Luc Touraille Avatar asked Mar 03 '09 10:03

Luc Touraille


1 Answers

You can do it using make. Each test will be a code snippet. Here's a working example with 2 tests for VC++. (I've used 2 batch files for pass test and fail test). I'm using GNU make here.

Makefile:


FAILTEST = .\failtest.bat
PASSTEST = .\passtest.bat

tests: must_fail_but_passes \
    must_pass_but_fails

must_fail_but_passes:
    @$(FAILTEST) [email protected]

must_pass_but_fails:
    @$(PASSTEST) [email protected]

must_pass_but_fails.cpp


struct Foo {
    int value_;
    Foo(void) : value_(0) {}
  private:
    Foo(const Foo&);
    const Foo& operator=(const Foo&);
};

int main() { Foo f(12); return 0; }

must_fail_but_passes.cpp


struct Foo {
    int value_;
    Foo(int value) : value_(value) {}
  private:
    Foo(const Foo&);
    const Foo& operator=(const Foo&);
};

int main() { Foo f(12); return 0; }

passtest.bat


@echo off
cl /nologo %1 >NUL
if %errorlevel% == 0 goto pass
@echo %1 FAILED
:pass

failtest.bat


@echo off
cl /nologo %1 >NUL
if not %errorlevel% == 0 goto pass
@echo %1 FAILED
:pass

Note that cl.exe (i.e. Visual Studio compiler) need to be in your path for this to "just work"

Have fun!

P.S. I doubt that this would make me famous though :-)

like image 126
Dushara Avatar answered Nov 15 '22 19:11

Dushara