File: basic_tests.c

package info (click to toggle)
interface99 1.0.2-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 324 kB
  • sloc: ansic: 951; sh: 48; makefile: 6
file content (121 lines) | stat: -rw-r--r-- 2,927 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
#include <interface99.h>

#include "common.h"
#include "util.h"

#include <assert.h>
#include <stddef.h>
#include <string.h>

// Ensure that forward declarations are generated.
#define TestForwardDecl_IFACE vfunc(void, abc, Foo self, FooVTable vtable)

interface(TestForwardDecl);

// Implementations {

typedef struct {
    char dummy;
} MarkerImpl;

impl(Marker, MarkerImpl);

typedef struct {
    char dummy;
} FooImpl;

#define FooImpl_foo foo1_impl
impl(Foo, FooImpl);

typedef struct {
    char dummy;
} BarImpl1;

#define BarImpl1_foo foo1_impl
#define BarImpl1_bar bar1_impl
impl(Bar, BarImpl1);

// Ensure that an interface can be implemented by many types.
typedef struct {
    char dummy;
} BarImpl2;

#define BarImpl2_foo foo2_impl
#define BarImpl2_bar bar2_impl
impl(Bar, BarImpl2);

// Ensure that a type can implement multiple interfaces.
typedef struct {
    char dummy;
} FooBarImpl;

#define FooBarImpl_foo foo1_impl
impl(Foo, FooBarImpl);
#undef FooBarImpl_foo

#define FooBarImpl_foo foo1_impl
#define FooBarImpl_bar bar1_impl
impl(Bar, FooBarImpl);
#undef FooBarImpl_foo
#undef FooBarImpl_bar

typedef struct {
    int x;
    long long d;
    const char *str;
} TestCompoundLit;

#define TestCompoundLit_foo foo1_impl
impl(Foo, TestCompoundLit);
// } (Implementations)

int main(void) {
    // Ensure `interface`-generated data.
    {
        ENSURE_VTABLE_FIELD_TYPE(MarkerVTable, dummy, char);
        ENSURE_DYN_OBJ_TYPE(Marker);

        ENSURE_VTABLE_FIELD_TYPE(FooVTable, foo, FooOpType);
        ENSURE_DYN_OBJ_TYPE(Foo);

        ENSURE_VTABLE_FIELD_TYPE(BarVTable, foo, FooOpType);
        ENSURE_VTABLE_FIELD_TYPE(BarVTable, bar, BarOpType);
        ENSURE_DYN_OBJ_TYPE(Bar);
    }

    // Ensure `impl`-generated data.
    {
        assert(VTABLE(MarkerImpl, Marker).dummy == '\0');

        assert(VTABLE(FooImpl, Foo).foo == foo1_impl);

        assert(VTABLE(BarImpl1, Bar).foo == foo1_impl);
        assert(VTABLE(BarImpl1, Bar).bar == bar1_impl);

        assert(VTABLE(BarImpl2, Bar).foo == foo2_impl);
        assert(VTABLE(BarImpl2, Bar).bar == bar2_impl);

        assert(VTABLE(FooBarImpl, Foo).foo == foo1_impl);
        assert(VTABLE(FooBarImpl, Bar).foo == foo1_impl);
        assert(VTABLE(FooBarImpl, Bar).bar == bar1_impl);
    }

    ENSURE_DYN_OBJ(MarkerImpl, Marker);
    ENSURE_DYN_OBJ(FooImpl, Foo);
    ENSURE_DYN_OBJ(BarImpl1, Bar);
    ENSURE_DYN_OBJ(BarImpl2, Bar);
    ENSURE_DYN_OBJ(FooBarImpl, Foo);
    ENSURE_DYN_OBJ(FooBarImpl, Bar);

    // Test compound literals with `DYN_LIT`.
    {
        Foo compound = DYN_LIT(TestCompoundLit, Foo, {.x = 123, .d = 15, .str = "abc"});

        assert(compound.vptr == &VTABLE(TestCompoundLit, Foo));
        assert(((TestCompoundLit *)compound.self)->x == 123);
        assert(((TestCompoundLit *)compound.self)->d == 15);
        assert(strcmp(((TestCompoundLit *)compound.self)->str, "abc") == 0);
    }

    return 0;
}