1use strict;
2use warnings;
3use Test::More;
4use FindBin;
5
6# this is needed to avoid false passes if was done first without 'info'
7use Inline CPP => config => force_build => 1, clean_after_build => 0,
8  typemaps => "$FindBin::Bin/typemap.09purevt",
9  ;
10
11# Test pure virtual functions (abstract classes).
12use Inline CPP => <<'END';
13
14#ifdef __INLINE_CPP_STANDARD_HEADERS
15#include <string>
16#else
17#include <string.h>
18#endif
19
20#ifdef __INLINE_CPP_NAMESPACE_STD
21using namespace std;
22#endif
23
24class Abstract {
25  public:
26        Abstract() {}
27        virtual char *text() = 0;
28        virtual int greet(char *name) {
29            printf("# Hello, %s.\n", name);
30            return 17;
31        }
32        virtual string greet2() {
33            string retval = "yo";
34            return retval;
35        }
36};
37
38class Impl : public Abstract {
39  public:
40    Impl() {}
41    ~Impl() {}
42    virtual char *text() { return "Hello from Impl!"; }
43};
44END
45
46my $o = new_ok( 'Impl' );
47is(
48    $o->text, 'Hello from Impl!',
49    "Resolved virtual member function from self."
50);
51
52is(
53    $o->greet('Neil'), 17,
54    "Inherited member function from parent."
55);
56
57is(
58    $o->greet2, "yo",
59    "Inherited string member function from parent."
60);
61
62my $p;
63eval{ $p = Abstract->new(); };
64if( $@ ) {
65    like(
66        $@,
67        qr/^Can't locate object method "new" via package "([^:]+::)*Abstract"/,
68        "Classes with pure virtual functions cannot be instantiated."
69    );
70} else {
71    not_ok(
72        "Abstract class with pure virtual function should not instantiate."
73    );
74}
75
76
77done_testing();
78