#!/usr/bin/env python # -*- coding: utf-8 -*- import sys from io import StringIO from observer import Subject, Data, DecimalViewer, HexViewer if sys.version_info < (2, 7): import unittest2 as unittest else: import unittest try: from unittest.mock import patch except ImportError: from mock import patch class TestSubject(unittest.TestCase): @classmethod def setUpClass(cls): cls.s = Subject() cls.dec_obs = DecimalViewer() cls.hex_obs = HexViewer() def test_a_observer_list_shall_be_empty_initially(cls): cls.assertEqual(len(cls.s._observers), 0) def test_b_observers_shall_be_attachable(cls): cls.s.attach(cls.dec_obs) cls.assertEqual(isinstance(cls.s._observers[0], DecimalViewer), True) cls.assertEqual(len(cls.s._observers), 1) cls.s.attach(cls.hex_obs) cls.assertEqual(isinstance(cls.s._observers[1], HexViewer), True) cls.assertEqual(len(cls.s._observers), 2) def test_c_observers_shall_be_detachable(cls): cls.s.detach(cls.dec_obs) # hex viewer shall be remaining if dec viewer is detached first cls.assertEqual(isinstance(cls.s._observers[0], HexViewer), True) cls.assertEqual(len(cls.s._observers), 1) cls.s.detach(cls.hex_obs) cls.assertEqual(len(cls.s._observers), 0) class TestData(unittest.TestCase): @classmethod def setUpClass(cls): cls.dec_obs = DecimalViewer() cls.hex_obs = HexViewer() cls.sub = Data('Data') #inherited behavior already tested with TestSubject cls.sub.attach(cls.dec_obs) cls.sub.attach(cls.hex_obs) def test_data_change_shall_notify_all_observers_once(cls): with patch.object(cls.dec_obs, 'update') as mock_dec_obs_update,\ patch.object(cls.hex_obs, 'update') as mock_hex_obs_update: cls.sub.data = 10 cls.assertEqual(mock_dec_obs_update.call_count, 1) cls.assertEqual(mock_hex_obs_update.call_count, 1) def test_data_value_shall_be_changeable(cls): cls.sub.data = 20 cls.assertEqual(cls.sub._data, 20) def test_data_name_shall_be_changeable(cls): cls.sub.name = 'New Data Name' cls.assertEqual(cls.sub.name, 'New Data Name') if __name__ == "__main__": unittest.main()