def test_requires_stop(self) -> None:
        sub1 = (DummyPulseTemplate(requires_stop=False), {}, {})
        sub2 = (DummyPulseTemplate(requires_stop=True, parameter_names={'foo'}), {'foo': 'foo'}, {})
        parameters = {'foo': DummyNoValueParameter()}

        seq = SequencePulseTemplate(sub1)
        self.assertFalse(seq.requires_stop(parameters, {}))

        seq = SequencePulseTemplate(sub2)
        self.assertFalse(seq.requires_stop(parameters, {}))

        seq = SequencePulseTemplate(sub1, sub2)
        self.assertFalse(seq.requires_stop(parameters, {}))

        seq = SequencePulseTemplate(sub2, sub1)
        self.assertFalse(seq.requires_stop(parameters, {}))
    def test_crash(self) -> None:
        table = TablePulseTemplate({'default': [('ta', 'va', 'hold'),
                                                ('tb', 'vb', 'linear'),
                                                ('tend', 0, 'jump')]}, identifier='foo')

        expected_parameters = {'ta', 'tb', 'tc', 'td', 'va', 'vb', 'tend'}
        first_mapping = {
            'ta': 'ta',
            'tb': 'tb',
            'va': 'va',
            'vb': 'vb',
            'tend': 'tend'
        }
        second_mapping = {
            'ta': 'tc',
            'tb': 'td',
            'va': 'vb',
            'vb': 'va + vb',
            'tend': '2 * tend'
        }
        sequence = SequencePulseTemplate((table, first_mapping, {}), (table, second_mapping, {}))
        self.assertEqual(expected_parameters, sequence.parameter_names)

        parameters = {
            'ta': ConstantParameter(2),
            'va': ConstantParameter(2),
            'tb': ConstantParameter(4),
            'vb': ConstantParameter(3),
            'tc': ConstantParameter(5),
            'td': ConstantParameter(11),
            'tend': ConstantParameter(6)}

        sequencer = DummySequencer()
        block = DummyInstructionBlock()
        self.assertFalse(sequence.requires_stop(parameters, {}))
        sequence.build_sequence(sequencer,
                                parameters=parameters,
                                conditions={},
                                measurement_mapping={},
                                channel_mapping={'default': 'default'},
                                instruction_block=block)
        from qupulse.pulses.sequencing import Sequencer
        s = Sequencer()
        s.push(sequence, parameters, channel_mapping={'default': 'EXAMPLE_A'})
    def test_table_sequence_sequencer_integration(self) -> None:
        t1 = TablePulseTemplate(entries={'default': [(2, 'foo'), (5, 0)]},
                                measurements=[('foo', 2, 2)])

        t2 = TablePulseTemplate(
            entries={'default': [(4, 0), (4.5, 'bar', 'linear'), (5, 0)]},
            measurements=[('foo', 4, 1)])

        seqt = SequencePulseTemplate(
            MappingPulseTemplate(t1, measurement_mapping={'foo': 'bar'}),
            MappingPulseTemplate(t2, parameter_mapping={'bar': '2 * hugo'}))

        with self.assertRaises(ParameterNotProvidedException):
            t1.requires_stop(dict(), dict())
        with self.assertRaises(ParameterNotProvidedException):
            t2.requires_stop(dict(), dict())
        self.assertFalse(
            seqt.requires_stop(
                {
                    'foo': DummyParameter(),
                    'hugo': DummyParameter()
                }, {}))

        foo = DummyNoValueParameter()
        bar = DummyNoValueParameter()
        sequencer = Sequencer()
        sequencer.push(seqt, {
            'foo': foo,
            'hugo': bar
        },
                       window_mapping=dict(bar='my', foo='thy'),
                       channel_mapping={'default': 'A'})
        instructions = sequencer.build()
        self.assertFalse(sequencer.has_finished())
        self.assertEqual(1, len(instructions))

        # stop after first TablePT
        foo = DummyParameter(value=1.1)
        bar = DummyNoValueParameter()
        sequencer = Sequencer()
        sequencer.push(seqt, {
            'foo': foo,
            'hugo': bar
        },
                       window_mapping=dict(bar='my', foo='thy'),
                       channel_mapping={'default': 'A'})
        block = sequencer.build()
        instructions = block.instructions
        self.assertFalse(sequencer.has_finished())
        self.assertIsInstance(block, AbstractInstructionBlock)
        self.assertEqual(2, len(instructions))
        self.assertEqual(instructions[0], MEASInstruction([('my', 2, 2)]))
        self.assertIsInstance(instructions[1], EXECInstruction)

        # stop before first TablePT
        foo = DummyParameter(value=1.1)
        bar = DummyNoValueParameter()
        sequencer = Sequencer()
        sequencer.push(seqt, {
            'foo': bar,
            'hugo': foo
        },
                       window_mapping=dict(bar='my', foo='thy'),
                       channel_mapping={'default': 'A'})
        instructions = sequencer.build()
        self.assertFalse(sequencer.has_finished())
        self.assertEqual(1, len(instructions))

        foo = DummyParameter(value=1.1)
        bar = DummyParameter(value=-0.2)
        sequencer = Sequencer()
        sequencer.push(seqt, {
            'foo': foo,
            'hugo': bar
        },
                       window_mapping=dict(bar='my', foo='thy'),
                       channel_mapping={'default': 'A'})
        instructions = sequencer.build()
        self.assertTrue(sequencer.has_finished())
        self.assertEqual(4, len(instructions.instructions))

        self.assertEqual(instructions[0], MEASInstruction([('my', 2, 2)]))
        self.assertIsInstance(instructions[1], EXECInstruction)
        self.assertEqual(instructions[2], MEASInstruction([('thy', 4, 1)]))
        self.assertIsInstance(instructions[3], EXECInstruction)