Merge branch 'master' into windows+cc
[ardour.git] / libs / ardour / test / test_util.cc
1 #include <fstream>
2 #include <sstream>
3 #include "pbd/xml++.h"
4 #include "pbd/textreceiver.h"
5 #include "ardour/session.h"
6 #include "ardour/audioengine.h"
7 #include <cppunit/extensions/HelperMacros.h>
8
9 using namespace std;
10 using namespace ARDOUR;
11 using namespace PBD;
12
13 static void
14 check_nodes (XMLNode const * p, XMLNode const * q, list<string> const & ignore_properties)
15 {
16         CPPUNIT_ASSERT_EQUAL (p->is_content(), q->is_content());
17         if (!p->is_content()) {
18                 CPPUNIT_ASSERT_EQUAL (p->name(), q->name());
19         } else {
20                 CPPUNIT_ASSERT_EQUAL (p->content(), q->content());
21         }
22
23         XMLPropertyList const & pp = p->properties ();
24         XMLPropertyList const & qp = q->properties ();
25         CPPUNIT_ASSERT_EQUAL (pp.size(), qp.size());
26
27         XMLPropertyList::const_iterator i = pp.begin ();
28         XMLPropertyList::const_iterator j = qp.begin ();
29         while (i != pp.end ()) {
30                 CPPUNIT_ASSERT_EQUAL ((*i)->name(), (*j)->name());
31                 if (find (ignore_properties.begin(), ignore_properties.end(), (*i)->name ()) == ignore_properties.end ()) {
32                         CPPUNIT_ASSERT_EQUAL ((*i)->value(), (*j)->value());
33                 }
34                 ++i;
35                 ++j;
36         }
37
38         XMLNodeList const & pc = p->children ();
39         XMLNodeList const & qc = q->children ();
40
41         CPPUNIT_ASSERT_EQUAL (pc.size(), qc.size());
42         XMLNodeList::const_iterator k = pc.begin ();
43         XMLNodeList::const_iterator l = qc.begin ();
44         
45         while (k != pc.end ()) {
46                 check_nodes (*k, *l, ignore_properties);
47                 ++k;
48                 ++l;
49         }
50 }
51
52 void
53 check_xml (XMLNode* node, string ref_file, list<string> const & ignore_properties)
54 {
55         XMLTree ref (ref_file);
56
57         XMLNode* p = node;
58         XMLNode* q = ref.root ();
59
60         check_nodes (p, q, ignore_properties);
61 }
62
63 bool
64 write_ref (XMLNode* node, string ref_file)
65 {
66         XMLTree ref;
67         ref.set_root (node);
68         return ref.write (ref_file);
69 }
70
71 class TestReceiver : public Receiver 
72 {
73 protected:
74         void receive (Transmitter::Channel chn, const char * str) {
75                 const char *prefix = "";
76                 
77                 switch (chn) {
78                 case Transmitter::Error:
79                         prefix = ": [ERROR]: ";
80                         break;
81                 case Transmitter::Info:
82                         /* ignore */
83                         return;
84                 case Transmitter::Warning:
85                         prefix = ": [WARNING]: ";
86                         break;
87                 case Transmitter::Fatal:
88                         prefix = ": [FATAL]: ";
89                         break;
90                 case Transmitter::Throw:
91                         /* this isn't supposed to happen */
92                         abort ();
93                 }
94                 
95                 /* note: iostreams are already thread-safe: no external
96                    lock required.
97                 */
98                 
99                 cout << prefix << str << endl;
100                 
101                 if (chn == Transmitter::Fatal) {
102                         exit (9);
103                 }
104         }
105 };
106
107 TestReceiver test_receiver;
108
109 /** @param dir Session directory.
110  *  @param state Session state file, without .ardour suffix.
111  */
112 Session *
113 load_session (string dir, string state)
114 {
115         SessionEvent::create_per_thread_pool ("test", 512);
116
117         test_receiver.listen_to (error);
118         test_receiver.listen_to (info);
119         test_receiver.listen_to (fatal);
120         test_receiver.listen_to (warning);
121
122         /* We can't use VSTs here as we have a stub instead of the
123            required bits in gtk2_ardour.
124         */
125         Config->set_use_lxvst (false);
126
127         AudioEngine* engine = AudioEngine::create ();
128
129         CPPUNIT_ASSERT (engine->set_default_backend ());
130
131         init_post_engine ();
132
133         CPPUNIT_ASSERT (engine->start () == 0);
134
135         Session* session = new Session (*engine, dir, state);
136         engine->set_session (session);
137         return session;
138 }