`this.X = () => {}` / `this.X = function(){}` in a constructor-style function body must be captured as methods owned by that function. This is the dominant pattern in pre-class JS (DAOs, route handlers): the methods live in the function body, which is otherwise only walked for calls
(tmp_path)
| 749 | |
| 750 | |
| 751 | def test_extract_js_this_assigned_methods(tmp_path): |
| 752 | """`this.X = () => {}` / `this.X = function(){}` in a constructor-style |
| 753 | function body must be captured as methods owned by that function. |
| 754 | |
| 755 | This is the dominant pattern in pre-class JS (DAOs, route handlers): the |
| 756 | methods live in the function body, which is otherwise only walked for |
| 757 | calls, so before this they were entirely invisible as symbols. |
| 758 | """ |
| 759 | from graphify.extract import extract_js |
| 760 | f = tmp_path / "dao.js" |
| 761 | f.write_text( |
| 762 | "function UserDAO(db) {\n" |
| 763 | " this.addUser = (name) => { return name; };\n" |
| 764 | " this.getUser = function(id) { return id; };\n" |
| 765 | "}\n" |
| 766 | ) |
| 767 | result = extract_js(f) |
| 768 | by_label = {n["label"]: n for n in result["nodes"]} |
| 769 | assert "UserDAO()" in by_label |
| 770 | assert ".addUser()" in by_label |
| 771 | assert ".getUser()" in by_label |
| 772 | # The methods are owned by UserDAO via a `method` edge. |
| 773 | owner = by_label["UserDAO()"]["id"] |
| 774 | method_edges = { |
| 775 | (e["source"], by_label_by_id(result, e["target"])) |
| 776 | for e in result["edges"] |
| 777 | if e["relation"] == "method" |
| 778 | } |
| 779 | assert (owner, ".addUser()") in method_edges |
| 780 | assert (owner, ".getUser()") in method_edges |
| 781 | |
| 782 | |
| 783 | def test_extract_js_commonjs_exports_assignment(tmp_path): |
nothing calls this directly
no test coverage detected