import unittest

from analogai.foundation.common.design_patterns.chain import ChainHandler, ChainCreator

class FirstHandler(ChainHandler):
    def __init__(self):
        super().__init__()
        self.called = False

    def execute(self, value):
        self.called = True
        return None

class SecondHandler(ChainHandler):
    def __init__(self):
        super().__init__()
        self.called = False

    def execute(self, value):
        self.called = True
        return value * 2

class ThirdHandler(ChainHandler):
    def __init__(self):
        super().__init__()
        self.called = False

    def execute(self, value):
        self.called = True
        return value + 1

class TestChain(unittest.TestCase):
    def test_chain_executes_until_result(self):
        h1 = FirstHandler()
        h2 = SecondHandler()
        h3 = ThirdHandler()
        head = ChainCreator.create([h1, h2, h3])
        result = head.execute(5)
        self.assertTrue(h1.called)
        self.assertTrue(h2.called)
        self.assertFalse(h3.called)
        self.assertEqual(result, 10)

    def test_chain_executes_all_if_none(self):
        class NoneHandler(ChainHandler):
            def __init__(self):
                super().__init__()
                self.called = False
            def execute(self, value):
                self.called = True
                return None
        h1 = NoneHandler()
        h2 = NoneHandler()
        h3 = ThirdHandler()
        head = ChainCreator.create([h1, h2, h3])
        result = head.execute(3)
        self.assertTrue(h1.called)
        self.assertTrue(h2.called)
        self.assertTrue(h3.called)
        self.assertEqual(result, 4)

if __name__ == '__main__':
    unittest.main()


