Skip to content

Commit

Permalink
use only pytest for testing
Browse files Browse the repository at this point in the history
pytest is clearly the preferred tool for testing in Python.
  • Loading branch information
FelixSchwarz committed Nov 21, 2023
1 parent d53b00c commit 70e072f
Show file tree
Hide file tree
Showing 10 changed files with 249 additions and 280 deletions.
1 change: 0 additions & 1 deletion .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ jobs:
- name: Install dependencies
run: |
pip install -e .[testing]
pip install pytest
- name: Run test suite
run: |
Expand Down
27 changes: 12 additions & 15 deletions mjml/lib/tests/dict_merger_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,20 @@
# Copyright 2015 Felix Schwarz
# The source code in this file is licensed under the MIT license.

from pythonic_testcase import *

from ..dict_merger import merge_dicts


class DictMergerTest(PythonicTestCase):
def test_returns_single_dict_unmodified(self):
assert_equals({}, merge_dicts({}))
assert_equals({'bar': 42}, merge_dicts({'bar': 42}))
def test_returns_single_dict_unmodified():
assert merge_dicts({}) == {}
assert merge_dicts({'bar': 42}) == {'bar': 42}

def test_can_merge_two_dicts_without_modifying_inputs(self):
a = {'a': 1}
b = {'b': 2}
assert_equals({'a': 1, 'b': 2}, merge_dicts(a, b))
def test_can_merge_two_dicts_without_modifying_inputs():
a = {'a': 1}
b = {'b': 2}
assert merge_dicts(a, b) == {'a': 1, 'b': 2}

def test_can_merge_three_dicts_without_modifying_inputs(self):
a = {'a': 1}
b = {'b': 2}
c = {'c': 3}
assert_equals({'a': 1, 'b': 2, 'c': 3}, merge_dicts(a, b, c))
def test_can_merge_three_dicts_without_modifying_inputs():
a = {'a': 1}
b = {'b': 2}
c = {'c': 3}
assert merge_dicts(a, b, c) == {'a': 1, 'b': 2, 'c': 3}
3 changes: 1 addition & 2 deletions setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -54,11 +54,10 @@ exclude =

[options.extras_require]
testing =
ddt
FakeFSHelpers
HTMLCompare >= 0.3.0 # >= 0.3.0: ability to ignore attribute ordering in HTML
lxml
PythonicTestcase
pytest
css_inlining =
css_inline >= 0.11, < 0.12 # >= 0.11, < 0.12: CSSInliner(inline_style_tags=..., keep_link_tags=..., keep_style_tags=...)

Expand Down
7 changes: 2 additions & 5 deletions tests/border_parser_test.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@

from unittest import TestCase

from mjml.helpers import borderParser


class BorderParserTest(TestCase):
def test_can_parse_css_none(self):
self.assertEqual(0, borderParser('none'))
def test_can_parse_css_none():
assert borderParser('none') == 0
17 changes: 7 additions & 10 deletions tests/custom_components_test.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@

from unittest import TestCase

from htmlcompare import assert_same_html

from mjml import mjml_to_html
Expand Down Expand Up @@ -33,12 +31,11 @@ def render(self):
return f'<div>***</div>{content}<div>***</div>'


class CustomComponentsTest(TestCase):
def test_custom_components(self):
expected_html = load_expected_html('_custom')
with get_mjml_fp('_custom') as mjml_fp:
result_list = mjml_to_html(mjml_fp, custom_components=[MjTextCustom, MjTextOverride])
def test_custom_components():
expected_html = load_expected_html('_custom')
with get_mjml_fp('_custom') as mjml_fp:
result_list = mjml_to_html(mjml_fp, custom_components=[MjTextCustom, MjTextOverride])

assert not result_list.errors
list_actual_html = result_list.html
assert_same_html(expected_html, list_actual_html, verbose=True)
assert not result_list.errors
list_actual_html = result_list.html
assert_same_html(expected_html, list_actual_html, verbose=True)
55 changes: 30 additions & 25 deletions tests/includes_with_umlauts_test.py
Original file line number Diff line number Diff line change
@@ -1,33 +1,38 @@

from io import StringIO
from unittest import TestCase

import pytest
from schwarz.fakefs_helpers import FakeFS

from mjml import mjml_to_html


class IncludesWithUmlautsTest(TestCase):
def test_can_properly_handle_include_umlauts(self):
fs = FakeFS.set_up(test=self)
included_mjml = (
'<mj-section>'
' <mj-column>'
' <mj-text>äöüß</mj-text>'
' </mj-column>'
'</mj-section>'
)
mjml = (
'<mjml>'
' <mj-body>'
' <mj-text>foo bar</mj-text>'
' <mj-include path="./footer.mjml" />'
' </mj-body>'
'</mjml>'
)
fs.create_file('footer.mjml', contents=included_mjml.encode('utf8'))

result = mjml_to_html(StringIO(mjml))
html = result.html

assert ('äöüß' in html)
@pytest.fixture
def fs():
_fs = FakeFS.set_up()
yield _fs
_fs.tear_down()


def test_can_properly_handle_include_umlauts(fs):
included_mjml = (
'<mj-section>'
' <mj-column>'
' <mj-text>äöüß</mj-text>'
' </mj-column>'
'</mj-section>'
)
mjml = (
'<mjml>'
' <mj-body>'
' <mj-text>foo bar</mj-text>'
' <mj-include path="./footer.mjml" />'
' </mj-body>'
'</mjml>'
)
fs.create_file('footer.mjml', contents=included_mjml.encode('utf8'))

result = mjml_to_html(StringIO(mjml))
html = result.html

assert ('äöüß' in html)
56 changes: 16 additions & 40 deletions tests/missing_functionality_test.py
Original file line number Diff line number Diff line change
@@ -1,50 +1,26 @@

from pathlib import Path
from unittest import TestCase, expectedFailure

from ddt import data as ddt_data, ddt as DataDrivenTestCase
import pytest
from htmlcompare import assert_same_html

from mjml import mjml_to_html


TESTDATA_DIR = Path(__file__).parent / 'missing_functionality'

def patch_nose1(func):
def _wrapper(test, *args, **kwargs):
_patch_nose1_result(test)
return func(test, *args, **kwargs)
return _wrapper


@DataDrivenTestCase
class MissingFeaturesTest(TestCase):
@ddt_data(
)
@expectedFailure
@patch_nose1
def test_ensure_same_html(self, test_id):
mjml_filename = f'{test_id}.mjml'
html_filename = f'{test_id}-expected.html'
with (TESTDATA_DIR / html_filename).open('rb') as html_fp:
expected_html = html_fp.read()

with (TESTDATA_DIR / mjml_filename).open('rb') as mjml_fp:
result = mjml_to_html(mjml_fp)

assert not result.errors
actual_html = result.html
assert_same_html(expected_html, actual_html, verbose=True)


def _patch_nose1_result(test):
# nose's TextTestResult does not support "expected failures" but I still
# like that test runner. Just treat an expected failure like a skipped test.
result = test._outcome.result
if not hasattr(result, 'addExpectedFailure'):
result.addExpectedFailure = result.addSkip
if not hasattr(result, 'addUnexpectedSuccess'):
def _addUnexpectedSuccess(test):
error = (AssertionError, AssertionError('unexpected success'), None)
return result.addFailure(test, error)
result.addUnexpectedSuccess = _addUnexpectedSuccess
# currently there are no tests which are expected to fail
@pytest.mark.parametrize('test_id', [])
@pytest.mark.xfail
def test_missing_functionality(test_id):
mjml_filename = f'{test_id}.mjml'
html_filename = f'{test_id}-expected.html'
with (TESTDATA_DIR / html_filename).open('rb') as html_fp:
expected_html = html_fp.read()

with (TESTDATA_DIR / mjml_filename).open('rb') as mjml_fp:
result = mjml_to_html(mjml_fp)

assert not result.errors
actual_html = result.html
assert_same_html(expected_html, actual_html, verbose=True)
46 changes: 22 additions & 24 deletions tests/mj_button_mailto_link_test.py
Original file line number Diff line number Diff line change
@@ -1,35 +1,33 @@

import re
from io import StringIO
from unittest import TestCase

import lxml.html

from mjml import mjml_to_html


class MjButtonMailtoLinkTest(TestCase):
def test_no_target_for_mailto_links(self):
mjml = (
'<mjml>'
' <mj-body>'
' <mj-button href="mailto:foo@site.example">Click me</mj-button>'
' </mj-body>'
'</mjml>'
)
def test_no_target_for_mailto_links():
mjml = (
'<mjml>'
' <mj-body>'
' <mj-button href="mailto:foo@site.example">Click me</mj-button>'
' </mj-body>'
'</mjml>'
)

result = mjml_to_html(StringIO(mjml))
html = result.html
mailto_match = re.search('<a href="([^"]+?)"[^>]*>', html)
start, end = mailto_match.span()
match_str = html[start:end]
result = mjml_to_html(StringIO(mjml))
html = result.html
mailto_match = re.search('<a href="([^"]+?)"[^>]*>', html)
start, end = mailto_match.span()
match_str = html[start:end]

a_el = lxml.html.fragment_fromstring(match_str)
self.assertEqual('mailto:foo@site.example', a_el.attrib['href'])
target = a_el.attrib.get('target')
# Thunderbird opens a blank page instead of the new message window if
# the <a> contains 'target="_blank"'.
# https://bugzilla.mozilla.org/show_bug.cgi?id=1677248
# https://bugzilla.mozilla.org/show_bug.cgi?id=1589968
# https://bugzilla.mozilla.org/show_bug.cgi?id=421310
assert not target, f'target="{target}"'
a_el = lxml.html.fragment_fromstring(match_str)
assert a_el.attrib['href'] == 'mailto:foo@site.example'
target = a_el.attrib.get('target')
# Thunderbird opens a blank page instead of the new message window if
# the <a> contains 'target="_blank"'.
# https://bugzilla.mozilla.org/show_bug.cgi?id=1677248
# https://bugzilla.mozilla.org/show_bug.cgi?id=1589968
# https://bugzilla.mozilla.org/show_bug.cgi?id=421310
assert not target, f'target="{target}"'
20 changes: 9 additions & 11 deletions tests/mjml2html_test.py
Original file line number Diff line number Diff line change
@@ -1,17 +1,15 @@

from io import StringIO
from unittest import TestCase

from mjml import mjml_to_html


class MJML2HTMLTest(TestCase):
def test_can_handle_comments_in_mjml(self):
mjml = (
'<mjml>'
' <mj-body>'
' <!-- empty -->'
' </mj-body>'
'</mjml>'
)
mjml_to_html(StringIO(mjml))
def test_can_handle_comments_in_mjml():
mjml = (
'<mjml>'
' <mj-body>'
' <!-- empty -->'
' </mj-body>'
'</mjml>'
)
mjml_to_html(StringIO(mjml))

0 comments on commit 70e072f

Please sign in to comment.