def test_configure_with_breakpoints(self):
     xs = LineGenerator("x", "mm", 0.0, 0.5, 3, alternate=True)
     ys = LineGenerator("y", "mm", 0.0, 0.1, 2)
     generator = CompoundGenerator([ys, xs], [], [], 0.1)
     generator.prepare()
     completed_steps = 0
     steps_to_do = 3
     info = ExposureDeadtimeInfo(0.01, 1000, 0.0)
     part_info = dict(anyname=[info])
     self.set_attributes(self.child, triggerMode="Internal")
     self.o.on_configure(
         self.context,
         completed_steps,
         steps_to_do,
         part_info,
         generator,
         fileDir="/tmp",
         breakpoints=[3, 3],
         exposure=info.calculate_exposure(generator.duration),
     )
     assert self.child.handled_requests.mock_calls == [
         call.put("arrayCallbacks", True),
         call.put("arrayCounter", 0),
         call.put("exposure", 0.1 - 0.01 - 0.0001),
         call.put("imageMode", "Multiple"),
         call.put("numImages", 3),
         call.put("acquirePeriod", 0.1 - 0.0001),
     ]
     assert not self.o.is_hardware_triggered
class TestDetectorDriverPartNestedConfigure(TestDetectorDriverPart):
    def setUp(self):
        super().setUp()
        # In this case we only move x and expect energy to be moved in between runs
        outer = LineGenerator("energy", "keV", 10.0, 11.0, 5)
        self.steps_to_do = 10
        inner = LineGenerator("x", "mm", 0.0, 0.5, self.steps_to_do)
        self.generator = CompoundGenerator([outer, inner], [], [], 0.1)
        self.generator.prepare()
        self.completed_steps = 0
        self.info = ExposureDeadtimeInfo(0.01, 1000, 0.0)
        self.part_info = dict(anyname=[self.info])

    def configure(self):
        self.o.on_configure(
            self.context,
            self.completed_steps,
            self.steps_to_do,
            self.part_info,
            self.generator,
            fileDir="/tmp",
            exposure=self.info.calculate_exposure(self.generator.duration),
        )

    def test_nested_configure(self):
        self.set_attributes(self.child, triggerMode="Internal")
        self.configure()
        # When not hardware triggered we set numImages for the inner scan only
        assert self.child.handled_requests.mock_calls == [
            call.put("arrayCallbacks", True),
            call.put("arrayCounter", 0),
            call.put("exposure", 0.1 - 0.01 - 0.0001),
            call.put("imageMode", "Multiple"),
            call.put("numImages", 10),
            call.put("acquirePeriod", 0.1 - 0.0001),
        ]

    def test_nested_hardware_triggered_configure(self):
        self.set_attributes(self.child, triggerMode="External")
        self.configure()
        # When hardware triggered we set numImages to the total frames and call start
        assert self.child.handled_requests.mock_calls == [
            call.put("arrayCallbacks", True),
            call.put("arrayCounter", 0),
            call.put("exposure", 0.1 - 0.01 - 0.0001),
            call.put("imageMode", "Multiple"),
            call.put("numImages", 50),
            call.put("acquirePeriod", 0.1 - 0.0001),
            call.post("start"),
            call.when_value_matches("acquiring", True, None),
        ]
    def test_seek_with_hardware_trigger_and_breakpoints(self):
        self.o.is_hardware_triggered = True
        # Calling seek after 10 completed steps with 10 left until a breakpoint
        self.o.done_when_reaches = 10

        # Build our seek parameters
        xs = LineGenerator("x", "mm", 0.0, 0.5, 20, alternate=True)
        ys = LineGenerator("y", "mm", 0.0, 0.1, 3)
        generator = CompoundGenerator([ys, xs], [], [], 0.1)
        generator.prepare()
        completed_steps = 10
        steps_to_do = 10
        info = ExposureDeadtimeInfo(0.01, 1000, 0.0)
        part_info = dict(anyname=[info])
        breakpoints = [20, 20, 20]

        self.o.on_seek(
            self.context,
            completed_steps,
            steps_to_do,
            part_info,
            generator,
            fileDir="/tmp",
            breakpoints=breakpoints,
            exposure=info.calculate_exposure(generator.duration),
        )

        # Check we got the right calls to setup the driver
        assert self.child.handled_requests.mock_calls == [
            call.put("arrayCallbacks", True),
            call.put("arrayCounter", 10),
            call.put("exposure", 0.1 - 0.01 - 0.0001),
            call.put("imageMode", "Multiple"),
            call.put("numImages", 10),
            call.put("acquirePeriod", 0.1 - 0.0001),
            call.post("start"),
            call.when_value_matches("acquiring", True, None),
        ]
        assert self.o.done_when_reaches == 20
        assert len(self.context._subscriptions) == 0