Rework fetch_bytes and _fetch_pypi_json patches to make testing easier. Various improvements to test_micropip. The main feature is a new fixture
'mock_fetch' with an add_pkg method that takes a package name, a map
from version to requirements, and a choice of platform. This should
hopefully make writing more tests a lot easier (which is good because
we could use more micropip test coverage but we are limited by the
difficulty of writing good tests).

This also adds a fixture to create distinct dummy package names and
enables @pytest.mark.asyncio to handle the async calls rather than
using `asyncio.get_event_loop.run_until_complete`.
import pytest
from pyodide_test_runner.fixture import selenium_context_manager


@pytest.mark.driver_timeout(40)
def test_scikit_learn(selenium_module_scope):
    if selenium_module_scope.browser == "chrome":
        pytest.xfail("Times out in chrome")
    with selenium_context_manager(selenium_module_scope) as selenium:
        selenium.load_package("scikit-learn")
        assert (
            selenium.run(
                """
                import numpy as np
                import sklearn
                from sklearn.linear_model import LogisticRegression

                rng = np.random.RandomState(42)
                X = rng.rand(100, 20)
                y = rng.randint(5, size=100)

                estimator = LogisticRegression(solver='liblinear')
                estimator.fit(X, y)
                print(estimator.predict(X))
                estimator.score(X, y)
                """
            )
            > 0
        )


@pytest.mark.driver_timeout(40)
def test_logistic_regression(selenium_module_scope):
    if selenium_module_scope.browser == "chrome":
        pytest.xfail("Times out in chrome")
    with selenium_context_manager(selenium_module_scope) as selenium:
        selenium.load_package("scikit-learn")
        selenium.run(
            """
            from sklearn.datasets import load_iris
            from sklearn.linear_model import LogisticRegression
            X, y = load_iris(return_X_y=True)
            clf = LogisticRegression(random_state=0).fit(X, y)
            print(clf.predict(X[:2, :]))
            print(clf.predict_proba(X[:2, :]))
            print(clf.score(X, y))
            """
        )

import pytest
from pyodide_test_runner.fixture import selenium_context_manager


@pytest.mark.driver_timeout(40)
def test_scikit_learn(selenium_module_scope):
    if selenium_module_scope.browser == "chrome":
        pytest.xfail("Times out in chrome")
    with selenium_context_manager(selenium_module_scope) as selenium:
        selenium.load_package("scikit-learn")
        assert (
            selenium.run(
                """
                import numpy as np
                import sklearn
                from sklearn.linear_model import LogisticRegression

                rng = np.random.RandomState(42)
                X = rng.rand(100, 20)
                y = rng.randint(5, size=100)

                estimator = LogisticRegression(solver='liblinear')
                estimator.fit(X, y)
                print(estimator.predict(X))
                estimator.score(X, y)
                """
            )
            > 0
        )


@pytest.mark.driver_timeout(40)
def test_logistic_regression(selenium_module_scope):
    if selenium_module_scope.browser == "chrome":
        pytest.xfail("Times out in chrome")
    with selenium_context_manager(selenium_module_scope) as selenium:
        selenium.load_package("scikit-learn")
        selenium.run(
            """
            from sklearn.datasets import load_iris
            from sklearn.linear_model import LogisticRegression
            X, y = load_iris(return_X_y=True)
            clf = LogisticRegression(random_state=0).fit(X, y)
            print(clf.predict(X[:2, :]))
            print(clf.predict_proba(X[:2, :]))
            print(clf.score(X, y))
            """
        )
