Spaces:
Paused
Paused
unknown
Claude Opus 5.5
Journal Finder: title-only search, journals or conferences in one step, conference location, result cards
346458d Download tests/test_tools_tabs.py from Rasheed/Test_AI_writing: direct link, hf CLI and curl.
- Browser
- Download file 16.2 kB
-
https://huggingface.co/spaces/Rasheed/Test_AI_writing/resolve/main/tests/test_tools_tabs.py
- Command line
-
hf download hf://spaces/Rasheed/Test_AI_writing/tests/test_tools_tabs.py
-
curl -L -o test_tools_tabs.py https://huggingface.co/spaces/Rasheed/Test_AI_writing/resolve/main/tests/test_tools_tabs.py
16.2 kB
| """Journal Formatter and Journal Finder tabs (no network: the journal lookup and the search itself are not run).""" | |
| import json | |
| import os | |
| import sys | |
| import zipfile | |
| from pathlib import Path | |
| import pytest | |
| import finder_tab as FND | |
| import formatter_tab as FMT | |
| ROOT = Path(__file__).resolve().parent.parent | |
| progress = lambda *a, **k: None | |
| def _manuscript(tmp_path): | |
| from docx import Document | |
| d = Document() | |
| d.add_heading("A Hybrid Deep Learning Framework for Intrusion Detection", 0) | |
| d.add_paragraph("Ravi Kumar, Priya Sharma") | |
| d.add_paragraph("Abstract: This study proposes a hybrid model that reaches 98.4% accuracy on a public dataset.") | |
| d.add_heading("Introduction", 1) | |
| d.add_paragraph("Medical devices are increasingly connected (Smith, 2020). Prior work used shallow models.") | |
| d.add_heading("References", 1) | |
| d.add_paragraph("Smith, J. (2020). Deep learning for intrusion detection. Journal of Network Security, 12(3), " | |
| "45-67.") | |
| p = tmp_path / "my paper.docx" | |
| d.save(str(p)) | |
| return str(p) | |
| # ---------------------------------------------------------------- formatter | |
| def test_formatter_engine_is_available(): | |
| assert FMT.AVAILABLE, FMT.WHY | |
| assert len(FMT._preset_choices()) > 10 and FMT._preset_key(FMT.AUTO) is None | |
| def test_format_gives_word_latex_report_and_an_overleaf_button(tmp_path): | |
| style = FMT.PRESETS["ieee_journal"]["name"] | |
| status, dl, docx, zip_, md, overleaf, report = FMT.format_doc(_manuscript(tmp_path), "", style, None, "", "", True, | |
| True, False, FMT.REF_STYLES[0], FMT.CITE_MODES[0], | |
| progress) | |
| assert "Formatted as" in status and "checks passed" in status | |
| assert docx.endswith("my_paper_formatted.docx") and Path(docx).stat().st_size > 5000 | |
| names = zipfile.ZipFile(zip_).namelist() | |
| assert "main.tex" in names and not any(n.startswith("/") for n in names) # main.tex at the top level | |
| main = zipfile.ZipFile(zip_).read("main.tex").decode("utf-8") | |
| assert "\\documentclass" in main and "IEEEtran" in main and "\\begin{document}" in main | |
| assert Path(md).read_text(encoding="utf-8").startswith("# Formatting report") and "Compliance" in report | |
| # Overleaf: instructions only; the customer downloads the zip and uploads it himself | |
| assert "Upload Project" in overleaf and "<form" not in overleaf and "overleaf.com/docs" not in overleaf | |
| # download buttons that carry the files (the file box's link is blocked on a custom domain) | |
| assert dl.count('class="cs-dl"') == 3 and 'download="my_paper_formatted.docx"' in dl | |
| assert 'download="my_paper_latex.zip" href="data:application/zip;base64,' in dl and "Download report" in dl | |
| def test_format_needs_a_manuscript_and_a_target(tmp_path): | |
| import gradio as gr | |
| with pytest.raises(gr.Error): | |
| FMT.format_doc(None, "IEEE Access", FMT.AUTO, None, "", "", True, True, False, "", "", progress) | |
| with pytest.raises(gr.Error): | |
| FMT.format_doc(_manuscript(tmp_path), "", FMT.AUTO, None, "", "", True, True, False, "", "", progress) | |
| def test_no_open_in_overleaf_button_only_instructions(tmp_path): | |
| p = tmp_path / "paper_latex.zip" | |
| with zipfile.ZipFile(p, "w") as z: | |
| z.writestr("main.tex", "x") | |
| h = FMT.overleaf_html(str(p)) | |
| assert "New Project → Upload Project" in h and "main.tex" in h | |
| assert "<form" not in h and "<a " not in h and "Open in Overleaf" not in h and "snip_uri" not in h | |
| assert FMT.overleaf_html(None) == "" | |
| assert not hasattr(FMT, "public_url") # nothing hands files to Overleaf any more | |
| # ---------------------------------------------------------------- finder | |
| def test_finder_files_and_data_are_in_place(): | |
| assert FND.AVAILABLE | |
| data = {f.name for f in (ROOT / "finder" / "data").iterdir()} | |
| assert {"ext_list_Jul_2026.xlsx", "scimagojr_2025.csv", "J_Medline.txt", "core_conference_ranks.csv"} <= data | |
| assert any("ABDC" in n for n in data) | |
| def test_shipped_parsed_lists_are_used_not_rebuilt(): | |
| data = ROOT / "finder" / "data" | |
| assert FND.freshen_data_caches() >= 4 | |
| for src, cache in ((data / "ext_list_Jul_2026.xlsx", data / "ext_list_Jul_2026.parsed.pkl"), | |
| (data / "scimagojr_2025.csv", data / "scimagojr_2025.parsed.pkl"), | |
| (data / "J_Medline.txt", data / ".pubmed_J_Medline.pkl")): | |
| assert cache.exists() and cache.stat().st_mtime >= src.stat().st_mtime, cache.name | |
| def test_both_tabs_take_the_suites_status_panel_and_log_their_runs(): | |
| import inspect | |
| for mod, tool in ((FMT, "Journal Formatter"), (FND, "Journal Finder")): | |
| src = inspect.getsource(mod.build) | |
| assert 'ui["run_live"]' in src and 'ui["wait"]' in src and 'ui["job"](status)' in src | |
| assert 'ui["log"]' in src and tool in src and 'ui["user"]' in src | |
| def test_job_options_map_to_the_pipeline_flags(): | |
| sys.path.insert(0, str(ROOT / "finder")) | |
| import run_job | |
| a = run_job.Args(title="A study of things", terms=["x"], limit=20, top=5, acceptance=False, turnaround=True, | |
| semantic=False, apc=True, quartiles=[1, 2], require_scopus=True, abdc_ranks=["A*", "A"], | |
| fast_days=60, sort_by="speed", special_issues=False) | |
| assert a.title == ["A", "study", "of", "things"] and a.term == ["x"] and a.limit == 20 and a.top == 5 | |
| assert a.no_scrape is True and a.no_turnaround is False and a.no_semantic is True and a.no_apc is False | |
| assert a.fast is True and a.quartile == [1, 2] and a.abdc_ranks == ["A*", "A"] and a.fast_days == 60 | |
| assert a.sort_by == "speed" and callable(a.progress) | |
| def test_shortlist_table_is_readable(tmp_path): | |
| csv = tmp_path / "shortlist.csv" | |
| csv.write_text("display_name,publisher,quartile,quartile_is_proxy,abdc_rank,in_pubmed,acceptance_rate_used," | |
| "acceptance_days,acceptance_speed,apc_status,apc_usd_est,term_matches,opportunity_score,homepage," | |
| "openalex_id\n" | |
| "Computers & Security,Elsevier,1,False,,False,0.21,112,Moderate,paid,3200,2,71.234," | |
| "https://example.org/cs,S1\n" | |
| "Journal of Things,Springer,2,True,A,True,,,,no APC,,1,55.5,https://example.org/jt,S2\n", | |
| encoding="utf-8") | |
| view, n = FND._table(csv) | |
| assert n == 2 and list(view.columns)[:3] == ["Journal", "Publisher", "Quartile"] and "openalex_id" not in view | |
| r1, r2 = view.iloc[0], view.iloc[1] | |
| assert r1["Quartile"] == "Q1" and r1["Acceptance rate"] == "21%" and r1["APC"] == "$3,200" and r1["PubMed"] == "—" | |
| assert r2["Quartile"] == "Q2 (estimate)" and r2["APC"] == "no APC" and r2["PubMed"] == "yes" and r2["ABDC"] == "A" | |
| def test_pubmed_column_with_gaps_is_not_all_yes(tmp_path): | |
| csv = tmp_path / "shortlist.csv" | |
| csv.write_text(chr(10).join(["display_name,in_pubmed", "A,False", "B,True", "C,", ""]), encoding="utf-8") | |
| view, _ = FND._table(csv) | |
| assert list(view["PubMed"]) == ["—", "yes", "—"] | |
| def test_download_buttons_hold_the_file(tmp_path): | |
| import base64 as b64 | |
| from tools_common import download_link, download_row | |
| f = tmp_path / "shortlist.csv" | |
| f.write_text("a,b", encoding="utf-8") | |
| h = download_link(str(f), "Download shortlist (.csv)") | |
| assert 'download="shortlist.csv"' in h and "Download shortlist (.csv)" in h | |
| assert b64.b64decode(h.split("base64,", 1)[1].split('"', 1)[0]) == b"a,b" | |
| assert download_link(None) == "" and download_link(str(tmp_path / "missing.csv")) == "" | |
| assert download_row((str(f), "One"), (None, "Two")).count("cs-dl") == 1 and download_row((None, "x")) == "" | |
| def test_find_asks_for_a_title_and_a_subject(): | |
| import gradio as gr | |
| blank = ["", [], "", ["Scopus"], [], [], 40, 10, 3, False, 90, "Best fit", True, True, True, True, 0, False] | |
| with pytest.raises(gr.Error): | |
| FND.find_journals(*blank, progress=progress) | |
| blank[0] = "A hybrid deep learning framework for intrusion detection" | |
| with pytest.raises(gr.Error): | |
| FND.find_journals(*blank, progress=progress) # title but no subject kept | |
| with pytest.raises(gr.Error): | |
| FND.detect_terms("too short") | |
| def test_both_tabs_are_part_of_the_app(): | |
| app = pytest.importorskip("app") | |
| labels = json.dumps(app.demo.get_config_file(), default=str) | |
| assert "Format my manuscript" in labels and "Find the best journals" in labels and "Where should the conference be?" in labels | |
| assert "cs-go-formatter" in labels and "cs-go-finder" in labels | |
| def test_a_reference_that_is_misread_keeps_the_authors_wording(): | |
| from formatmatch import refs as R | |
| text = lambda raw, style: "".join(x.text for x in R.format_reference(R.parse_reference(raw), style, 1)) | |
| book = "Mehta, P. K., Monteiro, P. J. M. Concrete: Microstructure, Properties, and Materials. McGraw-Hill, 2014." | |
| for raw in (book, "Neville, A. M. Properties of Concrete. Pearson, 2011.", | |
| "de Larrard, F. Concrete Mixture Proportioning: A Scientific Approach. E & FN Spon, London, 1999.", | |
| "Bureau of Indian Standards. IS 516: Method of tests for strength of concrete. New Delhi, 1959."): | |
| assert not R.parse_reference(raw).confident | |
| assert raw in text(raw, "apa") and raw in text("[7] " + raw, "ieee") # no surname or title word lost | |
| assert R.lost_words(R.parse_reference(book)) == {"mehta", "monteiro"} | |
| good = "Kumar, A., Rao, B., & Singh, C. (2019). Durability of blended cements. Cement and Concrete Research, 120, 45-56." | |
| assert R.parse_reference(good).confident # a clean entry is still restyled | |
| assert text(good, "ieee").startswith("[1]\tA. Kumar, B. Rao, and C. Singh, “Durability of blended cements,”") | |
| # ---------------------------------------------------------------- LaTeX for Overleaf | |
| def test_latex_checker_finds_what_stops_a_compile(): | |
| from formatmatch.texlint import lint | |
| good = ("\\begin{document}\\section{A} Text \\cite{r1} $x$ \\begin{figure}\\includegraphics{figures/f.png}" | |
| "\\caption{c}\\end{figure}\\begin{thebibliography}{1}\\bibitem{r1} X.\\end{thebibliography}\\end{document}") | |
| assert lint(good, {"figures/f.png": b""}) == [] | |
| bad = lint("\\begin{document}\\begin{table}\\begin{tabular}{l}a\\end{table} {x \\cite{r9} " | |
| "\\includegraphics{figures/missing.png}\\begin{thebibliography}{1}\\bibitem{r1} X." | |
| "\\end{thebibliography}\\end{document}", {}) | |
| joined = " | ".join(bad) | |
| for part in ("tabular", "opening brace", "missing.png is not in the project", "r9", "no caption"): | |
| assert part in joined, (part, bad) | |
| def test_two_column_pdf_lines_are_not_joined_across_the_gutter(): | |
| from formatmatch import read_pdf as RP | |
| line = lambda x0, x1, y: {"bbox": (x0, y, x1, y + 10), "spans": [{"text": "word " * 8, "size": 10, "flags": 0}]} | |
| blk = lambda x0, x1, ys: {"bbox": (x0, ys[0], x1, ys[-1] + 10), "lines": [line(x0, x1, y) for y in ys]} | |
| ys = list(range(100, 300, 12)) | |
| left, right = blk(50, 295, ys), blk(310, 555, ys) # an IEEE page: 15 pt between the columns | |
| g = RP._gutter([left, right], 612) | |
| assert g and 295 <= g <= 310 | |
| merged = RP._merge_baselines([left, right], 10, g) | |
| assert len(merged) == 2 and len(merged[0]["lines"]) == len(ys) # still two columns | |
| assert RP._order_blocks(merged, 612, g)[0] is merged[0] | |
| assert RP._gutter([blk(50, 555, ys)], 612) is None # a one-column page has no gutter | |
| # without the gutter the same lines were glued together (the old behaviour this guards against) | |
| assert len(RP._merge_baselines([blk(50, 295, ys), blk(310, 555, ys)], 10, None)) == 1 | |
| def test_pdf_pieces_cut_by_a_column_are_put_back_together(): | |
| from formatmatch import model as M, read_pdf as RP | |
| B = lambda role, t: M.Block(role, runs=[M.Run(t)], orig=t) | |
| assert RP._continues(B(M.REFERENCE, "[2] W. Tushar, T.K. Saha, Peer-to-peer trading"), B(M.REFERENCE, "in electricity networks, 2020.")) | |
| assert not RP._continues(B(M.REFERENCE, "[2] W. Tushar, Title, 2020."), B(M.REFERENCE, "[3] T. Morstyn, Title.")) | |
| assert RP._continues(B(M.PARA, "This paper fills these gaps with a personalised federated"), B(M.PARA, "MARL mechanism".lower())) | |
| assert not RP._continues(B(M.PARA, "A finished sentence."), B(M.PARA, "another one")) | |
| assert RP._continues(B(M.CAPTION, "LEARNING HYPERPARAMETERS (IDENTICAL FOR ALL"), B(M.PARA, "LEARNING METHODS)")) | |
| assert RP._soft_hyphen("heteroge-", "neous") and not RP._soft_hyphen("peer-to-", "peer") | |
| def test_sections_one_level_too_low_become_sections_and_floats_stay_in_the_column(): | |
| from formatmatch import model as M, pipeline as PL | |
| H = lambda t, lvl: M.Block(M.HEADING, runs=[M.Run(t)], level=lvl, orig=t) | |
| blocks = [M.Block(M.TITLE, runs=[M.Run("A Paper")]), H("Introduction", 2), H("Background", 3), H("Results", 2), | |
| H("References", 1)] | |
| rep = PL.Report() | |
| PL._promote_headings(blocks, rep) | |
| assert [b.level for b in blocks[1:]] == [1, 2, 1, 1] and any("moved up" in c for c in rep.changes) | |
| ok = [H("Introduction", 1), H("Method", 2)] | |
| PL._promote_headings(ok, PL.Report()) | |
| assert [b.level for b in ok] == [1, 2] # a sound outline is left alone | |
| # figure, caption, figure, caption: each caption takes the figure before it | |
| F = lambda n: M.Block(M.FIGURE, image=b"x" + bytes([n]), image_ext="png") | |
| C = lambda n: M.Block(M.CAPTION, runs=[M.Run(f"cap {n}")], cap_kind="figure", cap_num=n, orig=f"Fig. {n}. cap {n}") | |
| f1, c1, f2, c2 = F(1), C(1), F(2), C(2) | |
| out = PL._pair_floats([f1, c1, f2, c2], {"captions": {}}, PL.Report()) | |
| assert [id(x) for x in out] == [id(f1), id(c1), id(f2), id(c2)] | |
| def test_latex_keeps_equation_pictures_and_tables_inside_the_line(): | |
| from formatmatch import refs as R | |
| src = open(os.path.join(os.path.dirname(FMT.__file__), "formatmatch", "render_latex.py"), encoding="utf-8").read() | |
| assert "newcommand{" + chr(92) * 2 + "fmimg}" in src and "newcommand{" + chr(92) * 2 + "fmfit}" in src | |
| assert "includegraphics[height={h" not in src # the fixed-height picture that overflowed the column | |
| r = R.parse_reference("[2] W. Tushar, T.K. Saha, H.V. Poor, Peer-to-peer trading in electricity networks: An " | |
| "overview, IEEE Transactions on Smart Grid 11 (4) (2020) 3185–3200.") | |
| assert r.confident and r.authors[0] == ("Tushar", "W.") and r.container == "IEEE Transactions on Smart Grid" | |
| assert (r.volume, r.issue, r.year, r.pages) == ("11", "4", "2020", "3185–3200") | |
| def test_long_equations_are_fitted_to_the_column_in_latex_and_word(tmp_path): | |
| import io | |
| from PIL import Image | |
| from formatmatch.render_latex import LatexRenderer as LR | |
| assert LR.fit_math("a+b", False) == "\\fmmath{a+b}" | |
| assert LR.fit_math("a+b", True).startswith("\\fmmath[\\dimexpr\\linewidth-3.2em\\relax]{a+b") | |
| pic = "\\vcenter{\\hbox{\\fmimg{9.0pt}{equations/eq1.png}}}" | |
| assert LR.fit_math(pic, True) == pic and LR.fit_math("", False) == "" # pictures fit themselves | |
| # Word: a picture 10 in wide is shrunk to the column; a small one keeps its size | |
| from formatmatch import render_docx as RD | |
| import docx | |
| buf = io.BytesIO(); Image.new("RGB", (2000, 100), "white").save(buf, "PNG") | |
| class Fake: | |
| _col_width_cm = lambda self: 8.0 | |
| _picture = RD.DocxRenderer._picture if hasattr(RD, "DocxRenderer") else None | |
| cls = next(v for v in vars(RD).values() if isinstance(v, type) and hasattr(v, "_picture")) | |
| Fake._picture = cls._picture | |
| d = docx.Document(); p = d.add_paragraph() | |
| Fake()._picture(p, {"blob": buf.getvalue(), "h": 0.5}) # 0.5 in tall -> 10 in wide | |
| Fake()._picture(p, {"blob": buf.getvalue(), "h": 0.05}) # 1 in wide: fits | |
| wide, small = d.inline_shapes[0], d.inline_shapes[1] | |
| assert abs(wide.width.inches - 8.0 / 2.54 * 0.82) < 0.02 and wide.height.inches < 0.2 | |
| assert abs(small.height.inches - 0.05) < 0.005 | |