def test_card_screen_with_background_colour(): """ If a background colour is set for the card, ensure this is correctly configured for the layout associated with the card's screen. """ mock_screen_manager = mock.MagicMock() data_store = {"foo": "bar"} card = Card("title", background="red") mock_layout = mock.MagicMock() with mock.patch( "pypercard.core.BoxLayout", return_value=mock_layout ), mock.patch("pypercard.core.Screen"), mock.patch( "pypercard.core.Color" ) as mock_colour, mock.patch( "pypercard.core.Rectangle" ) as mock_rectangle: card.screen(mock_screen_manager, data_store) mock_layout.bind.assert_called_once_with( size=card._update_rect, pos=card._update_rect ) mock_colour.assert_called_once_with(1.0, 0.0, 0.0, 1.0) # "red" mock_rectangle.assert_called_once_with( size=mock_layout.size, pos=mock_layout.pos ) assert card.rect == mock_rectangle()
def test_card_verify_auto_advance(): """ If the auto_advance value is set, there MUST be an auto_target. """ with pytest.raises(ValueError): Card(title="title", auto_advance=1.0) # Check the good case. Card(title="title", auto_advance=1.0, auto_target="Another card")
def test_card_leave(): """ The _leave method is called when the card is hidden from the user. Ensure that the sound player is stopped. """ card = Card("title") card.player = mock.MagicMock() card._leave(card) card.player.stop.assert_called_once_with()
def test_card_slider_change(): """ Ensure this event handler updates the slider_label with the passed in value. """ card = Card("title") card.slider_label = mock.MagicMock() card._slider_change(None, 10) assert card.slider_label.text == "10.0"
def test_card_form_value_textarea(): """ Return the current value of the textarea widget. """ card = Card("title", form=Inputs.TEXTAREA, text="Form label...") mock_screen_manager = mock.MagicMock() data_store = {} card.screen(mock_screen_manager, data_store) card.textarea.text = "foobarbaz" assert card.form_value() == "foobarbaz"
def test_card_screen_with_form(): """ A card with a form has the expected _draw_form method called to paint it onto the screen. """ mock_screen_manager = mock.MagicMock() data_store = {"foo": "bar"} card = Card("title", form=Inputs.TEXTBOX, text="Form instructions...") card._draw_form = mock.MagicMock() card.screen(mock_screen_manager, data_store) card._draw_form.assert_called_once_with()
def test_card_verify_form_no_text(): """ If there is a form, there must also be text (to act as the form's label / instructions). """ title = "title" form = Inputs.TEXTBOX with pytest.raises(ValueError): Card(title=title, form=form) # Check the good case. Card(title=title, form=form, text="Label for the form.")
def test_card_screen_with_text_only(): """ If the card has only textual content, ensure the _draw_text method is called to paint it onto the screen. """ mock_screen_manager = mock.MagicMock() data_store = {"foo": "bar"} card = Card("title", text="Textual content...") card._draw_text = mock.MagicMock() card.screen(mock_screen_manager, data_store) card._draw_text.assert_called_once_with()
def test_card_screen_empty(): """ Ensure a relatively empty card results in the expected Screen object and the passed in ScreenManager instance and data_store is set for the card. """ mock_screen_manager = mock.MagicMock() data_store = {"foo": "bar"} card = Card("title") result = card.screen(mock_screen_manager, data_store) assert card.screen_manager == mock_screen_manager assert card.data_store == data_store assert isinstance(result, Screen)
def test_card_form_value_slider(): """ Return the current value of the slider widget. """ card = Card( "title", form=Inputs.SLIDER, text="Form label...", options=[1, 100] ) mock_screen_manager = mock.MagicMock() data_store = {} card.screen(mock_screen_manager, data_store) card.slider_label.text = "50" assert card.form_value() == 50.0
def test_cardapp_add_card_title_collision(): """ If the new card's title attribute is already taken, then the application should raise a ValueError. """ app = CardApp() app.screen_manager = mock.MagicMock() card = Card("title") card.screen = mock.MagicMock() app.add_card(card) new_card = Card("title") with pytest.raises(ValueError): app.add_card(new_card)
def test_card_screen_with_buttons(): """ If buttons are configured for the card, ensure the expected _draw_buttons method is called to paint the buttons onto the screen for the card. """ mock_screen_manager = mock.MagicMock() data_store = {"foo": "bar"} card = Card( "title", buttons=[{"label": "A Button", "target": "AnotherButton"}] ) card._draw_buttons = mock.MagicMock() card.screen(mock_screen_manager, data_store) card._draw_buttons.assert_called_once_with()
def test_cardapp_add_card(): """ The referenced card should be added to the app's screen_manager instance and the cards dictionary. """ app = CardApp() app.screen_manager = mock.MagicMock() card = Card("title") card.screen = mock.MagicMock() app.add_card(card) assert app.cards["title"] == card app.screen_manager.add_widget.assert_called_once_with( card.screen(None, None))
def test_card_verify_select_options_not_strings(): """ If the form is a single item selector, the available options MUST be strings. """ title = "title" text = "Instructions for the form." form = Inputs.SELECT options = ("foo", "bar", 123) with pytest.raises(ValueError): Card(title=title, text=text, form=form, options=options) # Check the good case. options = ("foo", "bar", "baz") Card(title=title, text=text, form=form, options=options)
def test_card_verify_multichoice_options_not_strings(): """ If the form is a multi-choice picker, the available options MUST be strings. """ title = "title" text = "Instructions for the form." form = Inputs.MULTICHOICE options = ("foo", "bar", 123) with pytest.raises(ValueError): Card(title=title, text=text, form=form, options=options) # Check the good case. options = ("foo", "bar", "baz") Card(title=title, text=text, form=form, options=options)
def test_card_update_rect(): """ Called whenever the application size changes to ensure that the rectangle that contains the screen to be drawn is also updated in size (so the background colour / image is updated, if required). """ card = Card("title") card.rect = mock.MagicMock() instance = mock.MagicMock() instance.pos = 400 instance.size = 500 card._update_rect(instance, 100) assert card.rect.pos == instance.pos assert card.rect.size == instance.size
def test_card_pre_enter_with_form(): """ The _pre_enter method is called before the card is displayed to the user. Ensure that all textual content is updated with a formatted string with the data_store as potential values. """ card = Card("title") card.text = "Hello {foo}" card.form = Inputs.TEXTBOX card.form_label = mock.MagicMock() card.buttons = [{"label": "Hello {foo}", "target": "AnotherCard"}] card.screen(mock.MagicMock(), {"foo": "world"}) card._pre_enter(card) assert card.form_label.text == "Hello world" assert card.button_widgets[0].text == "Hello world"
def test_card_form_value_select_nothing(): """ Return the current value of the select widget, if none are selected (should return None). """ card = Card( "title", form=Inputs.SELECT, text="Form label...", options=["foo", "bar", "baz"], ) mock_screen_manager = mock.MagicMock() data_store = {} card.screen(mock_screen_manager, data_store) assert card.form_value() is None
def test_card_form_value_select(): """ Return the current value of the select widget. """ card = Card( "title", form=Inputs.SELECT, text="Form label...", options=["foo", "bar", "baz"], ) mock_screen_manager = mock.MagicMock() data_store = {} card.screen(mock_screen_manager, data_store) card.select[0].state = "down" assert card.form_value() == "foo"
def test_card_verify_buttons_missing_attributes(): """ Each dictinary definition of a button MUST contain a label and target attribute. """ title = "title" buttons = [{"label": "Hello"}] with pytest.raises(ValueError): Card(title=title, buttons=buttons) buttons = [{"target": "Target Card"}] with pytest.raises(ValueError): Card(title=title, buttons=buttons) # Check the good case. buttons = [{"label": "Hello", "target": "Target Card"}] Card(title=title, buttons=buttons)
def test_card_screen_with_sound(): """ Ensure that if a sound is associated with a card, that it is instantiated and configured correctly as part of the screen generation process. """ mock_screen_manager = mock.MagicMock() data_store = {"foo": "bar"} card = Card("title", sound="music.wav", sound_repeat=True) mock_loader = mock.MagicMock() with mock.patch("pypercard.core.SoundLoader.load", mock_loader): card.screen(mock_screen_manager, data_store) mock_loader.assert_called_once_with("music.wav") mock_player = mock_loader() assert mock_player.loop is True assert card.player == mock_player
def test_card_verify_slider_options_numeric(): """ If the form is a slider, the options must contain values that are numeric. """ title = "title" text = "Instructions for the form." form = Inputs.SLIDER options = (1, 100, "hello") with pytest.raises(ValueError): Card(title=title, text=text, form=form, options=options) options = (0.1, 0.9, "hello") with pytest.raises(ValueError): Card(title=title, text=text, form=form, options=options) # Check the good case. options = (0.1, 1) Card(title=title, text=text, form=form, options=options)
def test_card_form_value_multichoice(): """ Return the current value of the multichoice widget. """ card = Card( "title", form=Inputs.MULTICHOICE, text="Form label...", options=["foo", "bar", "baz"], ) mock_screen_manager = mock.MagicMock() data_store = {} card.screen(mock_screen_manager, data_store) card.multichoice[0].state = "down" card.multichoice[2].state = "down" assert card.form_value() == ["foo", "baz"]
def test_card_verify_slider_options_size(): """ If the form is a slider, the options must contain the correct number of items (at least two, no more than three). """ title = "title" text = "Instructions for the form." form = Inputs.SLIDER options = (1,) with pytest.raises(ValueError): Card(title=title, text=text, form=form, options=options) options = (1, 2, 3, 4) with pytest.raises(ValueError): Card(title=title, text=text, form=form, options=options) # Check the good case. options = (1, 100, 10) Card(title=title, text=text, form=form, options=options)
def test_card_verify_buttons_not_dict(): """ The definitions of buttons must be expressed as dictionaries. """ title = "title" buttons = ["not a dictionary"] with pytest.raises(ValueError): Card(title=title, buttons=buttons)
def test_card_screen_with_background_image(): """ If a background image is set for the card, ensure this is correctly configured for the layout associated with the card's screen. """ mock_screen_manager = mock.MagicMock() data_store = {"foo": "bar"} card = Card("title", background="image.png") mock_layout = mock.MagicMock() with mock.patch("pypercard.core.BoxLayout", return_value=mock_layout), mock.patch( "pypercard.core.Screen"), mock.patch( "pypercard.core.Rectangle") as mock_rectangle: card.screen(mock_screen_manager, data_store) mock_rectangle.assert_called_once_with(source="image.png", size=mock_layout.size, pos=mock_layout.pos)
def test_card_verify_buttons_attribute_values(): """ Each attribute of the button must be of a certain type: * labels must be strings. * targets must be either strings or callable. """ title = "title" buttons = [{"label": 42, "target": "Target Card"}] with pytest.raises(ValueError): Card(title=title, buttons=buttons) title = "title" buttons = [{"label": "Hello", "target": True}] with pytest.raises(ValueError): Card(title=title, buttons=buttons) # Check the good case. buttons = [{"label": "Hello", "target": lambda x: x}] Card(title=title, buttons=buttons)
def test_card_verify_slider_options(): """ If the form is a slider, there must be an options list containing the min, max and (optional) step values. """ title = "title" text = "Instructions for the form." form = Inputs.SLIDER with pytest.raises(ValueError): Card(title=title, text=text, form=form)
def test_card_next_card_with_string(): """ Ensure the string value set as the auto_target is used to transition the screen manager. """ card = Card("title") card.data_store = {} card.form_value = mock.MagicMock(return_value=None) card.auto_target = "AnotherCard" card.screen_manager = mock.MagicMock() card._next_card(0.1) assert card.screen_manager.current == "AnotherCard"
def test_card_verify_select_options(): """ If the form is a single item selector, there must be a list of options from which to choose an item. """ title = "title" text = "Instructions for the form." form = Inputs.SELECT with pytest.raises(ValueError): Card(title=title, text=text, form=form)