Merge branch 'maint'
[debian/gnuradio] / gruel / src / lib / pmt / qa_pmt_prims.cc
1 /* -*- c++ -*- */
2 /*
3  * Copyright 2006,2009,2010 Free Software Foundation, Inc.
4  * 
5  * This file is part of GNU Radio
6  * 
7  * GNU Radio is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 3, or (at your option)
10  * any later version.
11  * 
12  * GNU Radio is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  * 
17  * You should have received a copy of the GNU General Public License
18  * along with GNU Radio; see the file COPYING.  If not, write to
19  * the Free Software Foundation, Inc., 51 Franklin Street,
20  * Boston, MA 02110-1301, USA.
21  */
22
23 #include <qa_pmt_prims.h>
24 #include <cppunit/TestAssert.h>
25 #include <gruel/msg_passing.h>
26 #include <cstdio>
27 #include <cstring>
28 #include <sstream>
29
30 using namespace pmt;
31
32 void
33 qa_pmt_prims::test_symbols()
34 {
35   CPPUNIT_ASSERT(!pmt_is_symbol(PMT_T));
36   CPPUNIT_ASSERT(!pmt_is_symbol(PMT_F));
37   CPPUNIT_ASSERT_THROW(pmt_symbol_to_string(PMT_F), pmt_wrong_type);
38
39   pmt_t sym1 = mp("test");
40   CPPUNIT_ASSERT(pmt_is_symbol(sym1));
41   CPPUNIT_ASSERT_EQUAL(std::string("test"), pmt_symbol_to_string(sym1));
42   CPPUNIT_ASSERT(pmt_is_true(sym1));
43   CPPUNIT_ASSERT(!pmt_is_false(sym1));
44
45   pmt_t sym2 = mp("foo");
46   pmt_t sym3 = mp("test");
47   CPPUNIT_ASSERT_EQUAL(sym1, sym3);
48   CPPUNIT_ASSERT(sym1 != sym2);
49   CPPUNIT_ASSERT(sym1 == sym3);
50
51   static const int N = 2048;
52   std::vector<pmt_t> v1(N);
53   std::vector<pmt_t> v2(N);
54
55   // generate a bunch of symbols
56   for (int i = 0; i < N; i++){
57     char buf[100];
58     snprintf(buf, sizeof(buf), "test-%d", i);
59     v1[i] = mp(buf);
60   }
61
62   // confirm that they are all unique
63   for (int i = 0; i < N; i++)
64     for (int j = i + 1; j < N; j++)
65       CPPUNIT_ASSERT(v1[i] != v1[j]);
66
67   // generate the same symbols again
68   for (int i = 0; i < N; i++){
69     char buf[100];
70     snprintf(buf, sizeof(buf), "test-%d", i);
71     v2[i] = mp(buf);
72   }
73
74   // confirm that we get the same ones back
75   for (int i = 0; i < N; i++)
76     CPPUNIT_ASSERT(v1[i] == v2[i]);
77 }
78
79 void
80 qa_pmt_prims::test_booleans()
81 {
82   pmt_t sym = mp("test");
83   CPPUNIT_ASSERT(pmt_is_bool(PMT_T));
84   CPPUNIT_ASSERT(pmt_is_bool(PMT_F));
85   CPPUNIT_ASSERT(!pmt_is_bool(sym));
86   CPPUNIT_ASSERT_EQUAL(pmt_from_bool(false), PMT_F);
87   CPPUNIT_ASSERT_EQUAL(pmt_from_bool(true), PMT_T);
88   CPPUNIT_ASSERT_EQUAL(false, pmt_to_bool(PMT_F));
89   CPPUNIT_ASSERT_EQUAL(true, pmt_to_bool(PMT_T));
90   CPPUNIT_ASSERT_THROW(pmt_to_bool(sym), pmt_wrong_type);
91 }
92
93 void
94 qa_pmt_prims::test_integers()
95 {
96   pmt_t p1 = pmt_from_long(1);
97   pmt_t m1 = pmt_from_long(-1);
98   CPPUNIT_ASSERT(!pmt_is_integer(PMT_T));
99   CPPUNIT_ASSERT(pmt_is_integer(p1));
100   CPPUNIT_ASSERT(pmt_is_integer(m1));
101   CPPUNIT_ASSERT_THROW(pmt_to_long(PMT_T), pmt_wrong_type);
102   CPPUNIT_ASSERT_EQUAL(-1L, pmt_to_long(m1));
103   CPPUNIT_ASSERT_EQUAL(1L, pmt_to_long(p1));
104 }
105
106 void
107 qa_pmt_prims::test_uint64s()
108 {
109   pmt_t p1 = pmt_from_uint64((uint64_t)1);
110   pmt_t m1 = pmt_from_uint64((uint64_t)8589934592ULL);
111   CPPUNIT_ASSERT(!pmt_is_uint64(PMT_T));
112   CPPUNIT_ASSERT(pmt_is_uint64(p1));
113   CPPUNIT_ASSERT(pmt_is_uint64(m1));
114   CPPUNIT_ASSERT_THROW(pmt_to_uint64(PMT_T), pmt_wrong_type);
115   CPPUNIT_ASSERT_EQUAL((uint64_t)8589934592ULL, (uint64_t)pmt_to_uint64(m1));
116   CPPUNIT_ASSERT_EQUAL((uint64_t)1ULL, (uint64_t)pmt_to_uint64(p1));
117 }
118
119 void
120 qa_pmt_prims::test_reals()
121 {
122   pmt_t p1 = pmt_from_double(1);
123   pmt_t m1 = pmt_from_double(-1);
124   CPPUNIT_ASSERT(!pmt_is_real(PMT_T));
125   CPPUNIT_ASSERT(pmt_is_real(p1));
126   CPPUNIT_ASSERT(pmt_is_real(m1));
127   CPPUNIT_ASSERT_THROW(pmt_to_double(PMT_T), pmt_wrong_type);
128   CPPUNIT_ASSERT_EQUAL(-1.0, pmt_to_double(m1));
129   CPPUNIT_ASSERT_EQUAL(1.0, pmt_to_double(p1));
130   CPPUNIT_ASSERT_EQUAL(1.0, pmt_to_double(pmt_from_long(1)));
131 }
132
133 void
134 qa_pmt_prims::test_complexes()
135 {
136   pmt_t p1 = pmt_make_rectangular(2, -3);
137   pmt_t m1 = pmt_make_rectangular(-3, 2);
138   CPPUNIT_ASSERT(!pmt_is_complex(PMT_T));
139   CPPUNIT_ASSERT(pmt_is_complex(p1));
140   CPPUNIT_ASSERT(pmt_is_complex(m1));
141   CPPUNIT_ASSERT_THROW(pmt_to_complex(PMT_T), pmt_wrong_type);
142   CPPUNIT_ASSERT_EQUAL(std::complex<double>(2, -3), pmt_to_complex(p1));
143   CPPUNIT_ASSERT_EQUAL(std::complex<double>(-3, 2), pmt_to_complex(m1));
144   CPPUNIT_ASSERT_EQUAL(std::complex<double>(1.0, 0), pmt_to_complex(pmt_from_long(1)));
145   CPPUNIT_ASSERT_EQUAL(std::complex<double>(1.0, 0), pmt_to_complex(pmt_from_double(1.0)));
146 }
147
148 void
149 qa_pmt_prims::test_pairs()
150 {
151   CPPUNIT_ASSERT(pmt_is_null(PMT_NIL));
152   CPPUNIT_ASSERT(!pmt_is_pair(PMT_NIL));
153   pmt_t s1 = mp("s1");
154   pmt_t s2 = mp("s2");
155   pmt_t s3 = mp("s3");
156
157
158   CPPUNIT_ASSERT_EQUAL((size_t)0, pmt_length(PMT_NIL));
159   CPPUNIT_ASSERT_THROW(pmt_length(s1), pmt_wrong_type);
160   CPPUNIT_ASSERT_THROW(pmt_length(pmt_from_double(42)), pmt_wrong_type);
161
162   pmt_t c1 = pmt_cons(s1, PMT_NIL);
163   CPPUNIT_ASSERT(pmt_is_pair(c1));
164   CPPUNIT_ASSERT(!pmt_is_pair(s1));
165   CPPUNIT_ASSERT_EQUAL(s1, pmt_car(c1));
166   CPPUNIT_ASSERT_EQUAL(PMT_NIL, pmt_cdr(c1));
167   CPPUNIT_ASSERT_EQUAL((size_t) 1, pmt_length(c1));
168
169   pmt_t c3 = pmt_cons(s3, PMT_NIL);
170   pmt_t c2 = pmt_cons(s2, c3);
171   pmt_set_cdr(c1, c2);
172   CPPUNIT_ASSERT_EQUAL(c2, pmt_cdr(c1));
173   pmt_set_car(c1, s3);
174   CPPUNIT_ASSERT_EQUAL(s3, pmt_car(c1));
175   CPPUNIT_ASSERT_EQUAL((size_t)1, pmt_length(c3));
176   CPPUNIT_ASSERT_EQUAL((size_t)2, pmt_length(c2));
177   
178   CPPUNIT_ASSERT_THROW(pmt_cdr(PMT_NIL), pmt_wrong_type);
179   CPPUNIT_ASSERT_THROW(pmt_car(PMT_NIL), pmt_wrong_type);
180   CPPUNIT_ASSERT_THROW(pmt_set_car(s1, PMT_NIL), pmt_wrong_type);
181   CPPUNIT_ASSERT_THROW(pmt_set_cdr(s1, PMT_NIL), pmt_wrong_type);
182 }
183
184 void
185 qa_pmt_prims::test_vectors()
186 {
187   static const size_t N = 3;
188   pmt_t v1 = pmt_make_vector(N, PMT_NIL);
189   CPPUNIT_ASSERT_EQUAL(N, pmt_length(v1));
190   pmt_t s0 = mp("s0");
191   pmt_t s1 = mp("s1");
192   pmt_t s2 = mp("s2");
193
194   pmt_vector_set(v1, 0, s0);
195   pmt_vector_set(v1, 1, s1);
196   pmt_vector_set(v1, 2, s2);
197
198   CPPUNIT_ASSERT_EQUAL(s0, pmt_vector_ref(v1, 0));
199   CPPUNIT_ASSERT_EQUAL(s1, pmt_vector_ref(v1, 1));
200   CPPUNIT_ASSERT_EQUAL(s2, pmt_vector_ref(v1, 2));
201
202   CPPUNIT_ASSERT_THROW(pmt_vector_ref(v1, N), pmt_out_of_range);
203   CPPUNIT_ASSERT_THROW(pmt_vector_set(v1, N, PMT_NIL), pmt_out_of_range);
204
205   pmt_vector_fill(v1, s0);
206   for (size_t i = 0; i < N; i++)
207     CPPUNIT_ASSERT_EQUAL(s0, pmt_vector_ref(v1, i));
208 }
209
210 static void
211 check_tuple(size_t len, const std::vector<pmt_t> &s, pmt_t t)
212 {
213   CPPUNIT_ASSERT_EQUAL(true, pmt_is_tuple(t));
214   CPPUNIT_ASSERT_EQUAL(len, pmt_length(t));
215
216   for (size_t i = 0; i < len; i++)
217     CPPUNIT_ASSERT_EQUAL(s[i], pmt_tuple_ref(t, i));
218
219 }
220
221 void
222 qa_pmt_prims::test_tuples()
223 {
224   pmt_t v = pmt_make_vector(10, PMT_NIL);
225   std::vector<pmt_t> s(10);
226   for (size_t i = 0; i < 10; i++){
227     std::ostringstream os;
228     os << "s" << i;
229     s[i] = mp(os.str());
230     pmt_vector_set(v, i, s[i]);
231   }
232
233
234   pmt_t t;
235
236   t = pmt_make_tuple();
237   check_tuple(0, s, t);
238
239   t = pmt_make_tuple(s[0]);
240   check_tuple(1, s, t);
241
242   CPPUNIT_ASSERT(pmt_is_vector(v));
243   CPPUNIT_ASSERT(!pmt_is_tuple(v));
244   CPPUNIT_ASSERT(pmt_is_tuple(t));
245   CPPUNIT_ASSERT(!pmt_is_vector(t));
246
247   t = pmt_make_tuple(s[0], s[1]);
248   check_tuple(2, s, t);
249
250   t = pmt_make_tuple(s[0], s[1], s[2]);
251   check_tuple(3, s, t);
252
253   t = pmt_make_tuple(s[0], s[1], s[2], s[3]);
254   check_tuple(4, s, t);
255
256   t = pmt_make_tuple(s[0], s[1], s[2], s[3], s[4]);
257   check_tuple(5, s, t);
258
259   t = pmt_make_tuple(s[0], s[1], s[2], s[3], s[4], s[5]);
260   check_tuple(6, s, t);
261
262   t = pmt_make_tuple(s[0], s[1], s[2], s[3], s[4], s[5], s[6]);
263   check_tuple(7, s, t);
264
265   t = pmt_make_tuple(s[0], s[1], s[2], s[3], s[4], s[5], s[6], s[7]);
266   check_tuple(8, s, t);
267
268   t = pmt_make_tuple(s[0], s[1], s[2], s[3], s[4], s[5], s[6], s[7], s[8]);
269   check_tuple(9, s, t);
270
271   t = pmt_make_tuple(s[0], s[1], s[2], s[3], s[4], s[5], s[6], s[7], s[8], s[9]);
272   check_tuple(10, s, t);
273
274   t = pmt_make_tuple(s[0], s[1], s[2]);
275   CPPUNIT_ASSERT_THROW(pmt_tuple_ref(t, 3), pmt_out_of_range);
276   CPPUNIT_ASSERT_THROW(pmt_vector_ref(t, 0), pmt_wrong_type);
277   CPPUNIT_ASSERT_THROW(pmt_tuple_ref(v, 0), pmt_wrong_type);
278
279   t = pmt_make_tuple(s[0], s[1], s[2], s[3], s[4], s[5], s[6], s[7], s[8], s[9]);
280   pmt_t t2 = pmt_to_tuple(v);
281   CPPUNIT_ASSERT_EQUAL(size_t(10), pmt_length(v));
282   CPPUNIT_ASSERT(pmt_equal(t, t2));
283   //std::cout << v << std::endl;
284   //std::cout << t2 << std::endl;
285
286   
287   t = pmt_make_tuple(s[0], s[1], s[2]);
288   pmt_t list0 = pmt_list3(s[0], s[1], s[2]);
289   CPPUNIT_ASSERT_EQUAL(size_t(3), pmt_length(list0));
290   t2 = pmt_to_tuple(list0);
291   CPPUNIT_ASSERT_EQUAL(size_t(3), pmt_length(t2));
292   CPPUNIT_ASSERT(pmt_equal(t, t2));
293 }
294
295 void
296 qa_pmt_prims::test_equivalence()
297 {
298   pmt_t s0 = mp("s0");
299   pmt_t s1 = mp("s1");
300   pmt_t s2 = mp("s2");
301   pmt_t list0 = pmt_cons(s0, pmt_cons(s1, pmt_cons(s2, PMT_NIL)));
302   pmt_t list1 = pmt_cons(s0, pmt_cons(s1, pmt_cons(s2, PMT_NIL)));
303   pmt_t i0 = pmt_from_long(42);
304   pmt_t i1 = pmt_from_long(42);
305   pmt_t r0 = pmt_from_double(42);
306   pmt_t r1 = pmt_from_double(42);
307   pmt_t r2 = pmt_from_double(43);
308
309   CPPUNIT_ASSERT(pmt_eq(s0, s0));
310   CPPUNIT_ASSERT(!pmt_eq(s0, s1));
311   CPPUNIT_ASSERT(pmt_eqv(s0, s0));
312   CPPUNIT_ASSERT(!pmt_eqv(s0, s1));
313
314   CPPUNIT_ASSERT(pmt_eqv(i0, i1));
315   CPPUNIT_ASSERT(pmt_eqv(r0, r1));
316   CPPUNIT_ASSERT(!pmt_eqv(r0, r2));
317   CPPUNIT_ASSERT(!pmt_eqv(i0, r0));
318
319   CPPUNIT_ASSERT(!pmt_eq(list0, list1));
320   CPPUNIT_ASSERT(!pmt_eqv(list0, list1));
321   CPPUNIT_ASSERT(pmt_equal(list0, list1));
322
323   pmt_t v0 = pmt_make_vector(3, s0);
324   pmt_t v1 = pmt_make_vector(3, s0);
325   pmt_t v2 = pmt_make_vector(4, s0);
326   CPPUNIT_ASSERT(!pmt_eqv(v0, v1));
327   CPPUNIT_ASSERT(pmt_equal(v0, v1));
328   CPPUNIT_ASSERT(!pmt_equal(v0, v2));
329
330   pmt_vector_set(v0, 0, list0);
331   pmt_vector_set(v0, 1, list0);
332   pmt_vector_set(v1, 0, list1);
333   pmt_vector_set(v1, 1, list1);
334   CPPUNIT_ASSERT(pmt_equal(v0, v1));
335 }
336
337 void
338 qa_pmt_prims::test_misc()
339 {
340   pmt_t k0 = mp("k0");
341   pmt_t k1 = mp("k1");
342   pmt_t k2 = mp("k2");
343   pmt_t k3 = mp("k3");
344   pmt_t v0 = mp("v0");
345   pmt_t v1 = mp("v1");
346   pmt_t v2 = mp("v2");
347   pmt_t p0 = pmt_cons(k0, v0);
348   pmt_t p1 = pmt_cons(k1, v1);
349   pmt_t p2 = pmt_cons(k2, v2);
350   
351   pmt_t alist = pmt_cons(p0, pmt_cons(p1, pmt_cons(p2, PMT_NIL)));
352   CPPUNIT_ASSERT(pmt_eq(p1, pmt_assv(k1, alist)));
353   CPPUNIT_ASSERT(pmt_eq(PMT_F, pmt_assv(k3, alist)));
354   
355   pmt_t keys = pmt_cons(k0, pmt_cons(k1, pmt_cons(k2, PMT_NIL)));
356   pmt_t vals = pmt_cons(v0, pmt_cons(v1, pmt_cons(v2, PMT_NIL)));
357   CPPUNIT_ASSERT(pmt_equal(keys, pmt_map(pmt_car, alist)));
358   CPPUNIT_ASSERT(pmt_equal(vals, pmt_map(pmt_cdr, alist)));
359 }
360
361 void
362 qa_pmt_prims::test_dict()
363 {
364   pmt_t dict = pmt_make_dict();
365   CPPUNIT_ASSERT(pmt_is_dict(dict));
366
367   pmt_t k0 = mp("k0");
368   pmt_t k1 = mp("k1");
369   pmt_t k2 = mp("k2");
370   pmt_t k3 = mp("k3");
371   pmt_t v0 = mp("v0");
372   pmt_t v1 = mp("v1");
373   pmt_t v2 = mp("v2");
374   pmt_t v3 = mp("v3");
375   pmt_t not_found = pmt_cons(PMT_NIL, PMT_NIL);
376   
377   CPPUNIT_ASSERT(!pmt_dict_has_key(dict, k0));
378   dict = pmt_dict_add(dict, k0, v0);
379   CPPUNIT_ASSERT(pmt_dict_has_key(dict, k0));
380   CPPUNIT_ASSERT(pmt_eqv(pmt_dict_ref(dict, k0, not_found), v0));
381   CPPUNIT_ASSERT(pmt_eqv(pmt_dict_ref(dict, k1, not_found), not_found));
382   dict = pmt_dict_add(dict, k1, v1);
383   dict = pmt_dict_add(dict, k2, v2);
384   CPPUNIT_ASSERT(pmt_eqv(pmt_dict_ref(dict, k1, not_found), v1));
385   dict = pmt_dict_add(dict, k1, v3);
386   CPPUNIT_ASSERT(pmt_eqv(pmt_dict_ref(dict, k1, not_found), v3));
387
388   pmt_t keys = pmt_list3(k1, k2, k0);
389   pmt_t vals = pmt_list3(v3, v2, v0);
390   //std::cout << "pmt_dict_keys:   " << pmt_dict_keys(dict) << std::endl;
391   //std::cout << "pmt_dict_values: " << pmt_dict_values(dict) << std::endl;
392   CPPUNIT_ASSERT(pmt_equal(keys, pmt_dict_keys(dict)));
393   CPPUNIT_ASSERT(pmt_equal(vals, pmt_dict_values(dict)));
394 }
395
396 void
397 qa_pmt_prims::test_io()
398 {
399   pmt_t k0 = mp("k0");
400   pmt_t k1 = mp("k1");
401   pmt_t k2 = mp("k2");
402   pmt_t k3 = mp("k3");
403
404   CPPUNIT_ASSERT_EQUAL(std::string("k0"), pmt_write_string(k0));
405 }
406
407 void
408 qa_pmt_prims::test_lists()
409 {
410   pmt_t s0 = mp("s0");
411   pmt_t s1 = mp("s1");
412   pmt_t s2 = mp("s2");
413   pmt_t s3 = mp("s3");
414
415   pmt_t l1 = pmt_list4(s0, s1, s2, s3);
416   pmt_t l2 = pmt_list3(s0, s1, s2);
417   pmt_t l3 = pmt_list_add(l2, s3);
418   CPPUNIT_ASSERT(pmt_equal(l1, l3));
419 }
420
421 // ------------------------------------------------------------------------
422
423 // class foo is used in test_any below.
424 // It can't be declared in the scope of test_any because of template
425 // namespace problems.
426
427 class foo {
428 public:
429   double        d_double;
430   int           d_int;
431   foo(double d=0, int i=0) : d_double(d), d_int(i) {}
432 };
433
434 bool operator==(const foo &a, const foo &b)
435 {
436   return a.d_double == b.d_double && a.d_int == b.d_int;
437 }
438
439 std::ostream& operator<<(std::ostream &os, const foo obj)
440 {
441   os << "<foo: " << obj.d_double << ", " << obj.d_int << ">";
442   return os;
443 }
444
445 void
446 qa_pmt_prims::test_any()
447 {
448   boost::any a0;
449   boost::any a1;
450   boost::any a2;
451
452   a0 = std::string("Hello!");
453   a1 = 42;
454   a2 = foo(3.250, 21);
455
456   pmt_t p0 = pmt_make_any(a0);
457   pmt_t p1 = pmt_make_any(a1);
458   pmt_t p2 = pmt_make_any(a2);
459
460   CPPUNIT_ASSERT_EQUAL(std::string("Hello!"),
461                        boost::any_cast<std::string>(pmt_any_ref(p0)));
462
463   CPPUNIT_ASSERT_EQUAL(42,
464                        boost::any_cast<int>(pmt_any_ref(p1)));
465
466   CPPUNIT_ASSERT_EQUAL(foo(3.250, 21),
467                        boost::any_cast<foo>(pmt_any_ref(p2)));
468 }
469
470 // ------------------------------------------------------------------------
471
472 class qa_pmt_msg_accepter_nop : public gruel::msg_accepter {
473 public:
474   qa_pmt_msg_accepter_nop(){};
475   ~qa_pmt_msg_accepter_nop();
476   void post(pmt_t){};
477 };
478
479 qa_pmt_msg_accepter_nop::~qa_pmt_msg_accepter_nop(){}
480
481 void
482 qa_pmt_prims::test_msg_accepter()
483 {
484   pmt_t sym = mp("my-symbol");
485
486   boost::any a0;
487   a0 = std::string("Hello!");
488   pmt_t p0 = pmt_make_any(a0);
489
490   gruel::msg_accepter_sptr ma0 = gruel::msg_accepter_sptr(new qa_pmt_msg_accepter_nop());
491   pmt_t p1 = pmt_make_msg_accepter(ma0);
492
493   CPPUNIT_ASSERT_EQUAL(ma0.get(), pmt_msg_accepter_ref(p1).get());
494
495   CPPUNIT_ASSERT_THROW(pmt_msg_accepter_ref(sym), pmt_wrong_type);
496   CPPUNIT_ASSERT_THROW(pmt_msg_accepter_ref(p0),  pmt_wrong_type);
497
498   // just confirm interfaces on send are OK
499   gruel::send(ma0.get(), sym);
500   gruel::send(ma0, sym);
501   gruel::send(p1, sym);
502
503 }
504
505 // ------------------------------------------------------------------------
506
507 void
508 qa_pmt_prims::test_serialize()
509 {
510   std::stringbuf sb;            // fake channel
511   pmt_t a = mp("a");
512   pmt_t b = mp("b");
513   pmt_t c = mp("c");
514
515   sb.str("");                   // reset channel to empty
516
517   // write stuff to channel
518
519   pmt_serialize(PMT_NIL, sb);
520   pmt_serialize(mp("foobarvia"), sb);
521   pmt_serialize(pmt_from_long(123456789), sb);
522   pmt_serialize(pmt_from_long(-123456789), sb);
523   pmt_serialize(pmt_cons(PMT_NIL, PMT_NIL), sb);
524   pmt_serialize(pmt_cons(a, b), sb);
525   pmt_serialize(pmt_list1(a), sb);
526   pmt_serialize(pmt_list2(a, b), sb);
527   pmt_serialize(pmt_list3(a, b, c), sb);
528   pmt_serialize(pmt_list3(a, pmt_list3(c, b, a), c), sb);
529   pmt_serialize(PMT_T, sb);
530   pmt_serialize(PMT_F, sb);
531
532   // read it back
533
534   CPPUNIT_ASSERT(pmt_equal(pmt_deserialize(sb), PMT_NIL));
535   CPPUNIT_ASSERT(pmt_equal(pmt_deserialize(sb), mp("foobarvia")));
536   CPPUNIT_ASSERT(pmt_equal(pmt_deserialize(sb), pmt_from_long(123456789)));
537   CPPUNIT_ASSERT(pmt_equal(pmt_deserialize(sb), pmt_from_long(-123456789)));
538   CPPUNIT_ASSERT(pmt_equal(pmt_deserialize(sb), pmt_cons(PMT_NIL, PMT_NIL)));
539   CPPUNIT_ASSERT(pmt_equal(pmt_deserialize(sb), pmt_cons(a, b)));
540   CPPUNIT_ASSERT(pmt_equal(pmt_deserialize(sb), pmt_list1(a)));
541   CPPUNIT_ASSERT(pmt_equal(pmt_deserialize(sb), pmt_list2(a, b)));
542   CPPUNIT_ASSERT(pmt_equal(pmt_deserialize(sb), pmt_list3(a, b, c)));
543   CPPUNIT_ASSERT(pmt_equal(pmt_deserialize(sb), pmt_list3(a, pmt_list3(c, b, a), c)));
544   CPPUNIT_ASSERT(pmt_equal(pmt_deserialize(sb), PMT_T));
545   CPPUNIT_ASSERT(pmt_equal(pmt_deserialize(sb), PMT_F));
546
547   CPPUNIT_ASSERT(pmt_equal(pmt_deserialize(sb), PMT_EOF));      // last item
548
549
550   // FIXME add tests for real, complex, vector, uniform-vector, dict
551   // FIXME add tests for malformed input too.
552
553 }
554
555 void
556 qa_pmt_prims::test_sets()
557 {
558   pmt_t s1 = mp("s1");
559   pmt_t s2 = mp("s2");
560   pmt_t s3 = mp("s3");
561
562   pmt_t l1 = pmt_list1(s1);
563   pmt_t l2 = pmt_list2(s2,s3);
564   pmt_t l3 = pmt_list3(s1,s2,s3);
565
566   CPPUNIT_ASSERT(pmt_is_pair(pmt_memq(s1,l1)));
567   CPPUNIT_ASSERT(pmt_is_false(pmt_memq(s3,l1)));
568
569   CPPUNIT_ASSERT(pmt_subsetp(l1,l3));
570   CPPUNIT_ASSERT(pmt_subsetp(l2,l3));
571   CPPUNIT_ASSERT(!pmt_subsetp(l1,l2));
572   CPPUNIT_ASSERT(!pmt_subsetp(l2,l1));
573   CPPUNIT_ASSERT(!pmt_subsetp(l3,l2));
574 }
575
576 void
577 qa_pmt_prims::test_sugar()
578 {
579   CPPUNIT_ASSERT(pmt_is_symbol(mp("my-symbol")));
580   CPPUNIT_ASSERT_EQUAL((long) 10, pmt_to_long(mp(10)));
581   CPPUNIT_ASSERT_EQUAL((double) 1e6, pmt_to_double(mp(1e6)));
582   CPPUNIT_ASSERT_EQUAL(std::complex<double>(2, 3),
583                        pmt_to_complex(mp(std::complex<double>(2, 3))));
584
585   int buf[10] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
586   pmt_t blob = mp(buf, sizeof(buf));
587   const void *data = pmt_blob_data(blob);
588   size_t nbytes = pmt_blob_length(blob);
589   CPPUNIT_ASSERT_EQUAL(sizeof(buf), nbytes);
590   CPPUNIT_ASSERT(memcmp(buf, data, nbytes) == 0);
591 }