diff --git a/.eslintignore b/.eslintignore
new file mode 100644
index 00000000..e7e1fb04
--- /dev/null
+++ b/.eslintignore
@@ -0,0 +1 @@
+tests/*
diff --git a/.eslintrc.js b/.eslintrc.js
new file mode 100644
index 00000000..0fb8699e
--- /dev/null
+++ b/.eslintrc.js
@@ -0,0 +1,3 @@
+module.exports = {
+ "root": true
+}
diff --git a/.gitignore b/.gitignore
index 87ca27ec..20a5d7db 100644
--- a/.gitignore
+++ b/.gitignore
@@ -14,3 +14,9 @@ coverage/*.xml
Pipfile
Pipfile.lock
+
+# Test output files
+tests/N1.mdx
+tests/N2.mdx
+tests/S1.mdx
+tests/provision.js
diff --git a/scripts/preprocess.py b/scripts/preprocess.py
index 199ad994..5d555d2d 100644
--- a/scripts/preprocess.py
+++ b/scripts/preprocess.py
@@ -60,7 +60,7 @@
class Preprocess:
- def __init__(self, args, is_test=False):
+ def __init__(self, args, is_test=False): # pragma: no cover
self.node_to_meta = {}
self.provider_to_meta = {}
self.variants = {}
@@ -185,7 +185,7 @@ def generate_graph(self, lines: iter) -> tuple:
self.node_to_meta[child][node_type].append(parent)
return graph, graph_reverse
- def write_graphs(self, sequence: str, output_dir: str) -> None:
+ def write_graphs(self, sequence: str, output_dir: str) -> None: # pragma: no cover
"""
Parses a csv that specifies node type, the edges between nodes, and node variants
:param sequence: sequence csv
@@ -425,7 +425,9 @@ def _get_node_to_country_provision(self):
node_to_country_provision[node]["all_names"].sort()
return node_to_country_provision
- def _get_country_provision_graph(self, graph, output_dir, node_id):
+ def _get_country_provision_graph(
+ self, graph, output_dir, node_id
+ ): # pragma: no cover
"""
Generate a graph representing country provisions for a node
:return: A dictionary representation of a graph
@@ -544,7 +546,9 @@ def _mk_pdf_for_node(
{"enable-local-file-access": None},
)
- def mk_pdfs(self, nodes_fi: str, stages_fi: str, output_dir: str) -> None:
+ def mk_pdfs(
+ self, nodes_fi: str, stages_fi: str, output_dir: str
+ ) -> None: # pragma: no cover
"""
Generate pdf version of the each node's description
:param nodes_fi: CSV file with node information
@@ -631,7 +635,7 @@ def write_provider_bq_table(self, provider_fi: str):
writer.writerow(line)
return provider_bq_fi
- def write_to_bq(self, nodes_fi, provider_bq_fi):
+ def write_to_bq(self, nodes_fi, provider_bq_fi): # pragma: no cover
"""
Load CSVs to bigquery tables, overwriting the existing tables.
Also loads the CSVs to versioned backup tables.
diff --git a/supply-chain/.eslintrc.js b/supply-chain/.eslintrc.js
index a8f09ae9..9d27fe78 100644
--- a/supply-chain/.eslintrc.js
+++ b/supply-chain/.eslintrc.js
@@ -1,6 +1,7 @@
module.exports = {
"globals": {
__PATH_PREFIX__: true,
+ "fetchMock": true,
},
"env": {
"browser": true,
@@ -12,6 +13,6 @@ module.exports = {
],
"parserOptions": {
"ecmaVersion": "latest",
- "sourceType": "module"
+ "sourceType": "module",
},
}
diff --git a/supply-chain/jest.config.js b/supply-chain/jest.config.js
index 4baea8c1..4df12f68 100644
--- a/supply-chain/jest.config.js
+++ b/supply-chain/jest.config.js
@@ -20,6 +20,7 @@ module.exports = {
collectCoverage: true,
collectCoverageFrom: [
'src/**/*.{js,jsx}',
+ '!src/pages/*',
'!**/__tests__/**',
],
// TBD - we have not decided on these yet
diff --git a/supply-chain/src/components/__tests__/dashboard.js b/supply-chain/src/components/__tests__/dashboard.js
index 632f0125..3abc0c1b 100644
--- a/supply-chain/src/components/__tests__/dashboard.js
+++ b/supply-chain/src/components/__tests__/dashboard.js
@@ -23,6 +23,18 @@ describe("Gradient Legend", () => {
});
describe("Dashboard", () => {
+ beforeEach(() => {
+ window.HTMLElement.prototype.scrollIntoView = function() {};
+ const location = {
+ ...window.location,
+ search: '',
+ };
+ Object.defineProperty(window, 'location', {
+ writable: true,
+ value: location,
+ });
+ })
+
it("renders correctly", () => {
const {asFragment} = render();
expect(asFragment()).toMatchSnapshot();
@@ -64,6 +76,25 @@ describe("Dashboard", () => {
expect(screen.getAllByText("Crystal growing furnaces").length).toEqual(1);
});
+ it("opens a documentation node with variants and subvariants", () => {
+ render();
+ // Click on a node with subvariants
+ fireEvent.click(screen.getByText("Deposition tools"));
+ fireEvent.click(screen.getAllByText("Chemical vapor deposition tools")[0]);
+
+ // Show subvariants list
+ expect(screen.getAllByText("Atomic layer deposition tools").length).toEqual(5);
+ });
+
+ it("opens a stage node", () => {
+ render();
+ // Click on a stage node title
+ fireEvent.click(screen.getByText("Fabrication"));
+
+ // Show stage node text
+ expect(screen.getByText("at the 45 nm node or below", {exact: false})).not.toBeNull();
+ });
+
it("changes the highlighting shown", () => {
render();
// Initially, the nodes are not highlighted
diff --git a/tests/test_N1.mdx b/tests/test_N1.mdx
new file mode 100644
index 00000000..14435e36
--- /dev/null
+++ b/tests/test_N1.mdx
@@ -0,0 +1,3 @@
+#### Logic chip design: Advanced CPUs
+
+Central processing units ("CPUs") are the dominant general purpose logic chips. Two U.S. firms, Intel and AMD, have long held a duopoly over CPUs used for laptops, desktops, and servers. (China has several ventures, though none are competitive with U.S. firms.) CPUs are often classified into "nodes," which represent technology generations: a chip at a new node (e.g., "5 nm‚" released in 2020) contains approximately double the transistor density as a previous node (e.g., "7 nm‚" released in 2018) and is also more cost-effective.
diff --git a/tests/test_preprocess.py b/tests/test_preprocess.py
index 0976176f..d9b08776 100644
--- a/tests/test_preprocess.py
+++ b/tests/test_preprocess.py
@@ -64,6 +64,7 @@ def test_mk_metadata(self):
def test_mk_provider_to_meta(self):
self.maxDiff = None
provider_fi = "./tests/test_providers.csv"
+ provision_fi = "./tests/test_provision.csv"
pp = Preprocess(None, True)
pp.mk_provider_to_meta(provider_fi)
self.assertEqual(
@@ -92,6 +93,12 @@ def test_mk_provider_to_meta(self):
},
},
)
+ pp.write_provision(provision_fi, "tests/")
+
+ output_truth = open("tests/test_provision.js").read()
+ output_testing = open("tests/provision.js").read()
+
+ self.assertEqual(output_testing, output_truth)
def test_get_flag(self):
self.assertEqual("🇺🇸", Preprocess.get_flag("USA"))
@@ -319,3 +326,14 @@ def test_clean_md_link(self):
"Flickr user [FritzchensFritz](https://www.flickr.com/photos/130561288@N04/50914099198/)"
),
)
+
+ def test_write_descriptions(self):
+ pp = Preprocess(None, True)
+ pp.write_descriptions(
+ "./tests/test_input.csv", "./tests/test_stages.csv", "tests/"
+ )
+
+ output_truth = open("tests/test_N1.mdx").read().strip()
+ output_testing = open("tests/N1.mdx").read().strip()
+
+ self.assertEqual(output_testing, output_truth)
diff --git a/tests/test_provision.csv b/tests/test_provision.csv
new file mode 100644
index 00000000..be9808a9
--- /dev/null
+++ b/tests/test_provision.csv
@@ -0,0 +1,3 @@
+provider_name,provider_id,provided_name,provided_id,share_provided,negligible_market_share
+USA,P1,Design,S1,61%,
+USA,P1,Fabrication,S2,27%,
diff --git a/tests/test_provision.js b/tests/test_provision.js
new file mode 100644
index 00000000..ed36b1fa
--- /dev/null
+++ b/tests/test_provision.js
@@ -0,0 +1,8 @@
+const countryProvision={"United States": {"S1": 61, "S2": 27}};
+const countryFlags={"United States": "\ud83c\uddfa\ud83c\uddf8"};
+const countryProvisionConcentration={"S1": 1, "S2": 1};
+const orgProvision={};
+const processNodesWithOrgProvision=[];
+const providerMeta={"P1": {"name": "USA", "type": "country"}, "P2": {"name": "CHN", "type": "country"}, "P4": {"name": "KOR", "type": "country"}, "P9": {"name": "Intel", "type": "organization", "hq_flag": "\ud83c\uddfa\ud83c\uddf8", "hq_country": "United States"}, "P10": {"name": "AMD", "type": "organization", "hq_flag": "\ud83c\uddfa\ud83c\uddf8", "hq_country": "United States"}, "P15": {"name": "Phytium", "type": "organization", "hq_flag": "\ud83c\udde8\ud83c\uddf3", "hq_country": "China (mainland)"}};
+
+export {countryProvision, countryFlags, countryProvisionConcentration, orgProvision, processNodesWithOrgProvision, providerMeta};