migration: preserve frontend shell pages and styles
This commit is contained in:
@@ -0,0 +1 @@
|
||||
"""Test support package for the preserved application."""
|
||||
@@ -0,0 +1,75 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import hashlib
|
||||
import re
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
APP_ROOT = Path(__file__).resolve().parents[1]
|
||||
ORIGINAL_ROOT = APP_ROOT.parent
|
||||
FRONTEND_ROOT = APP_ROOT / "frontend"
|
||||
ORIGINAL_STATIC = ORIGINAL_ROOT / "static"
|
||||
|
||||
SOURCE_RANGE = re.compile(
|
||||
r"/\* PRESERVATION-SOURCE-BEGIN app\.js:(\d+)-(\d+) \*/\n"
|
||||
r"(.*?)"
|
||||
r"/\* PRESERVATION-SOURCE-END app\.js:\1-\2 \*/\n?",
|
||||
re.DOTALL,
|
||||
)
|
||||
|
||||
|
||||
def sha256(path: Path) -> str:
|
||||
return hashlib.sha256(path.read_bytes()).hexdigest()
|
||||
|
||||
|
||||
def reassembled_frontend_runtime() -> str:
|
||||
chunks: dict[tuple[int, int], str] = {}
|
||||
for path in FRONTEND_ROOT.rglob("*.js"):
|
||||
for match in SOURCE_RANGE.finditer(path.read_text(encoding="utf-8")):
|
||||
source_range = (int(match.group(1)), int(match.group(2)))
|
||||
if source_range in chunks:
|
||||
raise AssertionError(f"duplicate app.js source range: {source_range}")
|
||||
chunks[source_range] = match.group(3)
|
||||
|
||||
assembled: list[str] = []
|
||||
next_line = 1
|
||||
for (start, end), content in sorted(chunks.items()):
|
||||
if start != next_line:
|
||||
raise AssertionError(
|
||||
f"app.js source coverage gap: expected line {next_line}, got {start}"
|
||||
)
|
||||
if len(content.splitlines(keepends=True)) != end - start + 1:
|
||||
raise AssertionError(f"app.js line count changed in range {start}-{end}")
|
||||
assembled.append(content)
|
||||
next_line = end + 1
|
||||
|
||||
original_line_count = len(
|
||||
(ORIGINAL_STATIC / "app.js").read_text(encoding="utf-8").splitlines()
|
||||
)
|
||||
if next_line != original_line_count + 1:
|
||||
raise AssertionError(
|
||||
f"app.js source coverage ended at {next_line - 1}, expected {original_line_count}"
|
||||
)
|
||||
return "".join(assembled)
|
||||
|
||||
|
||||
def assert_moved_asset_matches(
|
||||
testcase,
|
||||
original_relative: str,
|
||||
frontend_relative: str | None = None,
|
||||
) -> None:
|
||||
target_relative = frontend_relative or original_relative
|
||||
testcase.assertEqual(
|
||||
sha256(FRONTEND_ROOT / target_relative),
|
||||
sha256(ORIGINAL_STATIC / original_relative),
|
||||
original_relative,
|
||||
)
|
||||
|
||||
|
||||
def assert_page_prefix_matches(testcase, page_relative: str) -> None:
|
||||
original = (ORIGINAL_STATIC / page_relative).read_text(encoding="utf-8")
|
||||
migrated = (FRONTEND_ROOT / page_relative).read_text(encoding="utf-8")
|
||||
testcase.assertTrue(
|
||||
migrated.startswith(original.rstrip("\n") + "\n\n"),
|
||||
page_relative,
|
||||
)
|
||||
@@ -6,14 +6,14 @@ from pathlib import Path
|
||||
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[1]
|
||||
STATIC = ROOT / "static"
|
||||
STATIC = ROOT / "frontend"
|
||||
TOKENS = STATIC / "shared" / "tokens.css"
|
||||
LEGACY_STYLESHEETS = (
|
||||
"styles.css",
|
||||
"renovation.css",
|
||||
"redesign-v2.css",
|
||||
"design-system.css",
|
||||
"theme.css",
|
||||
"styles/styles.css",
|
||||
"styles/renovation.css",
|
||||
"styles/redesign-v2.css",
|
||||
"styles/design-system.css",
|
||||
"styles/theme.css",
|
||||
)
|
||||
|
||||
|
||||
@@ -26,12 +26,12 @@ class CssGovernanceTests(unittest.TestCase):
|
||||
def test_token_layer_loads_before_application_styles(self) -> None:
|
||||
expected_order = (
|
||||
"/shared/tokens.css",
|
||||
"/styles.css",
|
||||
"/renovation.css",
|
||||
"/redesign-v2.css",
|
||||
"/design-system.css",
|
||||
"/theme.css",
|
||||
"/wentian-v2.css",
|
||||
"/styles/styles.css",
|
||||
"/styles/renovation.css",
|
||||
"/styles/redesign-v2.css",
|
||||
"/styles/design-system.css",
|
||||
"/styles/theme.css",
|
||||
"/pages/heaven/page.css",
|
||||
)
|
||||
positions = [self.html.index(path) for path in expected_order]
|
||||
self.assertEqual(positions, sorted(positions))
|
||||
@@ -63,7 +63,7 @@ class CssGovernanceTests(unittest.TestCase):
|
||||
|
||||
def test_wentian_tokens_remain_isolated(self) -> None:
|
||||
self.assertNotRegex(self.tokens, r"--wt-[a-z0-9-]+\s*:")
|
||||
wentian = (STATIC / "wentian-v2.css").read_text(encoding="utf-8")
|
||||
wentian = (STATIC / "pages" / "heaven" / "page.css").read_text(encoding="utf-8")
|
||||
self.assertRegex(wentian, r"--wt-[a-z0-9-]+\s*:")
|
||||
|
||||
def test_compatibility_aliases_cover_historical_layers(self) -> None:
|
||||
|
||||
@@ -5,9 +5,11 @@ import re
|
||||
import unittest
|
||||
from pathlib import Path
|
||||
|
||||
from tests.preservation_helpers import reassembled_frontend_runtime
|
||||
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[1]
|
||||
STATIC = ROOT / "static"
|
||||
STATIC = ROOT / "frontend"
|
||||
|
||||
|
||||
class FrontendBoundaryTests(unittest.TestCase):
|
||||
@@ -22,7 +24,7 @@ class FrontendBoundaryTests(unittest.TestCase):
|
||||
|
||||
def test_shared_dependencies_load_before_application(self) -> None:
|
||||
html = (STATIC / "index.html").read_text(encoding="utf-8")
|
||||
ui_position = html.index('/ui-core.js')
|
||||
ui_position = html.index('/shared/ui-core.js')
|
||||
components_position = html.index('/shared/components.js')
|
||||
pages_position = html.index('/pages.config.js')
|
||||
runtime_position = html.index('/pages/runtime.js')
|
||||
@@ -40,7 +42,7 @@ class FrontendBoundaryTests(unittest.TestCase):
|
||||
self.assertLess(shell_position, app_position)
|
||||
|
||||
def test_application_state_is_created_through_shared_boundary(self) -> None:
|
||||
app = (STATIC / "app.js").read_text(encoding="utf-8")
|
||||
app = reassembled_frontend_runtime()
|
||||
self.assertIn("const state = window.XiaobaiState.create({", app)
|
||||
self.assertNotIn("const state = {", app)
|
||||
|
||||
@@ -70,7 +72,7 @@ class FrontendBoundaryTests(unittest.TestCase):
|
||||
self.assertEqual(actual, expected)
|
||||
|
||||
def test_shell_owns_navigation_and_page_mounting(self) -> None:
|
||||
app = (STATIC / "app.js").read_text(encoding="utf-8")
|
||||
app = reassembled_frontend_runtime()
|
||||
shell = (STATIC / "shared" / "shell.js").read_text(encoding="utf-8")
|
||||
self.assertNotIn("function syncNavigationState", app)
|
||||
self.assertNotIn("function initializeApplicationShell", app)
|
||||
@@ -109,7 +111,7 @@ class FrontendBoundaryTests(unittest.TestCase):
|
||||
self.assertEqual(actual, expected)
|
||||
|
||||
def test_page_lifecycle_is_owned_outside_application_monolith(self) -> None:
|
||||
app = (STATIC / "app.js").read_text(encoding="utf-8")
|
||||
app = reassembled_frontend_runtime()
|
||||
runtime = (STATIC / "pages" / "runtime.js").read_text(encoding="utf-8")
|
||||
start = app.index("function openView(")
|
||||
end = app.index("\nfunction initializeAutoTableSorting", start)
|
||||
@@ -122,7 +124,7 @@ class FrontendBoundaryTests(unittest.TestCase):
|
||||
|
||||
def test_shared_empty_state_component_is_used_by_multiple_features(self) -> None:
|
||||
components = (STATIC / "shared" / "components.js").read_text(encoding="utf-8")
|
||||
app = (STATIC / "app.js").read_text(encoding="utf-8")
|
||||
app = reassembled_frontend_runtime()
|
||||
self.assertIn("function emptyStateHtml(message, options = {})", components)
|
||||
self.assertIn("function renderEmptyState(target, message, options = {})", components)
|
||||
self.assertGreaterEqual(app.count("renderEmptyState("), 8)
|
||||
|
||||
@@ -5,8 +5,10 @@ import unittest
|
||||
from html.parser import HTMLParser
|
||||
from pathlib import Path
|
||||
|
||||
from tests.preservation_helpers import reassembled_frontend_runtime
|
||||
|
||||
STATIC_DIR = Path(__file__).resolve().parents[1] / "static"
|
||||
|
||||
STATIC_DIR = Path(__file__).resolve().parents[1] / "frontend"
|
||||
|
||||
|
||||
class IdCollector(HTMLParser):
|
||||
@@ -22,11 +24,11 @@ class FrontendContractTests(unittest.TestCase):
|
||||
@classmethod
|
||||
def setUpClass(cls) -> None:
|
||||
cls.html = (STATIC_DIR / "index.html").read_text(encoding="utf-8")
|
||||
cls.script = (STATIC_DIR / "app.js").read_text(encoding="utf-8")
|
||||
cls.script = reassembled_frontend_runtime()
|
||||
cls.shell = (STATIC_DIR / "shared" / "shell.js").read_text(encoding="utf-8")
|
||||
cls.ui_core = (STATIC_DIR / "ui-core.js").read_text(encoding="utf-8")
|
||||
cls.design_system = (STATIC_DIR / "design-system.css").read_text(encoding="utf-8")
|
||||
cls.theme = (STATIC_DIR / "theme.css").read_text(encoding="utf-8")
|
||||
cls.ui_core = (STATIC_DIR / "shared" / "ui-core.js").read_text(encoding="utf-8")
|
||||
cls.design_system = (STATIC_DIR / "styles" / "design-system.css").read_text(encoding="utf-8")
|
||||
cls.theme = (STATIC_DIR / "styles" / "theme.css").read_text(encoding="utf-8")
|
||||
cls.tokens = (STATIC_DIR / "shared" / "tokens.css").read_text(encoding="utf-8")
|
||||
collector = IdCollector()
|
||||
collector.feed(cls.html)
|
||||
@@ -158,7 +160,7 @@ class FrontendContractTests(unittest.TestCase):
|
||||
self.assertIn("必需数据已完整,本日没有股票同时满足", self.script)
|
||||
|
||||
def test_dialogs_and_dark_table_hover_have_shared_safety_constraints(self):
|
||||
redesign = (STATIC_DIR / "redesign-v2.css").read_text(encoding="utf-8")
|
||||
redesign = (STATIC_DIR / "styles" / "redesign-v2.css").read_text(encoding="utf-8")
|
||||
self.assertIn(".settings-dialog:not(.heaven-reading-dialog)[open] { margin: auto; }", redesign)
|
||||
self.assertIn("max-height: min(760px, calc(100dvh - 28px));", redesign)
|
||||
self.assertIn('#reviewWorkspaceView .data-table tbody tr:hover td', self.theme)
|
||||
@@ -166,8 +168,8 @@ class FrontendContractTests(unittest.TestCase):
|
||||
self.assertIn('#screenerView .screener-result-frame tbody tr:hover td:last-child', self.theme)
|
||||
|
||||
def test_global_toast_has_one_owner_and_cannot_stretch_between_insets(self):
|
||||
styles = (STATIC_DIR / "styles.css").read_text(encoding="utf-8")
|
||||
wentian = (STATIC_DIR / "wentian-v2.css").read_text(encoding="utf-8")
|
||||
styles = (STATIC_DIR / "styles" / "styles.css").read_text(encoding="utf-8")
|
||||
wentian = (STATIC_DIR / "pages" / "heaven" / "page.css").read_text(encoding="utf-8")
|
||||
self.assertIn("#toast.toast {", styles)
|
||||
self.assertIn("top: auto;", styles)
|
||||
self.assertIn("left: auto;", styles)
|
||||
@@ -183,7 +185,7 @@ class FrontendContractTests(unittest.TestCase):
|
||||
|
||||
def test_shared_ui_core_loads_before_application(self):
|
||||
self.assertLess(
|
||||
self.html.index('<script src="/ui-core.js"'),
|
||||
self.html.index('<script src="/shared/ui-core.js"'),
|
||||
self.html.index('<script src="/app.js'),
|
||||
)
|
||||
for function_name in (
|
||||
|
||||
@@ -4,6 +4,7 @@ import unittest
|
||||
from pathlib import Path
|
||||
|
||||
from server import DashboardService
|
||||
from tests.preservation_helpers import reassembled_frontend_runtime
|
||||
|
||||
|
||||
class SearchDatabaseStub:
|
||||
@@ -77,9 +78,9 @@ class GlobalSearchTests(unittest.TestCase):
|
||||
)
|
||||
|
||||
def test_frontend_reuses_full_stock_detail_and_renders_market_daily_k(self):
|
||||
static_dir = Path(__file__).resolve().parents[1] / "static"
|
||||
static_dir = Path(__file__).resolve().parents[1] / "frontend"
|
||||
html = (static_dir / "index.html").read_text(encoding="utf-8")
|
||||
script = (static_dir / "app.js").read_text(encoding="utf-8")
|
||||
script = reassembled_frontend_runtime()
|
||||
|
||||
self.assertIn('id="globalSearchButton"', html)
|
||||
self.assertIn('id="globalSearchDialog"', html)
|
||||
|
||||
@@ -23,7 +23,7 @@ class AccountSliceStructureTests(unittest.TestCase):
|
||||
|
||||
def test_runtime_paths_still_point_at_app_root(self) -> None:
|
||||
self.assertEqual(APP_DIR, Path(__file__).resolve().parents[1])
|
||||
self.assertEqual(STATIC_DIR, APP_DIR / "static")
|
||||
self.assertEqual(STATIC_DIR, APP_DIR / "frontend")
|
||||
|
||||
def test_account_persistence_and_http_transport_have_single_owners(self) -> None:
|
||||
for method in (
|
||||
|
||||
@@ -0,0 +1,100 @@
|
||||
from __future__ import annotations
|
||||
|
||||
import re
|
||||
import unittest
|
||||
|
||||
from backend.bootstrap.config import APP_DIR, STATIC_DIR
|
||||
from tests.preservation_helpers import (
|
||||
FRONTEND_ROOT,
|
||||
ORIGINAL_STATIC,
|
||||
assert_moved_asset_matches,
|
||||
assert_page_prefix_matches,
|
||||
reassembled_frontend_runtime,
|
||||
)
|
||||
|
||||
|
||||
class FrontendPreservationSliceTests(unittest.TestCase):
|
||||
def test_split_runtime_reassembles_to_the_exact_original(self) -> None:
|
||||
self.assertEqual(
|
||||
reassembled_frontend_runtime(),
|
||||
(ORIGINAL_STATIC / "app.js").read_text(encoding="utf-8"),
|
||||
)
|
||||
|
||||
def test_index_diff_is_limited_to_asset_relocation_and_split_loading(self) -> None:
|
||||
migrated = (FRONTEND_ROOT / "index.html").read_text(encoding="utf-8")
|
||||
restored = migrated
|
||||
for current, original in (
|
||||
("/styles/styles.css", "/styles.css"),
|
||||
("/styles/renovation.css", "/renovation.css"),
|
||||
("/styles/redesign-v2.css", "/redesign-v2.css"),
|
||||
("/styles/design-system.css", "/design-system.css"),
|
||||
("/styles/theme.css", "/theme.css"),
|
||||
("/pages/heaven/page.css", "/wentian-v2.css"),
|
||||
("/shared/ui-core.js", "/ui-core.js"),
|
||||
("/pages/heaven/loading-v2.js", "/heaven-loading-v2.js"),
|
||||
):
|
||||
restored = restored.replace(current, original)
|
||||
restored = restored.replace(
|
||||
' <script src="/pages/market/runtime.js?v=20260731-1" defer></script>\n',
|
||||
"",
|
||||
)
|
||||
restored = restored.replace(
|
||||
' <script src="/shared/export.js?v=20260731-1" defer></script>\n',
|
||||
"",
|
||||
)
|
||||
self.assertEqual(
|
||||
restored,
|
||||
(ORIGINAL_STATIC / "index.html").read_text(encoding="utf-8"),
|
||||
)
|
||||
|
||||
def test_complete_stylesheet_stack_is_byte_identical_after_relocation(self) -> None:
|
||||
for original, migrated in (
|
||||
("shared/tokens.css", "shared/tokens.css"),
|
||||
("styles.css", "styles/styles.css"),
|
||||
("renovation.css", "styles/renovation.css"),
|
||||
("redesign-v2.css", "styles/redesign-v2.css"),
|
||||
("design-system.css", "styles/design-system.css"),
|
||||
("theme.css", "styles/theme.css"),
|
||||
("wentian-v2.css", "pages/heaven/page.css"),
|
||||
):
|
||||
with self.subTest(asset=original):
|
||||
assert_moved_asset_matches(self, original, migrated)
|
||||
|
||||
def test_shared_vendor_and_animation_assets_are_byte_identical(self) -> None:
|
||||
for original, migrated in (
|
||||
("ui-core.js", "shared/ui-core.js"),
|
||||
("heaven-loading-v2.js", "pages/heaven/loading-v2.js"),
|
||||
("heaven-loading.js", "heaven-loading.js"),
|
||||
("vendor/lucide.min.js", "vendor/lucide.min.js"),
|
||||
("pages.config.js", "pages.config.js"),
|
||||
("pages/runtime.js", "pages/runtime.js"),
|
||||
("shared/api.js", "shared/api.js"),
|
||||
("shared/components.js", "shared/components.js"),
|
||||
("shared/shell.js", "shared/shell.js"),
|
||||
("shared/state.js", "shared/state.js"),
|
||||
):
|
||||
with self.subTest(asset=original):
|
||||
assert_moved_asset_matches(self, original, migrated)
|
||||
|
||||
def test_original_page_registration_prefixes_are_preserved(self) -> None:
|
||||
for path in sorted((ORIGINAL_STATIC / "pages").glob("*/page.js")):
|
||||
relative = path.relative_to(ORIGINAL_STATIC).as_posix()
|
||||
with self.subTest(page=relative):
|
||||
assert_page_prefix_matches(self, relative)
|
||||
|
||||
def test_frontend_is_the_only_served_static_root(self) -> None:
|
||||
self.assertEqual(STATIC_DIR, APP_DIR / "frontend")
|
||||
self.assertFalse((APP_DIR / "static").exists())
|
||||
|
||||
def test_shared_api_remains_the_only_fetch_exit(self) -> None:
|
||||
consumers = []
|
||||
for path in FRONTEND_ROOT.rglob("*.js"):
|
||||
if "vendor" in path.parts:
|
||||
continue
|
||||
if re.search(r"\bfetch\s*\(", path.read_text(encoding="utf-8")):
|
||||
consumers.append(path.relative_to(FRONTEND_ROOT).as_posix())
|
||||
self.assertEqual(consumers, ["shared/api.js"])
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
unittest.main()
|
||||
@@ -5,6 +5,13 @@ import hashlib
|
||||
import unittest
|
||||
from pathlib import Path
|
||||
|
||||
from tests.preservation_helpers import (
|
||||
ORIGINAL_STATIC,
|
||||
assert_moved_asset_matches,
|
||||
assert_page_prefix_matches,
|
||||
reassembled_frontend_runtime,
|
||||
)
|
||||
|
||||
|
||||
APP_ROOT = Path(__file__).resolve().parents[1]
|
||||
ORIGINAL_ROOT = APP_ROOT.parent
|
||||
@@ -73,19 +80,17 @@ class LadderRotationSliceSourceEquivalenceTests(unittest.TestCase):
|
||||
)
|
||||
|
||||
def test_api_and_frontend_assets_are_unchanged(self) -> None:
|
||||
for relative in (
|
||||
"config/api.config.json",
|
||||
"static/index.html",
|
||||
"static/app.js",
|
||||
"static/styles.css",
|
||||
"static/pages/ladder/page.js",
|
||||
"static/pages/rotation/page.js",
|
||||
):
|
||||
self.assertEqual(
|
||||
sha256(APP_ROOT / relative),
|
||||
sha256(ORIGINAL_ROOT / relative),
|
||||
relative,
|
||||
)
|
||||
self.assertEqual(
|
||||
sha256(APP_ROOT / "config/api.config.json"),
|
||||
sha256(ORIGINAL_ROOT / "config/api.config.json"),
|
||||
)
|
||||
self.assertEqual(
|
||||
reassembled_frontend_runtime(),
|
||||
(ORIGINAL_STATIC / "app.js").read_text(encoding="utf-8"),
|
||||
)
|
||||
assert_moved_asset_matches(self, "styles.css", "styles/styles.css")
|
||||
for page in ("pages/ladder/page.js", "pages/rotation/page.js"):
|
||||
assert_page_prefix_matches(self, page)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
@@ -13,6 +13,11 @@ from backend.data import realtime
|
||||
from backend.data.providers import ifind_client as canonical_ifind
|
||||
from backend.data.providers import tushare_client as canonical_tushare
|
||||
from backend.features.market import charts
|
||||
from tests.preservation_helpers import (
|
||||
ORIGINAL_STATIC,
|
||||
assert_moved_asset_matches,
|
||||
reassembled_frontend_runtime,
|
||||
)
|
||||
|
||||
|
||||
APP_ROOT = Path(__file__).resolve().parents[1]
|
||||
@@ -146,21 +151,19 @@ class MarketSliceSourceEquivalenceTests(unittest.TestCase):
|
||||
top_level_definitions(APP_ROOT / "backend/features/market/charts.py"),
|
||||
)
|
||||
|
||||
def test_unchanged_frontend_assets_match_the_original(self) -> None:
|
||||
for relative in (
|
||||
"index.html",
|
||||
"app.js",
|
||||
"styles.css",
|
||||
"renovation.css",
|
||||
"redesign-v2.css",
|
||||
"theme.css",
|
||||
"wentian-v2.css",
|
||||
def test_relocated_frontend_preserves_original_market_runtime_and_styles(self) -> None:
|
||||
self.assertEqual(
|
||||
reassembled_frontend_runtime(),
|
||||
(ORIGINAL_STATIC / "app.js").read_text(encoding="utf-8"),
|
||||
)
|
||||
for original, migrated in (
|
||||
("styles.css", "styles/styles.css"),
|
||||
("renovation.css", "styles/renovation.css"),
|
||||
("redesign-v2.css", "styles/redesign-v2.css"),
|
||||
("theme.css", "styles/theme.css"),
|
||||
("wentian-v2.css", "pages/heaven/page.css"),
|
||||
):
|
||||
self.assertEqual(
|
||||
sha256(APP_ROOT / "static" / relative),
|
||||
sha256(ORIGINAL_ROOT / "static" / relative),
|
||||
relative,
|
||||
)
|
||||
assert_moved_asset_matches(self, original, migrated)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
@@ -7,6 +7,12 @@ from pathlib import Path
|
||||
|
||||
import market_insights
|
||||
from backend.features.market import insights as canonical_insights
|
||||
from tests.preservation_helpers import (
|
||||
ORIGINAL_STATIC,
|
||||
assert_moved_asset_matches,
|
||||
assert_page_prefix_matches,
|
||||
reassembled_frontend_runtime,
|
||||
)
|
||||
|
||||
|
||||
APP_ROOT = Path(__file__).resolve().parents[1]
|
||||
@@ -174,21 +180,22 @@ class MarketInsightsSliceSourceEquivalenceTests(unittest.TestCase):
|
||||
self.assertEqual(migrated[name], original[name], name)
|
||||
|
||||
def test_api_and_frontend_assets_are_unchanged(self) -> None:
|
||||
for relative in (
|
||||
"config/api.config.json",
|
||||
"static/index.html",
|
||||
"static/app.js",
|
||||
"static/styles.css",
|
||||
"static/pages/auction/page.js",
|
||||
"static/pages/themes/page.js",
|
||||
"static/pages/popularity/page.js",
|
||||
"static/pages/dragon-tiger/page.js",
|
||||
self.assertEqual(
|
||||
sha256(APP_ROOT / "config/api.config.json"),
|
||||
sha256(ORIGINAL_ROOT / "config/api.config.json"),
|
||||
)
|
||||
self.assertEqual(
|
||||
reassembled_frontend_runtime(),
|
||||
(ORIGINAL_STATIC / "app.js").read_text(encoding="utf-8"),
|
||||
)
|
||||
assert_moved_asset_matches(self, "styles.css", "styles/styles.css")
|
||||
for page in (
|
||||
"pages/auction/page.js",
|
||||
"pages/themes/page.js",
|
||||
"pages/popularity/page.js",
|
||||
"pages/dragon-tiger/page.js",
|
||||
):
|
||||
self.assertEqual(
|
||||
sha256(APP_ROOT / relative),
|
||||
sha256(ORIGINAL_ROOT / relative),
|
||||
relative,
|
||||
)
|
||||
assert_page_prefix_matches(self, page)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
@@ -11,6 +11,12 @@ import screener
|
||||
import strategy_tracking
|
||||
from backend.features.screener import compiler, engine, strategies, tracking
|
||||
from backend.features.screener import service as screener_service
|
||||
from tests.preservation_helpers import (
|
||||
ORIGINAL_STATIC,
|
||||
assert_moved_asset_matches,
|
||||
assert_page_prefix_matches,
|
||||
reassembled_frontend_runtime,
|
||||
)
|
||||
|
||||
|
||||
APP_ROOT = Path(__file__).resolve().parents[1]
|
||||
@@ -182,17 +188,12 @@ class ScreenerSliceSourceEquivalenceTests(unittest.TestCase):
|
||||
)
|
||||
|
||||
def test_screener_frontend_assets_are_unchanged(self) -> None:
|
||||
for relative in (
|
||||
"static/index.html",
|
||||
"static/app.js",
|
||||
"static/styles.css",
|
||||
"static/pages/screener/page.js",
|
||||
):
|
||||
self.assertEqual(
|
||||
sha256(APP_ROOT / relative),
|
||||
sha256(ORIGINAL_ROOT / relative),
|
||||
relative,
|
||||
)
|
||||
self.assertEqual(
|
||||
reassembled_frontend_runtime(),
|
||||
(ORIGINAL_STATIC / "app.js").read_text(encoding="utf-8"),
|
||||
)
|
||||
assert_moved_asset_matches(self, "styles.css", "styles/styles.css")
|
||||
assert_page_prefix_matches(self, "pages/screener/page.js")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
@@ -7,6 +7,12 @@ from pathlib import Path
|
||||
|
||||
import sentiment_engine
|
||||
from backend.features.sentiment import engine as canonical_engine
|
||||
from tests.preservation_helpers import (
|
||||
ORIGINAL_STATIC,
|
||||
assert_moved_asset_matches,
|
||||
assert_page_prefix_matches,
|
||||
reassembled_frontend_runtime,
|
||||
)
|
||||
|
||||
|
||||
APP_ROOT = Path(__file__).resolve().parents[1]
|
||||
@@ -95,19 +101,17 @@ class SentimentPoolSliceSourceEquivalenceTests(unittest.TestCase):
|
||||
self.assertIs(sentiment_engine, canonical_engine)
|
||||
|
||||
def test_api_and_frontend_assets_are_unchanged(self) -> None:
|
||||
for relative in (
|
||||
"config/api.config.json",
|
||||
"static/index.html",
|
||||
"static/app.js",
|
||||
"static/styles.css",
|
||||
"static/pages/sentiment/page.js",
|
||||
"static/pages/pools/page.js",
|
||||
):
|
||||
self.assertEqual(
|
||||
sha256(APP_ROOT / relative),
|
||||
sha256(ORIGINAL_ROOT / relative),
|
||||
relative,
|
||||
)
|
||||
self.assertEqual(
|
||||
sha256(APP_ROOT / "config/api.config.json"),
|
||||
sha256(ORIGINAL_ROOT / "config/api.config.json"),
|
||||
)
|
||||
self.assertEqual(
|
||||
reassembled_frontend_runtime(),
|
||||
(ORIGINAL_STATIC / "app.js").read_text(encoding="utf-8"),
|
||||
)
|
||||
assert_moved_asset_matches(self, "styles.css", "styles/styles.css")
|
||||
for page in ("pages/sentiment/page.js", "pages/pools/page.js"):
|
||||
assert_page_prefix_matches(self, page)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
Reference in New Issue
Block a user