mirror of
				https://github.com/ethereum/solidity
				synced 2023-10-03 13:03:40 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			509 lines
		
	
	
		
			19 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			509 lines
		
	
	
		
			19 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
#!/usr/bin/env python3
 | 
						|
 | 
						|
from textwrap import dedent
 | 
						|
import json
 | 
						|
import unittest
 | 
						|
 | 
						|
from unittest_helpers import FIXTURE_DIR, load_fixture
 | 
						|
 | 
						|
# NOTE: This test file file only works with scripts/ added to PYTHONPATH so pylint can't find the imports
 | 
						|
# pragma pylint: disable=import-error
 | 
						|
from externalTests.benchmark_diff import BenchmarkDiffer, DifferenceStyle, DiffTableSet, DiffTableFormatter, OutputFormat
 | 
						|
# pragma pylint: enable=import-error
 | 
						|
 | 
						|
SUMMARIZED_BENCHMARKS_DEVELOP_JSON_PATH = FIXTURE_DIR / 'summarized-benchmarks-develop.json'
 | 
						|
SUMMARIZED_BENCHMARKS_BRANCH_JSON_PATH = FIXTURE_DIR / 'summarized-benchmarks-branch.json'
 | 
						|
 | 
						|
SUMMARIZED_DIFF_HUMANIZED_MD_PATH = FIXTURE_DIR / 'summarized-benchmark-diff-develop-branch-humanized.md'
 | 
						|
SUMMARIZED_DIFF_HUMANIZED_MD = load_fixture(SUMMARIZED_DIFF_HUMANIZED_MD_PATH)
 | 
						|
 | 
						|
 | 
						|
class TestBenchmarkDiff(unittest.TestCase):
 | 
						|
    def setUp(self):
 | 
						|
        self.maxDiff = 10000
 | 
						|
 | 
						|
    def test_benchmark_diff(self):
 | 
						|
        report_before = json.loads(load_fixture(SUMMARIZED_BENCHMARKS_DEVELOP_JSON_PATH))
 | 
						|
        report_after = json.loads(load_fixture(SUMMARIZED_BENCHMARKS_BRANCH_JSON_PATH))
 | 
						|
        expected_diff = {
 | 
						|
            "bleeps": {
 | 
						|
                "ir-optimize-evm+yul": {
 | 
						|
                    # Numerical difference -> negative/positive/zero.
 | 
						|
                    # Zeros are not skipped to differentiate them from missing values.
 | 
						|
                    "bytecode_size": 132868 - 132165,
 | 
						|
                    "deployment_gas": 0,
 | 
						|
                    "method_gas": 39289198 - 39289935,
 | 
						|
                },
 | 
						|
                "legacy-optimize-evm+yul": {
 | 
						|
                    # No differences within preset -> zeros still present.
 | 
						|
                    "bytecode_size": 0,
 | 
						|
                    "deployment_gas": 0,
 | 
						|
                    "method_gas": 0,
 | 
						|
                },
 | 
						|
            },
 | 
						|
            "colony": {
 | 
						|
                # Preset missing on one side -> replace dict with string
 | 
						|
                "ir-optimize-evm+yul": "!A",
 | 
						|
                "legacy-no-optimize": "!B",
 | 
						|
                "legacy-optimize-evm+yul": {
 | 
						|
                    "bytecode_size": 0,
 | 
						|
                    # Attribute missing on both sides -> skip
 | 
						|
                    #"deployment_gas":
 | 
						|
                    #"method_gas":
 | 
						|
                },
 | 
						|
            },
 | 
						|
            "elementfi": {
 | 
						|
                "legacy-no-optimize": {
 | 
						|
                    # Attributes null on one side -> replace value with string
 | 
						|
                    "bytecode_size": "!A",
 | 
						|
                    "deployment_gas": "!B",
 | 
						|
                    # Attribute null on both sides -> skip
 | 
						|
                    #"method_gas":
 | 
						|
                },
 | 
						|
                "legacy-optimize-evm+yul": {
 | 
						|
                    # Attributes missing on one side -> replace value with string
 | 
						|
                    "bytecode_size": "!A",
 | 
						|
                    "deployment_gas": "!B",
 | 
						|
                    # Attribute missing on both sides -> skip
 | 
						|
                    #"method_gas":
 | 
						|
                },
 | 
						|
                "ir-no-optimize": {
 | 
						|
                    # Attributes missing on one side, null on the other -> skip
 | 
						|
                    #"bytecode_size":
 | 
						|
                    #"deployment_gas":
 | 
						|
                    "method_gas": 0,
 | 
						|
                },
 | 
						|
                # Empty preset missing on one side -> replace dict with string
 | 
						|
                "legacy-optimize-evm-only": "!A",
 | 
						|
                "ir-optimize-evm-only": "!B",
 | 
						|
            },
 | 
						|
            "euler": {
 | 
						|
                # Matching versions -> show attributes, skip version
 | 
						|
                "ir-no-optimize": {
 | 
						|
                    "bytecode_size": 328540 - 323909,
 | 
						|
                    "deployment_gas": 0,
 | 
						|
                    "method_gas": 3537419168 - 3452105184,
 | 
						|
                },
 | 
						|
                # Different versions, different values -> replace whole preset with string
 | 
						|
                "legacy-no-optimize": "!V",
 | 
						|
                # Different versions, same values -> replace whole preset with string
 | 
						|
                "legacy-optimize-evm+yul": "!V",
 | 
						|
                # Different versions (not a commit hash), different values -> replace whole preset with string
 | 
						|
                "legacy-optimize-evm-only": "!V",
 | 
						|
                # Version missing on one side -> replace whole preset with string
 | 
						|
                "ir-optimize-evm-only": "!V",
 | 
						|
                # Version missing on both sides -> assume same version
 | 
						|
                "ir-optimize-evm+yul": {
 | 
						|
                    "bytecode_size": 205211 - 182190,
 | 
						|
                    "deployment_gas": 39459629 - 35236828,
 | 
						|
                    "method_gas": 0,
 | 
						|
                },
 | 
						|
            },
 | 
						|
            "zeppelin": {
 | 
						|
                "legacy-optimize-evm+yul": {
 | 
						|
                    # Whole project identical -> attributes still present, with zeros
 | 
						|
                    "bytecode_size": 0,
 | 
						|
                    "deployment_gas": 0,
 | 
						|
                    # Field missing on both sides -> skip
 | 
						|
                    #"method_gas":
 | 
						|
                }
 | 
						|
            },
 | 
						|
            # Empty project missing on one side -> replace its dict with a string
 | 
						|
            "gnosis": "!B",
 | 
						|
            "ens": "!A",
 | 
						|
        }
 | 
						|
        differ = BenchmarkDiffer(DifferenceStyle.ABSOLUTE, None, OutputFormat.JSON)
 | 
						|
        self.assertEqual(differ.run(report_before, report_after), expected_diff)
 | 
						|
 | 
						|
 | 
						|
class TestBenchmarkDiffer(unittest.TestCase):
 | 
						|
    def setUp(self):
 | 
						|
        self.maxDiff = 10000
 | 
						|
 | 
						|
    @staticmethod
 | 
						|
    def _nest(value, levels):
 | 
						|
        nested_value = value
 | 
						|
        for level in levels:
 | 
						|
            nested_value = {level: nested_value}
 | 
						|
 | 
						|
        return nested_value
 | 
						|
 | 
						|
    def _assert_single_value_diff_matches(self, differ, cases, nest_result=True, nestings=None):
 | 
						|
        if nestings is None:
 | 
						|
            nestings = [[], ['p'], ['p', 's'], ['p', 's', 'a']]
 | 
						|
 | 
						|
        for levels in nestings:
 | 
						|
            for (before, after, expected_diff) in cases:
 | 
						|
                self.assertEqual(
 | 
						|
                    differ.run(self._nest(before, levels), self._nest(after, levels)),
 | 
						|
                    self._nest(expected_diff, levels) if nest_result else expected_diff,
 | 
						|
                    f'Wrong diff for {self._nest(before, levels)} vs {self._nest(after, levels)}'
 | 
						|
                )
 | 
						|
 | 
						|
    def test_empty(self):
 | 
						|
        for style in DifferenceStyle:
 | 
						|
            differ = BenchmarkDiffer(style, None, OutputFormat.JSON)
 | 
						|
            self._assert_single_value_diff_matches(differ, [({}, {}, {})], nest_result=False)
 | 
						|
 | 
						|
    def test_null(self):
 | 
						|
        for style in DifferenceStyle:
 | 
						|
            differ = BenchmarkDiffer(style, None, OutputFormat.JSON)
 | 
						|
            self._assert_single_value_diff_matches(differ, [(None, None, {})], nest_result=False)
 | 
						|
 | 
						|
    def test_number_diff_absolute_json(self):
 | 
						|
        for output_format in OutputFormat:
 | 
						|
            self._assert_single_value_diff_matches(
 | 
						|
                BenchmarkDiffer(DifferenceStyle.ABSOLUTE, 4, output_format),
 | 
						|
                [
 | 
						|
                    (2,   2,    0),
 | 
						|
                    (2,   5,    3),
 | 
						|
                    (5,   2,   -3),
 | 
						|
                    (2.0, 2.0,  0),
 | 
						|
                    (2,   2.0,  0),
 | 
						|
                    (2.0, 2,    0),
 | 
						|
                    (2,   2.5,  2.5 - 2),
 | 
						|
                    (2.5, 2,    2 - 2.5),
 | 
						|
 | 
						|
                    (0,   0,    0),
 | 
						|
                    (0,   2,    2),
 | 
						|
                    (0,   -2,  -2),
 | 
						|
 | 
						|
                    (-3, -1,    2),
 | 
						|
                    (-1, -3,   -2),
 | 
						|
                    (2,   0,   -2),
 | 
						|
                    (-2,  0,    2),
 | 
						|
 | 
						|
                    (1.00006, 1,  1 - 1.00006),
 | 
						|
                    (1, 1.00006,  1.00006 - 1),
 | 
						|
                    (1.00004, 1, 1 - 1.00004),
 | 
						|
                    (1, 1.00004, 1.00004 - 1),
 | 
						|
                ],
 | 
						|
            )
 | 
						|
 | 
						|
    def test_number_diff_json(self):
 | 
						|
        for output_format in OutputFormat:
 | 
						|
            self._assert_single_value_diff_matches(
 | 
						|
                BenchmarkDiffer(DifferenceStyle.RELATIVE, 4, output_format),
 | 
						|
                [
 | 
						|
                    (2,   2,   0),
 | 
						|
                    (2,   5,   (5 - 2) / 2),
 | 
						|
                    (5,   2,   (2 - 5) / 5),
 | 
						|
                    (2.0, 2.0, 0),
 | 
						|
                    (2,   2.0, 0),
 | 
						|
                    (2.0, 2,   0),
 | 
						|
                    (2,   2.5, (2.5 - 2) / 2),
 | 
						|
                    (2.5, 2,   (2 - 2.5) / 2.5),
 | 
						|
 | 
						|
                    (0,   0,   0),
 | 
						|
                    (0,   2,   '+INF'),
 | 
						|
                    (0,   -2,  '-INF'),
 | 
						|
 | 
						|
                    (-3, -1,   0.6667),
 | 
						|
                    (-1, -3,  -2),
 | 
						|
                    (2,   0,  -1),
 | 
						|
                    (-2,  0,   1),
 | 
						|
 | 
						|
                    (1.00006, 1,   -0.0001),
 | 
						|
                    (1, 1.00006,    0.0001),
 | 
						|
                    (1.000004, 1, '-0'),
 | 
						|
                    (1, 1.000004, '+0'),
 | 
						|
                ],
 | 
						|
            )
 | 
						|
 | 
						|
    def test_number_diff_humanized_json_and_console(self):
 | 
						|
        for output_format in [OutputFormat.JSON, OutputFormat.CONSOLE]:
 | 
						|
            self._assert_single_value_diff_matches(
 | 
						|
                BenchmarkDiffer(DifferenceStyle.HUMANIZED, 4, output_format),
 | 
						|
                [
 | 
						|
                    (2,   2,      '0%'),
 | 
						|
                    (2,   5,   '+150%'),
 | 
						|
                    (5,   2,    '-60%'),
 | 
						|
                    (2.0, 2.0,    '0%'),
 | 
						|
                    (2,   2.0,    '0%'),
 | 
						|
                    (2.0, 2,      '0%'),
 | 
						|
                    (2,   2.5,  '+25%'),
 | 
						|
                    (2.5, 2,    '-20%'),
 | 
						|
 | 
						|
                    (0,   0,      '0%'),
 | 
						|
                    (0,   2,   '+INF%'),
 | 
						|
                    (0,   -2,  '-INF%'),
 | 
						|
 | 
						|
                    (-3, -1, '+66.67%'),
 | 
						|
                    (-1, -3,   '-200%'),
 | 
						|
                    (2,   0,   '-100%'),
 | 
						|
                    (-2,  0,   '+100%'),
 | 
						|
 | 
						|
                    (1.00006, 1,  '-0.01%'),
 | 
						|
                    (1, 1.00006,  '+0.01%'),
 | 
						|
                    (1.000004, 1,    '-0%'),
 | 
						|
                    (1, 1.000004,    '+0%'),
 | 
						|
                ],
 | 
						|
            )
 | 
						|
 | 
						|
    def test_number_diff_humanized_markdown(self):
 | 
						|
        self._assert_single_value_diff_matches(
 | 
						|
            BenchmarkDiffer(DifferenceStyle.HUMANIZED, 4, OutputFormat.MARKDOWN),
 | 
						|
            [
 | 
						|
                (2,   2,             '`0%`'),
 | 
						|
                (2,   5,   '**`+150% ❌`**'),
 | 
						|
                (5,   2,    '**`-60% ✅`**'),
 | 
						|
                (2.0, 2.0,           '`0%`'),
 | 
						|
                (2,   2.0,           '`0%`'),
 | 
						|
                (2.0, 2,             '`0%`'),
 | 
						|
                (2,   2.5,  '**`+25% ❌`**'),
 | 
						|
                (2.5, 2,    '**`-20% ✅`**'),
 | 
						|
 | 
						|
                (0,   0,             '`0%`'),
 | 
						|
                (0,   2,          '`+INF%`'),
 | 
						|
                (0,   -2,         '`-INF%`'),
 | 
						|
 | 
						|
                (-3, -1, '**`+66.67% ❌`**'),
 | 
						|
                (-1, -3,   '**`-200% ✅`**'),
 | 
						|
                (2,   0,   '**`-100% ✅`**'),
 | 
						|
                (-2,  0,   '**`+100% ❌`**'),
 | 
						|
 | 
						|
                (1.00006, 1,  '**`-0.01% ✅`**'),
 | 
						|
                (1, 1.00006,  '**`+0.01% ❌`**'),
 | 
						|
                (1.000004, 1,           '`-0%`'),
 | 
						|
                (1, 1.000004,           '`+0%`'),
 | 
						|
            ],
 | 
						|
        )
 | 
						|
 | 
						|
    def test_type_mismatch(self):
 | 
						|
        for style in DifferenceStyle:
 | 
						|
            self._assert_single_value_diff_matches(
 | 
						|
                BenchmarkDiffer(style, 4, OutputFormat.JSON),
 | 
						|
                [
 | 
						|
                    (1, {}, '!T'),
 | 
						|
                    ({}, 1, '!T'),
 | 
						|
                    (1.5, {}, '!T'),
 | 
						|
                    ({}, 1.5, '!T'),
 | 
						|
                    ('1', {}, '!T'),
 | 
						|
                    ({}, '1', '!T'),
 | 
						|
                    (1, '1', '!T'),
 | 
						|
                    ('1', 1, '!T'),
 | 
						|
                    (1.5, '1', '!T'),
 | 
						|
                    ('1', 1.5, '!T'),
 | 
						|
                    ('1', '1', '!T'),
 | 
						|
                ],
 | 
						|
            )
 | 
						|
 | 
						|
    def test_version_mismatch(self):
 | 
						|
        for style in DifferenceStyle:
 | 
						|
            self._assert_single_value_diff_matches(
 | 
						|
                BenchmarkDiffer(style, 4, OutputFormat.JSON),
 | 
						|
                [
 | 
						|
                    ({'a': 123, 'version': 1}, {'a': 123, 'version': 2}, '!V'),
 | 
						|
                    ({'a': 123, 'version': 2}, {'a': 123, 'version': 1}, '!V'),
 | 
						|
                    ({'a': 123, 'version': 'a'}, {'a': 123, 'version': 'b'}, '!V'),
 | 
						|
                    ({'a': 123, 'version': 'a'}, {'a': 123, 'version': 1}, '!V'),
 | 
						|
 | 
						|
                    ({'a': 'a', 'version': 1}, {'a': 'a', 'version': 2}, '!V'),
 | 
						|
                    ({'a': {}, 'version': 1}, {'a': {}, 'version': 2}, '!V'),
 | 
						|
                    ({'s': {'a': 1}, 'version': 1}, {'s': {'a': 1}, 'version': 2}, '!V'),
 | 
						|
 | 
						|
                    ({'a': 123, 'version': 1}, {'a': 456, 'version': 2}, '!V'),
 | 
						|
                    ({'a': 'a', 'version': 1}, {'a': 'b', 'version': 2}, '!V'),
 | 
						|
                    ({'s': {'a': 1}, 'version': 1}, {'s': {'a': 2}, 'version': 2}, '!V'),
 | 
						|
                ],
 | 
						|
            )
 | 
						|
 | 
						|
    def test_missing(self):
 | 
						|
        for style in DifferenceStyle:
 | 
						|
            self._assert_single_value_diff_matches(
 | 
						|
                BenchmarkDiffer(style, None, OutputFormat.JSON),
 | 
						|
                [
 | 
						|
                    (1, None, '!A'),
 | 
						|
                    (None, 1, '!B'),
 | 
						|
                    ('1', None, '!A'),
 | 
						|
                    (None, '1', '!B'),
 | 
						|
                    ({}, None, '!A'),
 | 
						|
                    (None, {}, '!B'),
 | 
						|
 | 
						|
                    ({'x': 1}, {}, {'x': '!A'}),
 | 
						|
                    ({}, {'x': 1}, {'x': '!B'}),
 | 
						|
                    ({'x': 1}, {'x': None}, {'x': '!A'}),
 | 
						|
                    ({'x': None}, {'x': 1}, {'x': '!B'}),
 | 
						|
                    ({'x': 1}, {'y': 1}, {'x': '!A', 'y': '!B'}),
 | 
						|
 | 
						|
                    ({'x': {}}, {}, {'x': '!A'}),
 | 
						|
                    ({}, {'x': {}}, {'x': '!B'}),
 | 
						|
                    ({'p': {'x': {}}}, {}, {'p': '!A'}),
 | 
						|
                    ({}, {'p': {'x': {}}}, {'p': '!B'}),
 | 
						|
                ],
 | 
						|
            )
 | 
						|
 | 
						|
    def test_missing_vs_null(self):
 | 
						|
        for style in DifferenceStyle:
 | 
						|
            self._assert_single_value_diff_matches(
 | 
						|
                BenchmarkDiffer(style, None, OutputFormat.JSON),
 | 
						|
                [
 | 
						|
                    ({'a': None}, {}, {}),
 | 
						|
                    ({}, {'a': None}, {}),
 | 
						|
                ],
 | 
						|
                nest_result=False,
 | 
						|
            )
 | 
						|
 | 
						|
 | 
						|
class TestDiffTableFormatter(unittest.TestCase):
 | 
						|
    def setUp(self):
 | 
						|
        self.maxDiff = 10000
 | 
						|
 | 
						|
        self.report_before = {
 | 
						|
            'project A': {
 | 
						|
                'preset X': {'A1':  99, 'A2': 50, 'version': 1},
 | 
						|
                'preset Y': {'A1':   0, 'A2': 50, 'version': 1},
 | 
						|
            },
 | 
						|
            'project B': {
 | 
						|
                'preset X': {           'A2': 50},
 | 
						|
                'preset Y': {'A1':   0},
 | 
						|
            },
 | 
						|
            'project C': {
 | 
						|
                'preset X': {'A1':   0, 'A2': 50, 'version': 1},
 | 
						|
            },
 | 
						|
            'project D': {
 | 
						|
                'preset X': {'A1': 999},
 | 
						|
            },
 | 
						|
        }
 | 
						|
        self.report_after = {
 | 
						|
            'project A': {
 | 
						|
                'preset X': {'A1': 100, 'A2':  50, 'version': 1},
 | 
						|
                'preset Y': {'A1': 500, 'A2': 500, 'version': 2},
 | 
						|
            },
 | 
						|
            'project B': {
 | 
						|
                'preset X': {'A1':   0},
 | 
						|
                'preset Y': {           'A2': 50},
 | 
						|
            },
 | 
						|
            'project C': {
 | 
						|
                'preset Y': {'A1':   0, 'A2': 50, 'version': 1},
 | 
						|
            },
 | 
						|
            'project E': {
 | 
						|
                'preset Y': {           'A2': 999},
 | 
						|
            },
 | 
						|
        }
 | 
						|
 | 
						|
    def test_diff_table_formatter(self):
 | 
						|
        report_before = json.loads(load_fixture(SUMMARIZED_BENCHMARKS_DEVELOP_JSON_PATH))
 | 
						|
        report_after = json.loads(load_fixture(SUMMARIZED_BENCHMARKS_BRANCH_JSON_PATH))
 | 
						|
        differ = BenchmarkDiffer(DifferenceStyle.HUMANIZED, 4, OutputFormat.MARKDOWN)
 | 
						|
        diff = differ.run(report_before, report_after)
 | 
						|
 | 
						|
        self.assertEqual(DiffTableFormatter.run(DiffTableSet(diff), OutputFormat.MARKDOWN), SUMMARIZED_DIFF_HUMANIZED_MD)
 | 
						|
 | 
						|
    def test_diff_table_formatter_json_absolute(self):
 | 
						|
        differ = BenchmarkDiffer(DifferenceStyle.ABSOLUTE, 4, OutputFormat.JSON)
 | 
						|
        diff = differ.run(self.report_before, self.report_after)
 | 
						|
 | 
						|
        expected_formatted_table = dedent("""\
 | 
						|
            {
 | 
						|
                "preset X": {
 | 
						|
                    "project A": {
 | 
						|
                        "A1": 1,
 | 
						|
                        "A2": 0
 | 
						|
                    },
 | 
						|
                    "project B": {
 | 
						|
                        "A1": "!B",
 | 
						|
                        "A2": "!A"
 | 
						|
                    },
 | 
						|
                    "project C": {
 | 
						|
                        "A1": "!A",
 | 
						|
                        "A2": "!A"
 | 
						|
                    },
 | 
						|
                    "project D": {
 | 
						|
                        "A1": "!A",
 | 
						|
                        "A2": "!A"
 | 
						|
                    },
 | 
						|
                    "project E": {
 | 
						|
                        "A1": "!B",
 | 
						|
                        "A2": "!B"
 | 
						|
                    }
 | 
						|
                },
 | 
						|
                "preset Y": {
 | 
						|
                    "project A": {
 | 
						|
                        "A1": "!V",
 | 
						|
                        "A2": "!V"
 | 
						|
                    },
 | 
						|
                    "project B": {
 | 
						|
                        "A1": "!A",
 | 
						|
                        "A2": "!B"
 | 
						|
                    },
 | 
						|
                    "project C": {
 | 
						|
                        "A1": "!B",
 | 
						|
                        "A2": "!B"
 | 
						|
                    },
 | 
						|
                    "project D": {
 | 
						|
                        "A1": "!A",
 | 
						|
                        "A2": "!A"
 | 
						|
                    },
 | 
						|
                    "project E": {
 | 
						|
                        "A1": "!B",
 | 
						|
                        "A2": "!B"
 | 
						|
                    }
 | 
						|
                }
 | 
						|
            }"""
 | 
						|
        )
 | 
						|
        self.assertEqual(DiffTableFormatter.run(DiffTableSet(diff), OutputFormat.JSON), expected_formatted_table)
 | 
						|
 | 
						|
    def test_diff_table_formatter_console_relative(self):
 | 
						|
        differ = BenchmarkDiffer(DifferenceStyle.RELATIVE, 4, OutputFormat.CONSOLE)
 | 
						|
        diff = differ.run(self.report_before, self.report_after)
 | 
						|
 | 
						|
        expected_formatted_table = dedent("""
 | 
						|
            PRESET X
 | 
						|
            |-----------|--------|----|
 | 
						|
            |   project |     A1 | A2 |
 | 
						|
            |-----------|--------|----|
 | 
						|
            | project A | 0.0101 |  0 |
 | 
						|
            | project B |     !B | !A |
 | 
						|
            | project C |     !A | !A |
 | 
						|
            | project D |     !A | !A |
 | 
						|
            | project E |     !B | !B |
 | 
						|
            |-----------|--------|----|
 | 
						|
 | 
						|
            PRESET Y
 | 
						|
            |-----------|----|----|
 | 
						|
            |   project | A1 | A2 |
 | 
						|
            |-----------|----|----|
 | 
						|
            | project A | !V | !V |
 | 
						|
            | project B | !A | !B |
 | 
						|
            | project C | !B | !B |
 | 
						|
            | project D | !A | !A |
 | 
						|
            | project E | !B | !B |
 | 
						|
            |-----------|----|----|
 | 
						|
        """)
 | 
						|
        self.assertEqual(DiffTableFormatter.run(DiffTableSet(diff), OutputFormat.CONSOLE), expected_formatted_table)
 | 
						|
 | 
						|
    def test_diff_table_formatter_markdown_humanized(self):
 | 
						|
        differ = BenchmarkDiffer(DifferenceStyle.HUMANIZED, 4, OutputFormat.MARKDOWN)
 | 
						|
        diff = differ.run(self.report_before, self.report_after)
 | 
						|
 | 
						|
        expected_formatted_table = dedent("""
 | 
						|
            ### `preset X`
 | 
						|
            |   project |             A1 |   A2 |
 | 
						|
            |:---------:|---------------:|-----:|
 | 
						|
            | project A | **`+1.01% ❌`** | `0%` |
 | 
						|
            | project B |           `!B` | `!A` |
 | 
						|
            | project C |           `!A` | `!A` |
 | 
						|
            | project D |           `!A` | `!A` |
 | 
						|
            | project E |           `!B` | `!B` |
 | 
						|
 | 
						|
            ### `preset Y`
 | 
						|
            |   project |   A1 |   A2 |
 | 
						|
            |:---------:|-----:|-----:|
 | 
						|
            | project A | `!V` | `!V` |
 | 
						|
            | project B | `!A` | `!B` |
 | 
						|
            | project C | `!B` | `!B` |
 | 
						|
            | project D | `!A` | `!A` |
 | 
						|
            | project E | `!B` | `!B` |
 | 
						|
 | 
						|
 | 
						|
            `!V` = version mismatch
 | 
						|
            `!B` = no value in the "before" version
 | 
						|
            `!A` = no value in the "after" version
 | 
						|
            `!T` = one or both values were not numeric and could not be compared
 | 
						|
            `-0` = very small negative value rounded to zero
 | 
						|
            `+0` = very small positive value rounded to zero
 | 
						|
 | 
						|
        """)
 | 
						|
        self.assertEqual(DiffTableFormatter.run(DiffTableSet(diff), OutputFormat.MARKDOWN), expected_formatted_table)
 |