File: test_cassette.py

package info (click to toggle)
pcbasic 2.0.7-8
  • links: PTS
  • area: main
  • in suites: forky, sid
  • size: 35,416 kB
  • sloc: python: 28,411; sh: 103; makefile: 10
file content (256 lines) | stat: -rw-r--r-- 9,579 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
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
"""
PC-BASIC test.cassette
Tests for cassette device

(c) 2020--2023 Rob Hagemans
This file is released under the GNU GPL version 3 or later.
"""

import os
import shutil

from pcbasic import Session
from tests.unit.utils import TestCase, run_tests


HERE = os.path.dirname(os.path.abspath(__file__))


def _input_file(name):
    """Test input file."""
    return os.path.join(HERE, 'input', 'cassette', name)

def _output_file(name):
    """Test output file."""
    return os.path.join(HERE, 'output', 'cassette', name)


class CassetteTest(TestCase):
    """Cassette tests."""

    tag = u'cassette'

    def setUp(self):
        """Ensure output directory exists."""
        try:
            os.makedirs(_output_file(u''))
        except EnvironmentError:
            pass

    def test_cas_load(self):
        """Load from a CAS file."""
        with Session(devices={b'CAS1:': _input_file('test.cas')}) as s:
            s.execute('load "cas1:test"')
            s.execute('list')
            output = [_row.strip() for _row in self.get_text(s)]
        assert output[:4] == [
            b'not this.B Skipped.',
            b'test    .B Found.',
            b'10 OPEN "output.txt" FOR OUTPUT AS 1',
            b'20 PRINT#1, "cassette test"'
        ]

    def test_cas_save_load(self):
        """Save and load from an existing CAS file."""
        shutil.copy(_input_file('test.cas'), _output_file('test.cas'))
        with Session(devices={b'CAS1:': _output_file('test.cas')}) as s:
            s.execute('save "cas1:empty"')
            s.execute('load "cas1:test"')
            s.execute('list')
            output = [_row.strip() for _row in self.get_text(s)]
        assert output[:3] == [
            b'test    .B Found.',
            b'10 OPEN "output.txt" FOR OUTPUT AS 1',
            b'20 PRINT#1, "cassette test"'
        ]

    def test_cas_current_device(self):
        """Save and load to cassette as current device."""
        with Session(
                devices={b'CAS1:': _output_file('test_current.cas')},
                current_device=b'CAS1:'
            ) as s:
            s.execute('10 ?')
            s.execute('save "Test"')
        with Session(
                devices={b'CAS1:': _output_file('test_current.cas')},
                current_device=b'CAS1:'
            ) as s:
            s.execute('load "Test"')
            s.execute('list')
            output = [_row.strip() for _row in self.get_text(s)]
        assert output[:2] == [
            b'Test    .B Found.',
            b'10 PRINT',
        ]

    def test_cas_text(self):
        """Save and load in plaintext to a CAS file."""
        try:
            os.remove(_output_file('test_prog.cas'))
        except EnvironmentError:
            pass
        with Session(devices={b'CAS1:': _output_file('test_prog.cas')}) as s:
            s.execute('10 A%=1234')
            s.execute('save "cas1:prog",A')
        with Session(devices={b'CAS1:': _output_file('test_prog.cas')}) as s:
            s.execute('run "cas1:prog"')
            output = [_row.strip() for _row in self.get_text(s)]
            assert s.get_variable('A%') == 1234
            assert output[0] == b'prog    .A Found.'

    def test_cas_data(self):
        """Write and read data to a CAS file."""
        try:
            os.remove(_output_file('test_data.cas'))
        except EnvironmentError:
            pass
        with Session(devices={b'CAS1:': _output_file('test_data.cas')}) as s:
            s.execute('open "cas1:data" for output as 1')
            s.execute('print#1, 1234')
        with Session(devices={b'CAS1:': _output_file('test_data.cas')}) as s:
            s.execute('open "cas1:data" for input as 1')
            s.execute('input#1, A%')
            output = [_row.strip() for _row in self.get_text(s)]
            assert s.get_variable('A%') == 1234
            assert output[0] == b'data    .D Found.'

    def test_wav_text(self):
        """Save and load in plaintext to a WAV file."""
        try:
            os.remove(_output_file('test_prog.wav'))
        except EnvironmentError:
            pass
        with Session(devices={b'CAS1:': _output_file('test_prog.wav')}) as s:
            s.execute('10 A%=1234')
            s.execute('save "cas1:prog",A')
        with Session(devices={b'CAS1:': _output_file('test_prog.wav')}) as s:
            s.execute('run "cas1:prog"')
            assert s.get_variable('A%') == 1234

    def test_wav_data(self):
        """Write and read data to a WAV file."""
        try:
            os.remove(_output_file('test_data.wav'))
        except EnvironmentError:
            pass
        with Session(devices={b'CAS1:': _output_file('test_data.wav')}) as s:
            s.execute('open "cas1:data" for output as 1')
            s.execute('print#1, 1234')
        with Session(devices={b'CAS1:': _output_file('test_data.wav')}) as s:
            s.execute('open "cas1:data" for input as 1')
            s.execute('input#1, A%')
            assert s.get_variable('A%') == 1234

    def test_wav_save_load(self):
        """Save and load in to the same WAV file in one session."""
        try:
            os.remove(_output_file('test.wav'))
        except EnvironmentError:
            pass
        # create a WAV file with two programs
        with Session(devices={b'CAS1:': _output_file('test.wav')}) as s:
            s.execute('10 A%=1234')
            s.execute('save "cas1:prog"')
            s.execute('20 A%=12345')
            s.execute('save "cas1:Prog 2",A')
        with Session(devices={b'CAS1:': _output_file('test.wav')}) as s:
            # overwrite (part of) the first program
            s.execute('save "cas1:"')
            # load whatever is next (this should be Prog 2)
            s.execute('run "cas1:"')
            assert s.get_variable('A%') == 12345

    def test_cas_empty(self):
        """Attach empty CAS file."""
        try:
            os.remove(_output_file('empty.cas'))
        except EnvironmentError:
            pass
        # create empty file
        open(_output_file('empty.cas'), 'wb').close()
        with Session(devices={b'CAS1:': _output_file('empty.cas')}) as s:
            s.execute('save "cas1:"')
            s.execute('load "cas1:"')
            output = [_row.strip() for _row in self.get_text(s)]
        # device timeout given at end of tape
        assert output[0] == b'Device Timeout\xff'

    def test_cas_unavailable(self):
        """Try to attach directory as CAS file."""
        try:
            os.rmdir(_output_file('empty'))
        except EnvironmentError:
            pass
        # create empty dir
        os.mkdir(_output_file('empty'))
        with Session(devices={b'CAS1:': _output_file('empty')}) as s:
            s.execute('load "cas1:"')
            output = [_row.strip() for _row in self.get_text(s)]
            assert output[0] == b'Device Unavailable\xff'
            # check internal api function
            assert not s._impl.files.device_available(b'CAS1:')

    def test_cas_already_open(self):
        """Try to open file twice."""
        try:
            os.remove(_output_file('test_data.cas'))
        except EnvironmentError:
            pass
        with Session(devices={b'CAS1:': _output_file('test_data.cas')}) as s:
            s.execute('open "cas1:data" for output as 1')
            s.execute('open "cas1:data" for output as 2')
            output = [_row.strip() for _row in self.get_text(s)]
            assert output[0] == b'File already open\xff'

    def test_cas_bad_name(self):
        """Try to open file with funny name."""
        try:
            os.remove(_output_file('test_data.cas'))
        except EnvironmentError:
            pass
        with Session(devices={b'CAS1:': _output_file('test_data.cas')}) as s:
            s.execute(b'open "cas1:\x02\x01" for output as 1')
            output = [_row.strip() for _row in self.get_text(s)]
            assert output[0] == b'Bad file number\xff'

    def test_cas_bad_mode(self):
        """Try to open file with illegal mode."""
        try:
            os.remove(_output_file('test_data.cas'))
        except EnvironmentError:
            pass
        with Session(devices={b'CAS1:': _output_file('test_data.cas')}) as s:
            s.execute('open "cas1:test" for random as 1')
            output = [_row.strip() for _row in self.get_text(s)]
            assert output[0] == b'Bad file mode\xff'

    def test_cas_bad_operation(self):
        """Try to perform illegal operations."""
        try:
            os.remove(_output_file('test_data.cas'))
        except EnvironmentError:
            pass
        with Session(devices={b'CAS1:': _output_file('test_data.cas')}) as s:
            s.execute('open "cas1:test" for output as 1')
            s.execute('? LOF(1)')
            s.execute('? LOC(1)')
            output = [_row.strip() for _row in self.get_text(s)]
            assert output[:2] == [b'Illegal function call\xff', b'Illegal function call\xff']

    def test_cas_no_name(self):
        """Save and load to cassette without a filename."""
        with Session(devices={b'CAS1:': _output_file('test_current.cas')}) as s:
            s.execute('10 ?')
            s.execute('save "cas1:"')
        with Session(devices={b'CAS1:': _output_file('test_current.cas')}) as s:
            s.execute('load "cas1:"')
            s.execute('list')
            output = [_row.rstrip() for _row in self.get_text(s)]
        assert output[:2] == [
            b'        .B Found.',
            b'10 PRINT',
        ]

if __name__ == '__main__':
    run_tests()