def test_fx_bad_substitution(self): content = textwrap.dedent(""" Scene ~~~~~ Shot ---- .. fx:: turberfield.dialogue.sequences.battle_royal barks/|P_NONE|/surprise.wav :offset: 0 :duration: 3000 :loop: 1 """) ensemble = copy.deepcopy(PropertyDirectiveTests.personae) script = SceneScript("inline", doc=SceneScript.read(content)) script.cast(script.select([ensemble[0]])) model = script.run() shot, cue = next(iter(model)) self.assertEqual("turberfield.dialogue.sequences.battle_royal", cue.package) self.assertEqual("barks//surprise.wav", cue.resource) self.assertEqual(0, cue.offset) self.assertEqual(3000, cue.duration) self.assertEqual(1, cue.loop)
def test_entitys_with_declared_state_and_content(self): content = textwrap.dedent(""" .. entity:: FIGHTER_1 .. entity:: FIGHTER_2 :types: turberfield.dialogue.test.test_battle.CastingTests.Animal :states: Aggression.angry Contentment.sad .. entity:: WEAPON A weapon which makes a noise in use. """) doc = SceneScript.read(content) for n, obj in enumerate(doc): with self.subTest(n=n): self.assertIsInstance(obj, Entity.Declaration) self.assertTrue(obj["names"]) if n == 0: self.assertFalse(obj["content"]) elif n == 1: self.assertEqual([ "turberfield.dialogue.test.test_battle.CastingTests.Animal" ], obj["options"]["types"]) self.assertEqual(["Aggression.angry", "Contentment.sad"], obj["options"]["states"]) self.assertFalse(obj["content"]) elif n == 2: self.assertTrue(obj["content"])
def test_fx_video(self): content = textwrap.dedent(""" Scene ~~~~~ Shot ---- .. fx:: turberfield.dialogue.sequences.battle_royal whack.{0} :offset: 0 :duration: 3000 :loop: 1 :label: A clip of someone getting whacked :height: 720 :poster: http://soundcloud.com/abcdef/cover.jpg :url: http://soundcloud.com/abcdef/ :width: 1080 """) for suffix in ("mp4", "ogv", "webm"): with self.subTest(suffix=suffix): text = content.format(suffix) script = SceneScript("inline", doc=SceneScript.read(text)) model = script.run() shot, cue = next(iter(model)) self.assertIsInstance(cue, Model.Video) self.assertEqual("turberfield.dialogue.sequences.battle_royal", cue.package) self.assertEqual("whack.{0}".format(suffix), cue.resource) self.assertEqual(0, cue.offset) self.assertEqual(3000, cue.duration) self.assertEqual(1, cue.loop) self.assertEqual(720, cue.height) self.assertEqual(1080, cue.width)
def test_fx_audio(self): content = textwrap.dedent(""" Scene ~~~~~ Shot ---- .. fx:: turberfield.dialogue.sequences.battle_royal whack.{0} :offset: 0 :duration: 3000 :loop: 1 """) for suffix in ("mp3", ".oga", "ogg", "wav"): with self.subTest(suffix=suffix): text = content.format(suffix) script = SceneScript("inline", doc=SceneScript.read(text)) model = script.run() shot, cue = next(iter(model)) self.assertIsInstance(cue, Model.Audio) self.assertEqual("turberfield.dialogue.sequences.battle_royal", cue.package) self.assertEqual("whack.{0}".format(suffix), cue.resource) self.assertEqual(0, cue.offset) self.assertEqual(3000, cue.duration) self.assertEqual(1, cue.loop)
def test_fx_image(self): content = textwrap.dedent(""" Scene ~~~~~ Shot ---- .. fx:: turberfield.dialogue.sequences.battle_royal whack.{0} :offset: 0 :duration: 3000 :loop: 1 :width: 480 """) for suffix in ("jpg", "jpeg", "png"): with self.subTest(suffix=suffix): text = content.format(suffix) script = SceneScript("inline", doc=SceneScript.read(text)) model = script.run() shot, cue = next(iter(model)) self.assertIsInstance(cue, Model.Still) self.assertEqual("turberfield.dialogue.sequences.battle_royal", cue.package) self.assertEqual("whack.{0}".format(suffix), cue.resource) self.assertEqual(0, cue.offset) self.assertEqual(3000, cue.duration) self.assertEqual(1, cue.loop) self.assertIsNone(cue.height) self.assertEqual(480, cue.width)
def test_shot_duplicates_scene(self): content = textwrap.dedent( """ Scene 1 ======= Shot 1 ------ Text Scene 2 ======= Scene 1 ------- Text """) script = SceneScript("inline", doc=SceneScript.read(content)) script.cast(script.select([])) model = list(script.run()) shot, line = next(iter(model)) self.assertEqual("scene 1", shot.scene) self.assertEqual("shot 1", shot.name)
def test_exact_matching(self): content = textwrap.dedent(""" .. entity:: WHATEVER Test exact ~~~~~~~~~~ One --- .. condition:: WHATEVER.value 1 One. Two --- .. condition:: WHATEVER.value 2 Two. """) script = SceneScript("inline", doc=SceneScript.read(content)) selection = script.select([DataObject(value=1)]) self.assertTrue(all(selection.values())) script.cast(selection) model = script.run() conditions = [l for s, l in model if isinstance(l, Model.Condition)] self.assertEqual(2, len(conditions)) self.assertTrue(Performer.allows(conditions[0])) self.assertFalse(Performer.allows(conditions[1]))
def test_property_getter_indent(self): content = textwrap.dedent(""" .. entity:: P Scene ~~~~~ Shot ---- [P]_ Hi, I'm |P_FIRSTNAME|. |P_SURNAME|. .. |P_FIRSTNAME| property:: P.name.firstname .. |P_SURNAME| property:: P.name.surname """) script = SceneScript("inline", doc=SceneScript.read(content)) script.cast(script.select([self.personae[0]])) model = iter(script.run()) shot, line = next(model) self.assertEqual("scene", shot.scene) self.assertEqual("shot", shot.name) self.assertEqual("Hi, I'm William.", line.text) self.assertTrue(line.persona) shot, line = next(model) self.assertTrue(line.persona, line)
def test_hyperlink_body_text(self): content = textwrap.dedent(""" Hyperlinks ========== Standalone ---------- See http://www.python.org for info. Embedded -------- See the `Python site <http://www.python.org>`_ for info. Named ----- See the `Python home page`_ for info. .. _Python home page: http://www.python.org """) script = SceneScript("inline", doc=SceneScript.read(content)) model = script.run() for shot in model.shots: with self.subTest(shot_name=shot.name): self.assertFalse(any(" " in line.text for line in shot.items)) self.assertTrue(all('<a href="http://www.python.org">' in i.html for i in shot.items), shot)
def test_speaker_reset_by_dedent(self): content = textwrap.dedent(""" .. entity:: P Scene ~~~~~ One --- [P]_ I'm speaking. Still speaking. Not any more. """) script = SceneScript("inline", doc=SceneScript.read(content)) script.cast(script.select([self.personae[0]])) model = script.run() one, two, three = list(model) self.assertTrue(one[1].persona) self.assertTrue(two[1].persona) self.assertIsNone(three[1].persona, three)
def test_set_refresh_enabled(self): text = textwrap.dedent(""" .. entity:: THEME_SETTINGS Scene ===== one --- .. property:: THEME_SETTINGS.punchline-states-refresh none two --- .. property:: THEME_SETTINGS.punchline-states-refresh inherit """) theme = Theme() script = SceneScript("inline", doc=SceneScript.read(text)) script.cast(script.select([theme.settings])) model = ModelAssignsStrings(script.fP, script.doc) script.doc.walkabout(model) presenter = Presenter(model) self.assertEqual(2, len(presenter.frames)) presenter.animate(presenter.frames[0]) self.assertEqual("none", theme.refresh_target) presenter.animate(presenter.frames[1]) self.assertEqual("inherit", theme.refresh_target)
def test_single_fx_splits_frame(self): content = textwrap.dedent(""" .. entity:: P Scene ~~~~~ Shot ---- [P]_ |P_FIRSTNAME| says, "{0}". .. fx:: logic slapwhack.wav :offset: 0 :duration: 3000 :loop: 1 [P]_ |P_FIRSTNAME| says, "{0}". .. |P_FIRSTNAME| property:: P.name.firstname """.format("Hello")) script = SceneScript("inline", doc=SceneScript.read(content)) script.cast(script.select(self.ensemble)) rv = list( Handler.frames(None, HandlerTests.dialogue(script.run()), dwell=0.3, pause=1)) self.assertEqual(2, len(rv)) self.assertTrue(all(i for i in rv)) self.assertIsInstance(rv[1][0].dialogue, Model.Audio)
def test_fx_label_substitution(self): content = textwrap.dedent(""" .. entity:: P Scene ~~~~~ Shot ---- .. fx:: turberfield.dialogue.sequences.battle_royal faces/|P_NAME|/surprise.png :offset: 0 :duration: 3000 :label: |P_NAME| looks surprised .. |P_NAME| property:: P.name.firstname """) ensemble = copy.deepcopy(PropertyDirectiveTests.personae) script = SceneScript("inline", doc=SceneScript.read(content)) script.cast(script.select([ensemble[0]])) model = script.run() shot, cue = next(iter(model)) self.assertEqual("turberfield.dialogue.sequences.battle_royal", cue.package) self.assertEqual("faces/William/surprise.png", cue.resource) self.assertEqual(0, cue.offset) self.assertEqual(3000, cue.duration) self.assertEqual("William looks surprised", cue.label)
def test_empty_entitys(self): content = textwrap.dedent(""" .. entity:: FIGHTER_1 .. entity:: FIGHTER_2 .. entity:: WEAPON """) objs = SceneScript.read(content) groups = group_by_type(objs) self.assertEqual(3, len(groups[Entity.Declaration]), groups)
def test_markup_body_text(self): content = textwrap.dedent(""" Markup ====== Emphasis -------- I *keep* telling you. I :emphasis:`keep` telling you. Strong ------ I **keep** telling you. I :strong:`keep` telling you. Preformat --------- I ``keep`` telling you. I :literal:`keep` telling you. """) script = SceneScript("inline", doc=SceneScript.read(content)) model = script.run() for shot in model.shots: with self.subTest(shot_name=shot.name): self.assertTrue(all("keep" in line.text for line in shot.items)) self.assertFalse(any(" " in line.text for line in shot.items), shot) if shot.name.startswith("em"): self.assertTrue( all('<em class="text">' in line.html for line in shot.items)) self.assertTrue( all("</em>" in line.html for line in shot.items)) elif shot.name.startswith("strong"): self.assertTrue( all('<strong class="text">' in line.html for line in shot.items)) self.assertTrue( all("</strong>" in line.html for line in shot.items)) elif shot.name.startswith("pre"): self.assertTrue( all('<pre class="text">' in line.html for line in shot.items)) self.assertTrue( all("</pre>" in line.html for line in shot.items))
def test_select_with_two_roles(self): content = textwrap.dedent(""" .. entity:: CHARACTER_1 :roles: CHARACTER_2 .. entity:: CHARACTER_2 """) ensemble = copy.deepcopy(PropertyDirectiveTests.personae[0:1]) script = SceneScript("inline", doc=SceneScript.read(content)) rv = list(script.select(ensemble, roles=2).values()) self.assertEqual(ensemble[0], rv[0]) self.assertEqual(ensemble[0], rv[1])
def test_property_getter_fields(self): content = textwrap.dedent(""" .. |VERSION| property:: turberfield.dialogue.__version__ :copyright: 2017 :version: |VERSION| """) script = SceneScript("inline", doc=SceneScript.read(content)) script.cast(script.select([self.personae[0]])) model = script.run() metadata = dict(model.metadata) self.assertIn("copyright", metadata) self.assertIn("version", metadata) self.assertEqual(2, metadata["version"].count("."), metadata)
def test_escape_common_characters(self): content = textwrap.dedent(""" Characters ========== Changed ------- $%^©£ """) script = SceneScript("inline", doc=SceneScript.read(content)) model = script.run() line = model.shots[0].items[0] self.assertEqual(5, line.html.count("&"), line.html)
def test_noescape_common_characters(self): content = textwrap.dedent(""" Characters ========== Unchanged --------- !"*()+-:;'.,@#{}=~ """) script = SceneScript("inline", doc=SceneScript.read(content)) model = script.run() line = model.shots[0].items[0] self.assertNotIn("&", line.html)
def test_escape_ampersand(self): content = textwrap.dedent(""" Characters ========== Ampersand --------- Three pints of M&B please. """) script = SceneScript("inline", doc=SceneScript.read(content)) model = script.run() line = model.shots[0].items[0] self.assertIn("M&B", line.html)
def test_missing_citations(self): content = textwrap.dedent(""" [NARRATOR]_ And they lived happily ever after. """) script = SceneScript("inline", doc=SceneScript.read(content)) script.cast(script.select([])) model = list(script.run()) items = list(model) self.assertEqual(1, len(items), items) shot, line = items[0] self.assertIs(None, shot.scene) self.assertIs(None, shot.name) self.assertEqual("narrator", line.persona)
def test_unspoken_footnote_html_to_weasyprint(self): content = textwrap.dedent(""" Don't worry, I'm a doctor [*]_. .. [*] Not a medical doctor. """) script = SceneScript("inline", doc=SceneScript.read(content)) model = script.run() self.assertEqual(1, len(model.shots)) lines = model.shots[0].items self.assertEqual(2, len(lines)) self.assertIn('class="footnote"', lines[-1].html) self.assertIn('role="note"', lines[-1].html) self.assertNotIn("<p>", lines[-1].html) self.assertNotIn("</p>", lines[-1].html)
def build_model(text, theme, uid=None, path: pathlib.Path = None, model_type=ModelAssignsStrings): theme.settings.id = uid or theme.settings.id path = path or pathlib.Path(".") SceneScript.settings.raw_enabled = True SceneScript.settings.file_insertion_enabled = True SceneScript.settings.input_encoding = "utf-8" SceneScript.settings.input_encoding_error_handler = "replace" script = SceneScript(path, doc=SceneScript.read(text)) ensemble = list(Eponymous.create(script)) + [theme.settings] script.cast(script.select(ensemble)) model = model_type(script.fP, script.doc) script.doc.walkabout(model) return model
def test_dialogue_at_level_1(self): content = textwrap.dedent(""" .. entity:: P Scene ===== [P]_ You can call me |P_NICKNAME|. .. |P_NICKNAME| property:: P.nickname """) script = SceneScript("inline", doc=SceneScript.read(content)) script.cast(script.select([self.personae[0]])) model = list(script.run()) self.assertFalse(model)
def test_fx_unknown(self): content = textwrap.dedent(""" Scene ~~~~~ Shot ---- .. fx:: turberfield.dialogue.sequences.battle_royal whack.nomime :offset: 0 :duration: 3000 :loop: 1 """) script = SceneScript("inline", doc=SceneScript.read(content)) model = script.run() self.assertRaises(StopIteration, next, iter(model))
def test_dialogue_at_level_0(self): content = textwrap.dedent(""" .. entity:: P [P]_ You can call me |P_NICKNAME|. .. |P_NICKNAME| property:: P.nickname """) script = SceneScript("inline", doc=SceneScript.read(content)) script.cast(script.select([self.personae[0]])) model = list(script.run()) shot, line = next(iter(model)) self.assertIs(None, shot.scene) self.assertIs(None, shot.name) self.assertIn(line.text, ("You can call me Fuzzer.", "You can call me Q.A."))
def test_raw_html(self): content = textwrap.dedent(""" Scene ===== Shot ---- I know what it needs... .. raw:: html <marquee>Puppies die when you do bad design</marquee> """) script = SceneScript("inline", doc=SceneScript.read(content)) model = script.run() self.assertEqual(2, model.shots[-1].items[-1].html.count("marquee")) self.assertEqual(0, model.shots[-1].items[-1].text.count("marquee"))
def test_frame_from_dialogue(self): content = textwrap.dedent(""" .. entity:: P Scene ~~~~~ Shot ---- [P]_ |P_FIRSTNAME| says, "{0}". .. |P_FIRSTNAME| property:: P.name.firstname """.format("Hello")) script = SceneScript("inline", doc=SceneScript.read(content)) script.cast(script.select(self.ensemble)) rv = Frame.items(FrameTests.dialogue(script.run()), dwell=0.3, pause=1) self.fail(list(rv))
def test_bullet_lists(self): content = textwrap.dedent(""" Scene ===== Shot ---- ABC. * Always * Be * Closing """) script = SceneScript("inline", doc=SceneScript.read(content)) model = script.run() self.assertEqual(["Always", "Be", "Closing"], model.shots[-1].items[-1].text.splitlines()) self.assertEqual(2, model.shots[-1].items[-1].html.count("ul>")) self.assertEqual(6, model.shots[-1].items[-1].html.count("li>"))
def test_property_setter_bad_substitution(self): content = textwrap.dedent(""" .. entity:: P Scene ~~~~~ Shot ---- .. property:: P.state |S_ID| """) ensemble = copy.deepcopy(PropertyDirectiveTests.personae) script = SceneScript("inline", doc=SceneScript.read(content)) script.cast(script.select([ensemble[0]])) model = script.run() p = next(l for s, l in model if isinstance(l, Model.Property)) self.assertEqual("state", p.attr) self.assertIs(None, p.val)