From d100203301739213ddb384411d3e9782b9df2877 Mon Sep 17 00:00:00 2001 From: himkt Date: Thu, 25 Sep 2025 21:54:32 +0900 Subject: [PATCH 1/7] chore: run CI with Python 3.13 --- .github/workflows/build-extension.yml | 6 +++--- .github/workflows/test.yml | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/build-extension.yml b/.github/workflows/build-extension.yml index 5512cac9..436b880f 100644 --- a/.github/workflows/build-extension.yml +++ b/.github/workflows/build-extension.yml @@ -23,16 +23,16 @@ jobs: - name: Install Python uses: actions/setup-python@v4 with: - python-version: '3.12' + python-version: '3.13' architecture: 'x64' - name: Setup pip cache uses: actions/cache@v3 with: path: ~/.cache/pip - key: pip-3.12-${{ hashFiles('package.json') }} + key: pip-3.13-${{ hashFiles('package.json') }} restore-keys: | - pip-3.12- + pip-3.13- pip- - name: Get yarn cache directory path diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 6787a061..a137a78d 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -15,7 +15,7 @@ jobs: strategy: matrix: os: [ubuntu-latest, macos-latest] - python-version: ["3.10", "3.11", "3.12"] + python-version: ["3.10", "3.11", "3.12", "3.13"] steps: - name: Checkout nglview repository From 700b68de81d6f225fa29b4e30b19ea25cbd9eedb Mon Sep 17 00:00:00 2001 From: himkt Date: Thu, 2 Oct 2025 18:45:02 +0900 Subject: [PATCH 2/7] debug: skip test_widget --- tests/test_widget.py | 1710 +++++++++++++++++++++--------------------- 1 file changed, 855 insertions(+), 855 deletions(-) diff --git a/tests/test_widget.py b/tests/test_widget.py index 05fa9f09..e9cbbf96 100644 --- a/tests/test_widget.py +++ b/tests/test_widget.py @@ -1,909 +1,909 @@ -import gzip -import os -import unittest -from unittest.mock import MagicMock, patch -from io import StringIO - -import numpy as np -import pytest -from IPython.display import display -from ipywidgets import HBox, IntText -from numpy.testing import assert_almost_equal as aa_eq -from traitlets import TraitError - -import nglview as nv -from nglview import NGLWidget, interpolate, js_utils, widget_utils -from nglview.representation import RepresentationControl -from nglview.utils.py_utils import decode_base64, encode_base64 -from nglview.utils.test_utils import get_mocked_traj -# local -from utils import get_fn -from utils import repr_dict as REPR_DICT - -try: - import simpletraj - has_simpletraj = True -except ImportError: - has_simpletraj = False - -try: - import pytraj as pt - has_pytraj = True -except ImportError: - pt = None - has_pytraj = False - -try: - import mdtraj as md - has_mdtraj = True -except ImportError: - has_mdtraj = False -try: - import parmed as pmd - has_parmed = True -except ImportError: - has_parmed = False - -try: - import MDAnalysis - has_MDAnalysis = True -except ImportError: - has_MDAnalysis = False - -try: - import htmd - has_HTMD = True -except ImportError: - has_HTMD = False - -try: - import ase - has_ase = True -except ImportError: - has_ase = False - -try: - import pymatgen - has_pymatgen = True -except ImportError: - has_pymatgen = False - -try: - import Bio.PDB - has_bio = True -except ImportError: - has_bio = False - -try: - import qcelemental - has_qcelemental = True -except ImportError: - has_qcelemental = False - - -def default_view(): - view = nv.NGLWidget() - view.add_trajectory(get_mocked_traj()) - return view - - -#----------------------------------------------------------------------------- -# NGLView stuff -#----------------------------------------------------------------------------- - -DEFAULT_REPR = [{ - 'params': { - 'sele': 'polymer' - }, - 'type': 'cartoon' -}, { - 'params': { - 'sele': 'hetero OR mol' - }, - 'type': 'ball+stick' -}, { - "type": "ball+stick", - "params": { - "sele": "not protein and not nucleic" - } -}] - - -def _assert_dict_list_equal(listdict0, listdict1): - for (dict0, dict1) in zip(listdict0, listdict1): - for (key0, key1) in zip(sorted(dict0.keys()), sorted(dict1.keys())): - assert key0 == key1 - assert dict0.get(key0) == dict1.get(key1) - - -def test_API_promise_to_have(): - - # for Jupyter notebook extension - nv._jupyter_nbextension_paths() - - view = nv.demo() - - # trigger _set_size - with patch.object(view, '_remote_call') as mock_call: - view.layout.width = '100px' - view.layout.height = '500px' - mock_call.assert_called_with('setSize', - args=['', '500px'], - target='Widget') - - # Structure - structure = nv.Structure() - structure.get_structure_string - assert hasattr(structure, 'id') - assert hasattr(structure, 'ext') - assert hasattr(structure, 'params') - - # Widget - nv.NGLWidget._set_coordinates - - nv.NGLWidget.add_component - nv.NGLWidget.add_trajectory - nv.NGLWidget._coordinates_dict - nv.NGLWidget.set_representations - nv.NGLWidget.clear - nv.NGLWidget.center - - # add component - view.add_component('rcsb://1tsu.pdb') - view.add_pdbid('1tsu') - - # display - js_utils.clean_error_output() - view._display_image() - - # show - try: - nv.show_pdbid('1tsu') - except: - pass - nv.show_url('https://dummy.pdb') - # other backends will be tested in other sections - - # constructor - ngl_traj = get_mocked_traj() - nv.NGLWidget(ngl_traj, parameters=dict(background_color='black')) - nv.NGLWidget(ngl_traj, representations=[dict(type='cartoon', params={})]) - - view.parameters - view.camera - view.camera = 'perspective' - view._request_stage_parameters() - view._ngl_repr_dict = REPR_DICT - - view._update_background_color(change=dict(new='blue')) - view.on_loaded(change=dict(new=True)) - view.on_loaded(change=dict(new=False)) - - view._first_time_loaded = False - view - view._first_time_loaded = True - view - view._init_gui = True - view - view._theme = 'dark' - view - - view.display(gui=True, style='ngl') - view.display(gui=False) - view.display(gui=True, style='ipywidgets') - view._set_sync_camera([view]) - view._set_unsync_camera([view]) - view._set_selection('.CA') - view.color_by('atomindex') - representations = [dict(type='cartoon', params=dict())] - view.representations = representations - repr_parameters = dict(opacity=0.3, params=dict()) - view.update_representation(parameters=repr_parameters) - view._remove_representation() - view.clear() - view.add_representation('surface', selection='*', useWorker=True) - view.add_representation('surface', selection='*', component=1) - view.center() - view._on_render_image(change=dict(new='xyz')) - view.render_image() - view.render_image(frame=2) - view.download_image() - - msg = dict(type='request_frame', data=dict()) - view._handle_nglview_custom_msg(None, msg=msg, buffers=[]) - msg = dict(type='repr_parameters', data=dict(name='hello')) - view._handle_nglview_custom_msg(None, msg=msg, buffers=[]) - view.loaded = True - msg = dict(type='request_loaded', data=True) - view._handle_nglview_custom_msg(None, msg=msg, buffers=[]) - view.loaded = False - msg = dict(type='request_loaded', data=True) - view._handle_nglview_custom_msg(None, msg=msg, buffers=[]) - msg = dict(type='all_reprs_info', data=REPR_DICT) - view._handle_nglview_custom_msg(None, msg=msg, buffers=[]) - msg = dict(type='stage_parameters', data=dict()) - view._handle_nglview_custom_msg(None, msg=msg, buffers=[]) - # test negative frame (it will be set to self.count - 1) - view.frame = -1 - msg = dict(type='request_frame', data=dict()) - # async_message - msg = {'type': 'async_message', 'data': 'ok'} - view._handle_nglview_custom_msg(None, msg, []) - # render_image - r = view.render_image() - msg = {'type': 'image_data', 'ID': r.model_id, 'data': b'YmxhIGJsYQ=='} - view._handle_nglview_custom_msg(None, msg, []) - view.loaded = True - view.show_only([ - 0, - ]) - view._js_console() - view._get_full_params() - - # iter - for c in view: - assert isinstance(c, nv.widget.ComponentViewer) - - -@unittest.skipUnless(has_pytraj, 'skip if not having pytraj') -@unittest.skipUnless(has_mdtraj, 'skip if not having mdtraj') -def test_add_trajectory(): - view = nv.NGLWidget(default=False) - - def update_coords(view=view): - view.frame = 1000 - view.frame = 0 - - p_traj = pt.load(nv.datafiles.TRR, nv.datafiles.PDB) - view.add_trajectory(p_traj) - m_traj = md.load(nv.datafiles.XTC, top=nv.datafiles.PDB) - view.add_trajectory(m_traj) - # trigger updating coordinates - update_coords() - assert len(view._coordinates_dict.keys()) == 2 - if has_MDAnalysis: - from MDAnalysis import Universe - mda_traj = Universe(nv.datafiles.PDB, nv.datafiles.TRR) - view.add_trajectory(mda_traj) - update_coords() - assert len(view._coordinates_dict.keys()) == 3 - if has_HTMD: - from htmd import Molecule - htmd_traj = Molecule(nv.datafiles.PDB) - htmd_traj.filter('protein') - view.add_trajectory(htmd_traj) - update_coords() - if has_MDAnalysis: - assert len(view._coordinates_dict.keys()) == 4 - else: - assert len(view._coordinates_dict.keys()) == 3 - - -def test_API_promise_to_have_add_more_backend(): - - @nv.register_backend('dummy') - class MyLovelyClass(nv.Structure, nv.Trajectory): - pass - - assert 'dummy' in nv.BACKENDS - - -def test_handling_n_components_changed(): - view = nv.NGLWidget() - n_traj = get_mocked_traj() - view.add_trajectory(n_traj) - # fake updating n_components and _repr_dict from front-end - view._ngl_repr_dict = REPR_DICT - view.n_components = 1 - view.remove_component(n_traj.id) - # fake updating n_components from front-end - view._ngl_repr_dict = {'c0': {}} - view.n_components = 0 - - -def test_base_adaptor(): - # abstract base class - def func_0(): - nv.Structure().get_structure_string() - - def func_1(): - nv.Trajectory().get_coordinates(1) - - def func_2(): - nv.Trajectory().n_frames - - pytest.raises(NotImplementedError, func_0) - pytest.raises(NotImplementedError, func_1) - pytest.raises(NotImplementedError, func_2) - - -def test_coordinates_dict(): - traj = get_mocked_traj() - view = nv.NGLWidget(traj) - view.frame = 1 - coords = view._coordinates_dict[0] - aa_eq(coords, traj.get_coordinates(1)) - - # dummy - view._send_binary = False - view._coordinates_dict = {0: coords} - # increase coverage for IndexError: make index=1000 (which is larger than n_frames) - view._set_coordinates(1000) - - -def test_load_data(): - view = default_view() - - # load blob with ext - blob = open(nv.datafiles.PDB).read() - view._load_data(blob, ext='pdb') - - # raise if passing blob but does not provide ext - with pytest.raises(ValueError): - view._load_data(blob) - - # raise if passing dummy name - - with pytest.raises( - ValueError, - match= - 'you must provide file extension if using file-like object or text content' - ): - view._load_data("hahahaha") - - # load PyTrajectory - t0 = get_mocked_traj() - view._load_data(t0) - - # load current folder - view._load_data(get_fn('tz2.pdb')) - - -def test_representations(): - view = default_view() - view.representations = DEFAULT_REPR - view.add_cartoon() - representations_2 = DEFAULT_REPR[:] - representations_2.append({'type': 'cartoon', 'params': {'sele': 'all'}}) - _assert_dict_list_equal(view.representations, representations_2) +# import gzip +# import os +# import unittest +# from unittest.mock import MagicMock, patch +# from io import StringIO + +# import numpy as np +# import pytest +# from IPython.display import display +# from ipywidgets import HBox, IntText +# from numpy.testing import assert_almost_equal as aa_eq +# from traitlets import TraitError + +# import nglview as nv +# from nglview import NGLWidget, interpolate, js_utils, widget_utils +# from nglview.representation import RepresentationControl +# from nglview.utils.py_utils import decode_base64, encode_base64 +# from nglview.utils.test_utils import get_mocked_traj +# # local +# from utils import get_fn +# from utils import repr_dict as REPR_DICT + +# try: +# import simpletraj +# has_simpletraj = True +# except ImportError: +# has_simpletraj = False + +# try: +# import pytraj as pt +# has_pytraj = True +# except ImportError: +# pt = None +# has_pytraj = False + +# try: +# import mdtraj as md +# has_mdtraj = True +# except ImportError: +# has_mdtraj = False +# try: +# import parmed as pmd +# has_parmed = True +# except ImportError: +# has_parmed = False + +# try: +# import MDAnalysis +# has_MDAnalysis = True +# except ImportError: +# has_MDAnalysis = False + +# try: +# import htmd +# has_HTMD = True +# except ImportError: +# has_HTMD = False + +# try: +# import ase +# has_ase = True +# except ImportError: +# has_ase = False + +# try: +# import pymatgen +# has_pymatgen = True +# except ImportError: +# has_pymatgen = False + +# try: +# import Bio.PDB +# has_bio = True +# except ImportError: +# has_bio = False + +# try: +# import qcelemental +# has_qcelemental = True +# except ImportError: +# has_qcelemental = False + + +# def default_view(): +# view = nv.NGLWidget() +# view.add_trajectory(get_mocked_traj()) +# return view + + +# #----------------------------------------------------------------------------- +# # NGLView stuff +# #----------------------------------------------------------------------------- + +# DEFAULT_REPR = [{ +# 'params': { +# 'sele': 'polymer' +# }, +# 'type': 'cartoon' +# }, { +# 'params': { +# 'sele': 'hetero OR mol' +# }, +# 'type': 'ball+stick' +# }, { +# "type": "ball+stick", +# "params": { +# "sele": "not protein and not nucleic" +# } +# }] + + +# def _assert_dict_list_equal(listdict0, listdict1): +# for (dict0, dict1) in zip(listdict0, listdict1): +# for (key0, key1) in zip(sorted(dict0.keys()), sorted(dict1.keys())): +# assert key0 == key1 +# assert dict0.get(key0) == dict1.get(key1) + + +# def test_API_promise_to_have(): + +# # for Jupyter notebook extension +# nv._jupyter_nbextension_paths() + +# view = nv.demo() + +# # trigger _set_size +# with patch.object(view, '_remote_call') as mock_call: +# view.layout.width = '100px' +# view.layout.height = '500px' +# mock_call.assert_called_with('setSize', +# args=['', '500px'], +# target='Widget') + +# # Structure +# structure = nv.Structure() +# structure.get_structure_string +# assert hasattr(structure, 'id') +# assert hasattr(structure, 'ext') +# assert hasattr(structure, 'params') + +# # Widget +# nv.NGLWidget._set_coordinates + +# nv.NGLWidget.add_component +# nv.NGLWidget.add_trajectory +# nv.NGLWidget._coordinates_dict +# nv.NGLWidget.set_representations +# nv.NGLWidget.clear +# nv.NGLWidget.center + +# # add component +# view.add_component('rcsb://1tsu.pdb') +# view.add_pdbid('1tsu') + +# # display +# js_utils.clean_error_output() +# view._display_image() + +# # show +# try: +# nv.show_pdbid('1tsu') +# except: +# pass +# nv.show_url('https://dummy.pdb') +# # other backends will be tested in other sections + +# # constructor +# ngl_traj = get_mocked_traj() +# nv.NGLWidget(ngl_traj, parameters=dict(background_color='black')) +# nv.NGLWidget(ngl_traj, representations=[dict(type='cartoon', params={})]) + +# view.parameters +# view.camera +# view.camera = 'perspective' +# view._request_stage_parameters() +# view._ngl_repr_dict = REPR_DICT + +# view._update_background_color(change=dict(new='blue')) +# view.on_loaded(change=dict(new=True)) +# view.on_loaded(change=dict(new=False)) + +# view._first_time_loaded = False +# view +# view._first_time_loaded = True +# view +# view._init_gui = True +# view +# view._theme = 'dark' +# view + +# view.display(gui=True, style='ngl') +# view.display(gui=False) +# view.display(gui=True, style='ipywidgets') +# view._set_sync_camera([view]) +# view._set_unsync_camera([view]) +# view._set_selection('.CA') +# view.color_by('atomindex') +# representations = [dict(type='cartoon', params=dict())] +# view.representations = representations +# repr_parameters = dict(opacity=0.3, params=dict()) +# view.update_representation(parameters=repr_parameters) +# view._remove_representation() +# view.clear() +# view.add_representation('surface', selection='*', useWorker=True) +# view.add_representation('surface', selection='*', component=1) +# view.center() +# view._on_render_image(change=dict(new='xyz')) +# view.render_image() +# view.render_image(frame=2) +# view.download_image() + +# msg = dict(type='request_frame', data=dict()) +# view._handle_nglview_custom_msg(None, msg=msg, buffers=[]) +# msg = dict(type='repr_parameters', data=dict(name='hello')) +# view._handle_nglview_custom_msg(None, msg=msg, buffers=[]) +# view.loaded = True +# msg = dict(type='request_loaded', data=True) +# view._handle_nglview_custom_msg(None, msg=msg, buffers=[]) +# view.loaded = False +# msg = dict(type='request_loaded', data=True) +# view._handle_nglview_custom_msg(None, msg=msg, buffers=[]) +# msg = dict(type='all_reprs_info', data=REPR_DICT) +# view._handle_nglview_custom_msg(None, msg=msg, buffers=[]) +# msg = dict(type='stage_parameters', data=dict()) +# view._handle_nglview_custom_msg(None, msg=msg, buffers=[]) +# # test negative frame (it will be set to self.count - 1) +# view.frame = -1 +# msg = dict(type='request_frame', data=dict()) +# # async_message +# msg = {'type': 'async_message', 'data': 'ok'} +# view._handle_nglview_custom_msg(None, msg, []) +# # render_image +# r = view.render_image() +# msg = {'type': 'image_data', 'ID': r.model_id, 'data': b'YmxhIGJsYQ=='} +# view._handle_nglview_custom_msg(None, msg, []) +# view.loaded = True +# view.show_only([ +# 0, +# ]) +# view._js_console() +# view._get_full_params() + +# # iter +# for c in view: +# assert isinstance(c, nv.widget.ComponentViewer) + + +# @unittest.skipUnless(has_pytraj, 'skip if not having pytraj') +# @unittest.skipUnless(has_mdtraj, 'skip if not having mdtraj') +# def test_add_trajectory(): +# view = nv.NGLWidget(default=False) + +# def update_coords(view=view): +# view.frame = 1000 +# view.frame = 0 + +# p_traj = pt.load(nv.datafiles.TRR, nv.datafiles.PDB) +# view.add_trajectory(p_traj) +# m_traj = md.load(nv.datafiles.XTC, top=nv.datafiles.PDB) +# view.add_trajectory(m_traj) +# # trigger updating coordinates +# update_coords() +# assert len(view._coordinates_dict.keys()) == 2 +# if has_MDAnalysis: +# from MDAnalysis import Universe +# mda_traj = Universe(nv.datafiles.PDB, nv.datafiles.TRR) +# view.add_trajectory(mda_traj) +# update_coords() +# assert len(view._coordinates_dict.keys()) == 3 +# if has_HTMD: +# from htmd import Molecule +# htmd_traj = Molecule(nv.datafiles.PDB) +# htmd_traj.filter('protein') +# view.add_trajectory(htmd_traj) +# update_coords() +# if has_MDAnalysis: +# assert len(view._coordinates_dict.keys()) == 4 +# else: +# assert len(view._coordinates_dict.keys()) == 3 + + +# def test_API_promise_to_have_add_more_backend(): + +# @nv.register_backend('dummy') +# class MyLovelyClass(nv.Structure, nv.Trajectory): +# pass + +# assert 'dummy' in nv.BACKENDS + + +# def test_handling_n_components_changed(): +# view = nv.NGLWidget() +# n_traj = get_mocked_traj() +# view.add_trajectory(n_traj) +# # fake updating n_components and _repr_dict from front-end +# view._ngl_repr_dict = REPR_DICT +# view.n_components = 1 +# view.remove_component(n_traj.id) +# # fake updating n_components from front-end +# view._ngl_repr_dict = {'c0': {}} +# view.n_components = 0 + + +# def test_base_adaptor(): +# # abstract base class +# def func_0(): +# nv.Structure().get_structure_string() + +# def func_1(): +# nv.Trajectory().get_coordinates(1) + +# def func_2(): +# nv.Trajectory().n_frames + +# pytest.raises(NotImplementedError, func_0) +# pytest.raises(NotImplementedError, func_1) +# pytest.raises(NotImplementedError, func_2) + + +# def test_coordinates_dict(): +# traj = get_mocked_traj() +# view = nv.NGLWidget(traj) +# view.frame = 1 +# coords = view._coordinates_dict[0] +# aa_eq(coords, traj.get_coordinates(1)) + +# # dummy +# view._send_binary = False +# view._coordinates_dict = {0: coords} +# # increase coverage for IndexError: make index=1000 (which is larger than n_frames) +# view._set_coordinates(1000) + + +# def test_load_data(): +# view = default_view() + +# # load blob with ext +# blob = open(nv.datafiles.PDB).read() +# view._load_data(blob, ext='pdb') + +# # raise if passing blob but does not provide ext +# with pytest.raises(ValueError): +# view._load_data(blob) + +# # raise if passing dummy name + +# with pytest.raises( +# ValueError, +# match= +# 'you must provide file extension if using file-like object or text content' +# ): +# view._load_data("hahahaha") + +# # load PyTrajectory +# t0 = get_mocked_traj() +# view._load_data(t0) + +# # load current folder +# view._load_data(get_fn('tz2.pdb')) + + +# def test_representations(): +# view = default_view() +# view.representations = DEFAULT_REPR +# view.add_cartoon() +# representations_2 = DEFAULT_REPR[:] +# representations_2.append({'type': 'cartoon', 'params': {'sele': 'all'}}) +# _assert_dict_list_equal(view.representations, representations_2) - # accept dict too (to specify seperate reprs for different component - def func(): - view.representations = {'0': MagicMock()} +# # accept dict too (to specify seperate reprs for different component +# def func(): +# view.representations = {'0': MagicMock()} - # Representations - # make fake params - try: - view._ngl_repr_dict = {'c0': {'0': {'parameters': {}}}} - except (KeyError, TraitError): - # in real application, we are not allowed to assign values - pass +# # Representations +# # make fake params +# try: +# view._ngl_repr_dict = {'c0': {'0': {'parameters': {}}}} +# except (KeyError, TraitError): +# # in real application, we are not allowed to assign values +# pass - view._ngl_repr_dict = REPR_DICT - representation_widget = RepresentationControl(view, 0, 0) - representation_widget - representation_widget._on_parameters_changed(change=dict(new=dict())) +# view._ngl_repr_dict = REPR_DICT +# representation_widget = RepresentationControl(view, 0, 0) +# representation_widget +# representation_widget._on_parameters_changed(change=dict(new=dict())) -def test_representation_control(): - view = nv.demo() - repr_control = view._display_repr() +# def test_representation_control(): +# view = nv.demo() +# repr_control = view._display_repr() - repr_control.name = 'surface' - repr_control.name = 'cartoon' - repr_control.repr_index = 1 - repr_control.component_index = 1 +# repr_control.name = 'surface' +# repr_control.name = 'cartoon' +# repr_control.repr_index = 1 +# repr_control.component_index = 1 -def test_add_repr_shortcut(): - view = default_view() - assert isinstance(view, nv.NGLWidget), 'must be instance of NGLWidget' +# def test_add_repr_shortcut(): +# view = default_view() +# assert isinstance(view, nv.NGLWidget), 'must be instance of NGLWidget' - # add - view.add_cartoon(color='residueindex') - view.add_rope(color='red') +# # add +# view.add_cartoon(color='residueindex') +# view.add_rope(color='red') - # update - view.update_cartoon(opacity=0.4) - view.update_rope(coor='blue') +# # update +# view.update_cartoon(opacity=0.4) +# view.update_rope(coor='blue') - # remove - view.remove_cartoon() - view.remove_rope() +# # remove +# view.remove_cartoon() +# view.remove_rope() -def test_color_scheme(): - view = nv.demo() - scheme = nv.color._ColorScheme([['red', '1-6'], ['yellow', '20-30']], - 'what') - view.clear() - view.add_cartoon(color=scheme) +# def test_color_scheme(): +# view = nv.demo() +# scheme = nv.color._ColorScheme([['red', '1-6'], ['yellow', '20-30']], +# 'what') +# view.clear() +# view.add_cartoon(color=scheme) -def test_add_new_shape(): - view = nv.NGLWidget() - sphere = ('sphere', [0, 0, 9], [1, 0, 0], 1.5) - arrow = ('arrow', [1, 2, 7], [30, 3, 3], [1, 0, 1], 1.0) - c0 = view._add_shape([sphere, arrow], name='my_shape') +# def test_add_new_shape(): +# view = nv.NGLWidget() +# sphere = ('sphere', [0, 0, 9], [1, 0, 0], 1.5) +# arrow = ('arrow', [1, 2, 7], [30, 3, 3], [1, 0, 1], 1.0) +# c0 = view._add_shape([sphere, arrow], name='my_shape') - # Shape - c1 = view.shape.add_arrow([1, 2, 7], [30, 3, 3], [1, 0, 1], 1.0) - assert len(view._ngl_component_ids) == 2 - view.remove_component(c0) - assert len(view._ngl_component_ids) == 1 +# # Shape +# c1 = view.shape.add_arrow([1, 2, 7], [30, 3, 3], [1, 0, 1], 1.0) +# assert len(view._ngl_component_ids) == 2 +# view.remove_component(c0) +# assert len(view._ngl_component_ids) == 1 - view.remove_component(c1) - assert len(view._ngl_component_ids) == 0 +# view.remove_component(c1) +# assert len(view._ngl_component_ids) == 0 -def test_add_buffer(): - view = nv.NGLWidget() - view - kwargs = { - "position": [0, 0, 0, 1, 1, 1], - "color": [1, 0, 0, 255, 0, 0], - "radius": [1., 2.] - } +# def test_add_buffer(): +# view = nv.NGLWidget() +# view +# kwargs = { +# "position": [0, 0, 0, 1, 1, 1], +# "color": [1, 0, 0, 255, 0, 0], +# "radius": [1., 2.] +# } - view.shape.add_buffer('sphere', **kwargs) +# view.shape.add_buffer('sphere', **kwargs) -def test_remote_call(): - # how to test JS? - view = default_view() - view._remote_call('centerView', target='stage') +# def test_remote_call(): +# # how to test JS? +# view = default_view() +# view._remote_call('centerView', target='stage') - fn = 'notebooks/tz2.pdb' - kwargs = {'defaultRepresentation': True} - view._remote_call('loadFile', target='stage', args=[ - fn, - ], kwargs=kwargs) +# fn = 'notebooks/tz2.pdb' +# kwargs = {'defaultRepresentation': True} +# view._remote_call('loadFile', target='stage', args=[ +# fn, +# ], kwargs=kwargs) -def test_download_image(): - """just make sure it can be called - """ - view = default_view() - view.download_image('myname.png', 2, False, False, True) +# def test_download_image(): +# """just make sure it can be called +# """ +# view = default_view() +# view.download_image('myname.png', 2, False, False, True) -def test_show_structure_file(): - view = nv.show_structure_file(nv.datafiles.PDB) +# def test_show_structure_file(): +# view = nv.show_structure_file(nv.datafiles.PDB) -def test_show_file(): - view = nv.show_file(nv.datafiles.PDB) +# def test_show_file(): +# view = nv.show_file(nv.datafiles.PDB) -def test_show_text(): - text = open(nv.datafiles.PDB).read() - nv.show_text(text) +# def test_show_text(): +# text = open(nv.datafiles.PDB).read() +# nv.show_text(text) -@pytest.mark.skipif(not has_ase, reason='skip if not having ase') -def test_show_ase(): - from ase import Atom, Atoms - dimer = Atoms([Atom('X', (0, 0, 0)), Atom('X', (0, 0, 1))]) - dimer.set_positions([(1, 2, 3), (4, 5, 6.2)]) - nv.show_ase(dimer) +# @pytest.mark.skipif(not has_ase, reason='skip if not having ase') +# def test_show_ase(): +# from ase import Atom, Atoms +# dimer = Atoms([Atom('X', (0, 0, 0)), Atom('X', (0, 0, 1))]) +# dimer.set_positions([(1, 2, 3), (4, 5, 6.2)]) +# nv.show_ase(dimer) -@pytest.mark.skipif(not has_pymatgen, reason='skip if not having pymatgen') -def test_show_pymatgen(): - from pymatgen.core import Lattice, Structure - lattice = Lattice.cubic(4.2) - structure = Structure(lattice, ["Cs", "Cl"], [[0, 0, 0], [0.5, 0.5, 0.5]]) - view = nv.show_pymatgen(structure) - view +# @pytest.mark.skipif(not has_pymatgen, reason='skip if not having pymatgen') +# def test_show_pymatgen(): +# from pymatgen.core import Lattice, Structure +# lattice = Lattice.cubic(4.2) +# structure = Structure(lattice, ["Cs", "Cl"], [[0, 0, 0], [0.5, 0.5, 0.5]]) +# view = nv.show_pymatgen(structure) +# view -@pytest.mark.skipif(not has_qcelemental, - reason='skip if not having qcelemental') -def test_show_qcelemental(): - import qcelemental as qcel +# @pytest.mark.skipif(not has_qcelemental, +# reason='skip if not having qcelemental') +# def test_show_qcelemental(): +# import qcelemental as qcel - mol = qcel.models.Molecule.from_data("He 0 0 0") - view = nv.show_qcelemental(mol) - view +# mol = qcel.models.Molecule.from_data("He 0 0 0") +# view = nv.show_qcelemental(mol) +# view -@pytest.mark.skipif(not has_bio, reason='skip if not having biopython') -def test_show_biopython(): - from Bio.PDB import PDBParser - parser = PDBParser() - structure = parser.get_structure('protein', nv.datafiles.PDB) - nv.show_biopython(structure) +# @pytest.mark.skipif(not has_bio, reason='skip if not having biopython') +# def test_show_biopython(): +# from Bio.PDB import PDBParser +# parser = PDBParser() +# structure = parser.get_structure('protein', nv.datafiles.PDB) +# nv.show_biopython(structure) -@pytest.mark.skipif(not has_simpletraj, reason='skip if not having simpletraj') -def test_show_simpletraj(): - traj = nv.SimpletrajTrajectory(nv.datafiles.XTC, nv.datafiles.GRO) - view = nv.show_simpletraj(traj) - view - view.frame = 3 +# @pytest.mark.skipif(not has_simpletraj, reason='skip if not having simpletraj') +# def test_show_simpletraj(): +# traj = nv.SimpletrajTrajectory(nv.datafiles.XTC, nv.datafiles.GRO) +# view = nv.show_simpletraj(traj) +# view +# view.frame = 3 -@pytest.mark.skipif(not has_mdtraj, reason='skip if not having mdtraj') -def test_show_mdtraj(): - import mdtraj as md - traj = md.load(nv.datafiles.PDB) - view = nv.show_mdtraj(traj) +# @pytest.mark.skipif(not has_mdtraj, reason='skip if not having mdtraj') +# def test_show_mdtraj(): +# import mdtraj as md +# traj = md.load(nv.datafiles.PDB) +# view = nv.show_mdtraj(traj) -@pytest.mark.skipif(not has_HTMD, reason='skip if not having HTMD') -def test_show_htmd(): - from htmd import Molecule - fn = nv.datafiles.PDB - traj = Molecule(fn) - view = nv.show_htmd(traj) - # trigger updating cooridnates - view.frame = 100 - index = 0 - view.frame = index - xyz_htmd = np.squeeze(traj.coords[:, :, index]) - aa_eq(view._coordinates_dict[0], xyz_htmd) +# @pytest.mark.skipif(not has_HTMD, reason='skip if not having HTMD') +# def test_show_htmd(): +# from htmd import Molecule +# fn = nv.datafiles.PDB +# traj = Molecule(fn) +# view = nv.show_htmd(traj) +# # trigger updating cooridnates +# view.frame = 100 +# index = 0 +# view.frame = index +# xyz_htmd = np.squeeze(traj.coords[:, :, index]) +# aa_eq(view._coordinates_dict[0], xyz_htmd) -@pytest.mark.skipif(not has_MDAnalysis, reason='skip if not having MDAnalysis') -def test_show_MDAnalysis(): - from MDAnalysis import Universe - tn, fn = nv.datafiles.PDB, nv.datafiles.PDB - u = Universe(fn, tn) - view = nv.show_mdanalysis(u) +# @pytest.mark.skipif(not has_MDAnalysis, reason='skip if not having MDAnalysis') +# def test_show_MDAnalysis(): +# from MDAnalysis import Universe +# tn, fn = nv.datafiles.PDB, nv.datafiles.PDB +# u = Universe(fn, tn) +# view = nv.show_mdanalysis(u) -@pytest.mark.skipif(not has_parmed, reason='skip if not having ParmEd') -def test_show_parmed(): - import parmed as pmd - fn = nv.datafiles.PDB - parm = pmd.load_file(fn) - view = nv.show_parmed(parm) +# @pytest.mark.skipif(not has_parmed, reason='skip if not having ParmEd') +# def test_show_parmed(): +# import parmed as pmd +# fn = nv.datafiles.PDB +# parm = pmd.load_file(fn) +# view = nv.show_parmed(parm) - ngl_traj = nv.ParmEdTrajectory(parm) - ngl_traj.only_save_1st_model = False - ngl_traj.get_structure_string() +# ngl_traj = nv.ParmEdTrajectory(parm) +# ngl_traj.only_save_1st_model = False +# ngl_traj.get_structure_string() -def test_encode_and_decode(): - xyz = np.arange(100).astype('f4') - shape = xyz.shape +# def test_encode_and_decode(): +# xyz = np.arange(100).astype('f4') +# shape = xyz.shape - b64_str = encode_base64(xyz) - new_xyz = decode_base64(b64_str, dtype='f4', shape=shape) - aa_eq(xyz, new_xyz) - - -def test_structure_file(): - for fn in [get_fn('tz2.pdb'), nv.datafiles.GRO]: - content = open(fn, 'r').read() - fs1 = nv.FileStructure(fn) - assert content == fs1.get_structure_string() - - # gz - fn = get_fn('tz2_2.pdb.gz') - fs2 = nv.FileStructure(fn) - content = gzip.open(fn).read() - assert content == fs2.get_structure_string() - - -def test_camelize_parameters(): - view = nv.NGLWidget() - view.parameters = dict(background_color='black') - assert 'backgroundColor' in view._parameters - - -def test_component_for_duck_typing(): - # FIXME: deprecate duck typing? - # syntax looks ugly. - view = NGLWidget() - traj = get_mocked_traj() - - # add 3 components (trajectory is a component) - view.add_component(get_fn('tz2.pdb')) - view.add_component(get_fn('tz2_2.pdb.gz')) - view.add_trajectory(traj) - view.component_0.add_representation('cartoon') - - c0 = view[0] - c1 = view[1] - assert hasattr(view, 'component_0') - assert hasattr(view, 'component_1') - assert hasattr(view, 'trajectory_0') - assert hasattr(view.trajectory_0, 'n_frames') - assert hasattr(view.trajectory_0, 'get_coordinates') - assert hasattr(view.trajectory_0, 'get_structure_string') - - c0.show() - c0.hide() - - # 2 components left - view.remove_component(c0.id) - # c1 become 1st component - assert not hasattr(view, 'component_2') - assert len(view._ngl_component_ids) == 2 - - # negative indexing - assert view[0]._index == c1._index - - -def test_trajectory_show_hide_sending_cooridnates(): - view = NGLWidget() - - traj0 = get_mocked_traj() - traj1 = get_mocked_traj() - - view.add_trajectory(traj0) - view.add_trajectory(traj1) - - for traj in view._trajlist: - assert traj.shown - - view.frame = 1 - - def copy_coordinate_dict(view): - # make copy to avoid memory free - return {k: v.copy() for k, v in view._coordinates_dict.items()} - - coordinates_dict = copy_coordinate_dict(view) - aa_eq(coordinates_dict[0], traj0.get_coordinates(1)) - aa_eq(coordinates_dict[1], traj1.get_coordinates(1)) - - # hide 0 - view.hide([ - 0, - ]) - assert not view._trajlist[0].shown - assert view._trajlist[1].shown - - # update frame so view can update its coordinates - view.frame = 2 - coordinates_dict = copy_coordinate_dict(view) - assert coordinates_dict[0].shape[0] == 0 - aa_eq(coordinates_dict[1], traj1.get_coordinates(2)) - - # hide 0, 1 - view.hide([0, 1]) - assert not view._trajlist[0].shown - assert not view._trajlist[1].shown - view.frame = 3 - coordinates_dict = copy_coordinate_dict(view) - assert coordinates_dict[0].shape[0] == 0 - assert coordinates_dict[1].shape[0] == 0 - - # slicing, show only component 1 - view[1].show() - view.frame = 0 - assert not view._trajlist[0].shown - assert view._trajlist[1].shown - coordinates_dict = copy_coordinate_dict(view) - assert coordinates_dict[0].shape[0] == 0 - aa_eq(coordinates_dict[1], traj1.get_coordinates(0)) - - # show all - view[1].show() - view[0].show() - view.show(indices='all') - view.show(indices=[ - 0, - ]) - view.show(indices=[0, 1]) - view.frame = 1 - assert view._trajlist[1].shown - coordinates_dict = copy_coordinate_dict(view) - aa_eq(coordinates_dict[0], traj0.get_coordinates(1)) - aa_eq(coordinates_dict[1], traj1.get_coordinates(1)) - - # hide all - view[1].hide() - view[0].hide() - view.frame = 2 - assert not view._trajlist[0].shown - assert not view._trajlist[1].shown - coordinates_dict = copy_coordinate_dict(view) - assert coordinates_dict[0].shape[0] == 0 - assert coordinates_dict[1].shape[0] == 0 - - -def test_existing_js_files(): - from glob import glob - jsfiles = glob(os.path.join(os.path.dirname(nv.__file__), 'nbextension', '*js')) - mapfiles = glob(os.path.join(os.path.dirname(nv.__file__), 'nbextension', '*map')) - - assert len(jsfiles) == 2 - assert len(mapfiles) == 1 - - -def test_add_structure(): - view = nv.NGLWidget() - with pytest.raises(ValueError): - # raise if not is instance of nv.Structure - view.add_structure(nv.datafiles.PDB) - - -def test_add_struture_then_trajectory(): - view = nv.show_structure_file(get_fn('tz2.pdb')) - view.loaded = True - traj = get_mocked_traj() - view.add_trajectory(traj) - view.frame = 3 - coords = view._coordinates_dict[1].copy() - expected = traj.get_coordinates(3) - aa_eq(coords, expected) - view.loaded = False - view.add_trajectory(traj) - - -def test_loaded_attribute(): - traj = get_mocked_traj() - structure = nv.FileStructure(nv.datafiles.PDB) - - # False, empty constructor - view = nv.NGLWidget() - view.loaded = False - view.add_structure(structure) - view.add_trajectory(traj) - view - - # False, constructor with a single Structure - view = nv.NGLWidget(structure) - view.loaded = False - view.add_trajectory(traj) - view - - # True - view = nv.NGLWidget() - view.loaded = True - view.add_structure(structure) - view.add_trajectory(traj) - view - - # False then True, empty constructor - view = nv.NGLWidget() - view.loaded = False - view.add_structure(structure) - view.loaded = True - view.add_trajectory(traj) - view - - # False then True, constructor with a Trajectory - view = nv.NGLWidget(traj) - view.loaded = False - view.add_structure(structure) - view.loaded = True - view.add_trajectory(traj) - view - - -def test_widget_utils(): - box = HBox() - i0 = IntText() - i0._ngl_name = 'i0' - i1 = IntText() - i1._ngl_name = 'i1' - box.children = [i0, i1] - - assert i0 is widget_utils.get_widget_by_name(box, 'i0') - assert i1 is widget_utils.get_widget_by_name(box, 'i1') - - box.children = [i1, i0] - assert i0 is widget_utils.get_widget_by_name(box, 'i0') - assert i1 is widget_utils.get_widget_by_name(box, 'i1') - - assert widget_utils.get_widget_by_name(box, 'i100') is None - assert widget_utils.get_widget_by_name(None, 'i100') is None - - -def test_adaptor_raise(): - with pytest.raises(ValueError): - nv.FileStructure('hellotheredda.pdb') - - -def test_theme(): - from nglview import theme - # FIXME: fill me - - -def test_interpolate(): - # dummy test - traj = get_mocked_traj() - interpolate.linear(0, 0.4, traj, step=1) - - -def dummy_test_to_increase_coverage(): - nv.__version__ - - -def test_viewer_control(): - view = nv.demo() - view - - mat = [11, 12, 13, 14, 21, 22, 23, 24, 31, 32, 33, 34, 41, 42, 43, 44] - - vector = [0, 1, 2] - - view.control.align(mat) - view.control.rotate(mat) - view.control.translate(vector) - view.control.apply_matrix(mat) - view.control.center(vector) - view.control.orient(mat) - view.control.zoom(0.3) - view.control.rotate(mat) - view.control.spin(vector, 0.1) - - -def test_queuing_messages(): - view = nv.NGLWidget() - view.add_component(nv.datafiles.PDB) - view.download_image() - view - assert [f._method_name for f in view._callbacks_before_loaded] == \ - [ - 'loadFile', - '_downloadImage'] - assert [f['methodName'] for f in view._ngl_msg_archive] == \ - ['loadFile'] - - # display 2nd time - view - assert [f['methodName'] for f in view._ngl_msg_archive] == \ - ['loadFile'] - - -@patch('nglview.NGLWidget._unset_serialization') -def test_write_html(mock_unset): - from nglview.color import ColormakerRegistry as cm - from nglview.theme import ThemeManager - import ipywidgets.embed as embed - - tm = ThemeManager() - traj0 = get_mocked_traj() - traj1 = get_mocked_traj() - view = nv.NGLWidget() - view.add_trajectory(traj0) - view.add_trajectory(traj1) - view.gui_style = 'ngl' - view._gui_theme = 'dark' - display(view) - fp = StringIO() - - with patch.object(embed, 'embed_snippet') as mock_embed_snippet: - mock_embed_snippet.return_value = 'ok' - nv.write_html(fp, [view], frame_range=(0, 3)) - mock_embed_snippet.assert_called_with([tm, cm, view]) - mock_unset.assert_called_with() - assert len(view._ngl_coordinate_resource[0]) == 3 - assert len(view._ngl_coordinate_resource[1]) == 3 - - # box - with patch.object(embed, 'embed_snippet') as mock_embed_snippet: - mock_embed_snippet.return_value = 'ok' - nv.write_html(fp, [HBox([view])], frame_range=(0, 3)) - # FIXME: assertion? - - -def test_trim_messages(): - view = nv.demo() - view.remove_component(view[0]) - assert view._ngl_msg_archive == [] - view.add_component(nv.datafiles.ALA3) - assert len(view._ngl_msg_archive) == 1 - assert view._ngl_msg_archive[0]['methodName'] == 'loadFile' - - view = nv.demo() - c = view.add_component(nv.datafiles.ALA3) - view.remove_component(c) - assert len(view._ngl_msg_archive) == 1 - assert view._ngl_msg_archive[0]['methodName'] == 'loadFile' - - -def test_fullscreen(): - v = nv.demo() - fs = nv.widget.Fullscreen(v, [v]) - fs.fullscreen() - with patch.object(v, 'handle_resize'): - fs._fullscreen_changed(MagicMock(new=True, old=False)) - assert v.handle_resize.called - # just run the code - fs._fullscreen_changed(MagicMock(new=True, old=False)) - fs._fullscreen_changed(MagicMock(new=False, old=True)) +# b64_str = encode_base64(xyz) +# new_xyz = decode_base64(b64_str, dtype='f4', shape=shape) +# aa_eq(xyz, new_xyz) + + +# def test_structure_file(): +# for fn in [get_fn('tz2.pdb'), nv.datafiles.GRO]: +# content = open(fn, 'r').read() +# fs1 = nv.FileStructure(fn) +# assert content == fs1.get_structure_string() + +# # gz +# fn = get_fn('tz2_2.pdb.gz') +# fs2 = nv.FileStructure(fn) +# content = gzip.open(fn).read() +# assert content == fs2.get_structure_string() + + +# def test_camelize_parameters(): +# view = nv.NGLWidget() +# view.parameters = dict(background_color='black') +# assert 'backgroundColor' in view._parameters + + +# def test_component_for_duck_typing(): +# # FIXME: deprecate duck typing? +# # syntax looks ugly. +# view = NGLWidget() +# traj = get_mocked_traj() + +# # add 3 components (trajectory is a component) +# view.add_component(get_fn('tz2.pdb')) +# view.add_component(get_fn('tz2_2.pdb.gz')) +# view.add_trajectory(traj) +# view.component_0.add_representation('cartoon') + +# c0 = view[0] +# c1 = view[1] +# assert hasattr(view, 'component_0') +# assert hasattr(view, 'component_1') +# assert hasattr(view, 'trajectory_0') +# assert hasattr(view.trajectory_0, 'n_frames') +# assert hasattr(view.trajectory_0, 'get_coordinates') +# assert hasattr(view.trajectory_0, 'get_structure_string') + +# c0.show() +# c0.hide() + +# # 2 components left +# view.remove_component(c0.id) +# # c1 become 1st component +# assert not hasattr(view, 'component_2') +# assert len(view._ngl_component_ids) == 2 + +# # negative indexing +# assert view[0]._index == c1._index + + +# def test_trajectory_show_hide_sending_cooridnates(): +# view = NGLWidget() + +# traj0 = get_mocked_traj() +# traj1 = get_mocked_traj() + +# view.add_trajectory(traj0) +# view.add_trajectory(traj1) + +# for traj in view._trajlist: +# assert traj.shown + +# view.frame = 1 + +# def copy_coordinate_dict(view): +# # make copy to avoid memory free +# return {k: v.copy() for k, v in view._coordinates_dict.items()} + +# coordinates_dict = copy_coordinate_dict(view) +# aa_eq(coordinates_dict[0], traj0.get_coordinates(1)) +# aa_eq(coordinates_dict[1], traj1.get_coordinates(1)) + +# # hide 0 +# view.hide([ +# 0, +# ]) +# assert not view._trajlist[0].shown +# assert view._trajlist[1].shown + +# # update frame so view can update its coordinates +# view.frame = 2 +# coordinates_dict = copy_coordinate_dict(view) +# assert coordinates_dict[0].shape[0] == 0 +# aa_eq(coordinates_dict[1], traj1.get_coordinates(2)) + +# # hide 0, 1 +# view.hide([0, 1]) +# assert not view._trajlist[0].shown +# assert not view._trajlist[1].shown +# view.frame = 3 +# coordinates_dict = copy_coordinate_dict(view) +# assert coordinates_dict[0].shape[0] == 0 +# assert coordinates_dict[1].shape[0] == 0 + +# # slicing, show only component 1 +# view[1].show() +# view.frame = 0 +# assert not view._trajlist[0].shown +# assert view._trajlist[1].shown +# coordinates_dict = copy_coordinate_dict(view) +# assert coordinates_dict[0].shape[0] == 0 +# aa_eq(coordinates_dict[1], traj1.get_coordinates(0)) + +# # show all +# view[1].show() +# view[0].show() +# view.show(indices='all') +# view.show(indices=[ +# 0, +# ]) +# view.show(indices=[0, 1]) +# view.frame = 1 +# assert view._trajlist[1].shown +# coordinates_dict = copy_coordinate_dict(view) +# aa_eq(coordinates_dict[0], traj0.get_coordinates(1)) +# aa_eq(coordinates_dict[1], traj1.get_coordinates(1)) + +# # hide all +# view[1].hide() +# view[0].hide() +# view.frame = 2 +# assert not view._trajlist[0].shown +# assert not view._trajlist[1].shown +# coordinates_dict = copy_coordinate_dict(view) +# assert coordinates_dict[0].shape[0] == 0 +# assert coordinates_dict[1].shape[0] == 0 + + +# def test_existing_js_files(): +# from glob import glob +# jsfiles = glob(os.path.join(os.path.dirname(nv.__file__), 'nbextension', '*js')) +# mapfiles = glob(os.path.join(os.path.dirname(nv.__file__), 'nbextension', '*map')) + +# assert len(jsfiles) == 2 +# assert len(mapfiles) == 1 + + +# def test_add_structure(): +# view = nv.NGLWidget() +# with pytest.raises(ValueError): +# # raise if not is instance of nv.Structure +# view.add_structure(nv.datafiles.PDB) + + +# def test_add_struture_then_trajectory(): +# view = nv.show_structure_file(get_fn('tz2.pdb')) +# view.loaded = True +# traj = get_mocked_traj() +# view.add_trajectory(traj) +# view.frame = 3 +# coords = view._coordinates_dict[1].copy() +# expected = traj.get_coordinates(3) +# aa_eq(coords, expected) +# view.loaded = False +# view.add_trajectory(traj) + + +# def test_loaded_attribute(): +# traj = get_mocked_traj() +# structure = nv.FileStructure(nv.datafiles.PDB) + +# # False, empty constructor +# view = nv.NGLWidget() +# view.loaded = False +# view.add_structure(structure) +# view.add_trajectory(traj) +# view + +# # False, constructor with a single Structure +# view = nv.NGLWidget(structure) +# view.loaded = False +# view.add_trajectory(traj) +# view + +# # True +# view = nv.NGLWidget() +# view.loaded = True +# view.add_structure(structure) +# view.add_trajectory(traj) +# view + +# # False then True, empty constructor +# view = nv.NGLWidget() +# view.loaded = False +# view.add_structure(structure) +# view.loaded = True +# view.add_trajectory(traj) +# view + +# # False then True, constructor with a Trajectory +# view = nv.NGLWidget(traj) +# view.loaded = False +# view.add_structure(structure) +# view.loaded = True +# view.add_trajectory(traj) +# view + + +# def test_widget_utils(): +# box = HBox() +# i0 = IntText() +# i0._ngl_name = 'i0' +# i1 = IntText() +# i1._ngl_name = 'i1' +# box.children = [i0, i1] + +# assert i0 is widget_utils.get_widget_by_name(box, 'i0') +# assert i1 is widget_utils.get_widget_by_name(box, 'i1') + +# box.children = [i1, i0] +# assert i0 is widget_utils.get_widget_by_name(box, 'i0') +# assert i1 is widget_utils.get_widget_by_name(box, 'i1') + +# assert widget_utils.get_widget_by_name(box, 'i100') is None +# assert widget_utils.get_widget_by_name(None, 'i100') is None + + +# def test_adaptor_raise(): +# with pytest.raises(ValueError): +# nv.FileStructure('hellotheredda.pdb') + + +# def test_theme(): +# from nglview import theme +# # FIXME: fill me + + +# def test_interpolate(): +# # dummy test +# traj = get_mocked_traj() +# interpolate.linear(0, 0.4, traj, step=1) + + +# def dummy_test_to_increase_coverage(): +# nv.__version__ + + +# def test_viewer_control(): +# view = nv.demo() +# view + +# mat = [11, 12, 13, 14, 21, 22, 23, 24, 31, 32, 33, 34, 41, 42, 43, 44] + +# vector = [0, 1, 2] + +# view.control.align(mat) +# view.control.rotate(mat) +# view.control.translate(vector) +# view.control.apply_matrix(mat) +# view.control.center(vector) +# view.control.orient(mat) +# view.control.zoom(0.3) +# view.control.rotate(mat) +# view.control.spin(vector, 0.1) + + +# def test_queuing_messages(): +# view = nv.NGLWidget() +# view.add_component(nv.datafiles.PDB) +# view.download_image() +# view +# assert [f._method_name for f in view._callbacks_before_loaded] == \ +# [ +# 'loadFile', +# '_downloadImage'] +# assert [f['methodName'] for f in view._ngl_msg_archive] == \ +# ['loadFile'] + +# # display 2nd time +# view +# assert [f['methodName'] for f in view._ngl_msg_archive] == \ +# ['loadFile'] + + +# @patch('nglview.NGLWidget._unset_serialization') +# def test_write_html(mock_unset): +# from nglview.color import ColormakerRegistry as cm +# from nglview.theme import ThemeManager +# import ipywidgets.embed as embed + +# tm = ThemeManager() +# traj0 = get_mocked_traj() +# traj1 = get_mocked_traj() +# view = nv.NGLWidget() +# view.add_trajectory(traj0) +# view.add_trajectory(traj1) +# view.gui_style = 'ngl' +# view._gui_theme = 'dark' +# display(view) +# fp = StringIO() + +# with patch.object(embed, 'embed_snippet') as mock_embed_snippet: +# mock_embed_snippet.return_value = 'ok' +# nv.write_html(fp, [view], frame_range=(0, 3)) +# mock_embed_snippet.assert_called_with([tm, cm, view]) +# mock_unset.assert_called_with() +# assert len(view._ngl_coordinate_resource[0]) == 3 +# assert len(view._ngl_coordinate_resource[1]) == 3 + +# # box +# with patch.object(embed, 'embed_snippet') as mock_embed_snippet: +# mock_embed_snippet.return_value = 'ok' +# nv.write_html(fp, [HBox([view])], frame_range=(0, 3)) +# # FIXME: assertion? + + +# def test_trim_messages(): +# view = nv.demo() +# view.remove_component(view[0]) +# assert view._ngl_msg_archive == [] +# view.add_component(nv.datafiles.ALA3) +# assert len(view._ngl_msg_archive) == 1 +# assert view._ngl_msg_archive[0]['methodName'] == 'loadFile' + +# view = nv.demo() +# c = view.add_component(nv.datafiles.ALA3) +# view.remove_component(c) +# assert len(view._ngl_msg_archive) == 1 +# assert view._ngl_msg_archive[0]['methodName'] == 'loadFile' + + +# def test_fullscreen(): +# v = nv.demo() +# fs = nv.widget.Fullscreen(v, [v]) +# fs.fullscreen() +# with patch.object(v, 'handle_resize'): +# fs._fullscreen_changed(MagicMock(new=True, old=False)) +# assert v.handle_resize.called +# # just run the code +# fs._fullscreen_changed(MagicMock(new=True, old=False)) +# fs._fullscreen_changed(MagicMock(new=False, old=True)) From 00779aec1498ad01947a73a5a22bbf7f864a6779 Mon Sep 17 00:00:00 2001 From: himkt Date: Thu, 2 Oct 2025 18:53:50 +0900 Subject: [PATCH 3/7] debug: run test_API_promise_to_have --- tests/test_widget.py | 490 +++++++++++++++++++++---------------------- 1 file changed, 245 insertions(+), 245 deletions(-) diff --git a/tests/test_widget.py b/tests/test_widget.py index e9cbbf96..156c1724 100644 --- a/tests/test_widget.py +++ b/tests/test_widget.py @@ -1,248 +1,248 @@ -# import gzip -# import os -# import unittest -# from unittest.mock import MagicMock, patch -# from io import StringIO - -# import numpy as np -# import pytest -# from IPython.display import display -# from ipywidgets import HBox, IntText -# from numpy.testing import assert_almost_equal as aa_eq -# from traitlets import TraitError - -# import nglview as nv -# from nglview import NGLWidget, interpolate, js_utils, widget_utils -# from nglview.representation import RepresentationControl -# from nglview.utils.py_utils import decode_base64, encode_base64 -# from nglview.utils.test_utils import get_mocked_traj -# # local -# from utils import get_fn -# from utils import repr_dict as REPR_DICT - -# try: -# import simpletraj -# has_simpletraj = True -# except ImportError: -# has_simpletraj = False - -# try: -# import pytraj as pt -# has_pytraj = True -# except ImportError: -# pt = None -# has_pytraj = False - -# try: -# import mdtraj as md -# has_mdtraj = True -# except ImportError: -# has_mdtraj = False -# try: -# import parmed as pmd -# has_parmed = True -# except ImportError: -# has_parmed = False - -# try: -# import MDAnalysis -# has_MDAnalysis = True -# except ImportError: -# has_MDAnalysis = False - -# try: -# import htmd -# has_HTMD = True -# except ImportError: -# has_HTMD = False - -# try: -# import ase -# has_ase = True -# except ImportError: -# has_ase = False - -# try: -# import pymatgen -# has_pymatgen = True -# except ImportError: -# has_pymatgen = False - -# try: -# import Bio.PDB -# has_bio = True -# except ImportError: -# has_bio = False - -# try: -# import qcelemental -# has_qcelemental = True -# except ImportError: -# has_qcelemental = False - - -# def default_view(): -# view = nv.NGLWidget() -# view.add_trajectory(get_mocked_traj()) -# return view - - -# #----------------------------------------------------------------------------- -# # NGLView stuff -# #----------------------------------------------------------------------------- - -# DEFAULT_REPR = [{ -# 'params': { -# 'sele': 'polymer' -# }, -# 'type': 'cartoon' -# }, { -# 'params': { -# 'sele': 'hetero OR mol' -# }, -# 'type': 'ball+stick' -# }, { -# "type": "ball+stick", -# "params": { -# "sele": "not protein and not nucleic" -# } -# }] - - -# def _assert_dict_list_equal(listdict0, listdict1): -# for (dict0, dict1) in zip(listdict0, listdict1): -# for (key0, key1) in zip(sorted(dict0.keys()), sorted(dict1.keys())): -# assert key0 == key1 -# assert dict0.get(key0) == dict1.get(key1) - - -# def test_API_promise_to_have(): - -# # for Jupyter notebook extension -# nv._jupyter_nbextension_paths() - -# view = nv.demo() - -# # trigger _set_size -# with patch.object(view, '_remote_call') as mock_call: -# view.layout.width = '100px' -# view.layout.height = '500px' -# mock_call.assert_called_with('setSize', -# args=['', '500px'], -# target='Widget') - -# # Structure -# structure = nv.Structure() -# structure.get_structure_string -# assert hasattr(structure, 'id') -# assert hasattr(structure, 'ext') -# assert hasattr(structure, 'params') - -# # Widget -# nv.NGLWidget._set_coordinates - -# nv.NGLWidget.add_component -# nv.NGLWidget.add_trajectory -# nv.NGLWidget._coordinates_dict -# nv.NGLWidget.set_representations -# nv.NGLWidget.clear -# nv.NGLWidget.center - -# # add component -# view.add_component('rcsb://1tsu.pdb') -# view.add_pdbid('1tsu') - -# # display -# js_utils.clean_error_output() -# view._display_image() - -# # show -# try: -# nv.show_pdbid('1tsu') -# except: -# pass -# nv.show_url('https://dummy.pdb') -# # other backends will be tested in other sections - -# # constructor -# ngl_traj = get_mocked_traj() -# nv.NGLWidget(ngl_traj, parameters=dict(background_color='black')) -# nv.NGLWidget(ngl_traj, representations=[dict(type='cartoon', params={})]) - -# view.parameters -# view.camera -# view.camera = 'perspective' -# view._request_stage_parameters() -# view._ngl_repr_dict = REPR_DICT - -# view._update_background_color(change=dict(new='blue')) -# view.on_loaded(change=dict(new=True)) -# view.on_loaded(change=dict(new=False)) - -# view._first_time_loaded = False -# view -# view._first_time_loaded = True -# view -# view._init_gui = True -# view -# view._theme = 'dark' -# view - -# view.display(gui=True, style='ngl') -# view.display(gui=False) -# view.display(gui=True, style='ipywidgets') -# view._set_sync_camera([view]) -# view._set_unsync_camera([view]) -# view._set_selection('.CA') -# view.color_by('atomindex') -# representations = [dict(type='cartoon', params=dict())] -# view.representations = representations -# repr_parameters = dict(opacity=0.3, params=dict()) -# view.update_representation(parameters=repr_parameters) -# view._remove_representation() -# view.clear() -# view.add_representation('surface', selection='*', useWorker=True) -# view.add_representation('surface', selection='*', component=1) -# view.center() -# view._on_render_image(change=dict(new='xyz')) -# view.render_image() -# view.render_image(frame=2) -# view.download_image() - -# msg = dict(type='request_frame', data=dict()) -# view._handle_nglview_custom_msg(None, msg=msg, buffers=[]) -# msg = dict(type='repr_parameters', data=dict(name='hello')) -# view._handle_nglview_custom_msg(None, msg=msg, buffers=[]) -# view.loaded = True -# msg = dict(type='request_loaded', data=True) -# view._handle_nglview_custom_msg(None, msg=msg, buffers=[]) -# view.loaded = False -# msg = dict(type='request_loaded', data=True) -# view._handle_nglview_custom_msg(None, msg=msg, buffers=[]) -# msg = dict(type='all_reprs_info', data=REPR_DICT) -# view._handle_nglview_custom_msg(None, msg=msg, buffers=[]) -# msg = dict(type='stage_parameters', data=dict()) -# view._handle_nglview_custom_msg(None, msg=msg, buffers=[]) -# # test negative frame (it will be set to self.count - 1) -# view.frame = -1 -# msg = dict(type='request_frame', data=dict()) -# # async_message -# msg = {'type': 'async_message', 'data': 'ok'} -# view._handle_nglview_custom_msg(None, msg, []) -# # render_image -# r = view.render_image() -# msg = {'type': 'image_data', 'ID': r.model_id, 'data': b'YmxhIGJsYQ=='} -# view._handle_nglview_custom_msg(None, msg, []) -# view.loaded = True -# view.show_only([ -# 0, -# ]) -# view._js_console() -# view._get_full_params() - -# # iter -# for c in view: -# assert isinstance(c, nv.widget.ComponentViewer) +import gzip +import os +import unittest +from unittest.mock import MagicMock, patch +from io import StringIO + +import numpy as np +import pytest +from IPython.display import display +from ipywidgets import HBox, IntText +from numpy.testing import assert_almost_equal as aa_eq +from traitlets import TraitError + +import nglview as nv +from nglview import NGLWidget, interpolate, js_utils, widget_utils +from nglview.representation import RepresentationControl +from nglview.utils.py_utils import decode_base64, encode_base64 +from nglview.utils.test_utils import get_mocked_traj +# local +from utils import get_fn +from utils import repr_dict as REPR_DICT + +try: + import simpletraj + has_simpletraj = True +except ImportError: + has_simpletraj = False + +try: + import pytraj as pt + has_pytraj = True +except ImportError: + pt = None + has_pytraj = False + +try: + import mdtraj as md + has_mdtraj = True +except ImportError: + has_mdtraj = False +try: + import parmed as pmd + has_parmed = True +except ImportError: + has_parmed = False + +try: + import MDAnalysis + has_MDAnalysis = True +except ImportError: + has_MDAnalysis = False + +try: + import htmd + has_HTMD = True +except ImportError: + has_HTMD = False + +try: + import ase + has_ase = True +except ImportError: + has_ase = False + +try: + import pymatgen + has_pymatgen = True +except ImportError: + has_pymatgen = False + +try: + import Bio.PDB + has_bio = True +except ImportError: + has_bio = False + +try: + import qcelemental + has_qcelemental = True +except ImportError: + has_qcelemental = False + + +def default_view(): + view = nv.NGLWidget() + view.add_trajectory(get_mocked_traj()) + return view + + +#----------------------------------------------------------------------------- +# NGLView stuff +#----------------------------------------------------------------------------- + +DEFAULT_REPR = [{ + 'params': { + 'sele': 'polymer' + }, + 'type': 'cartoon' +}, { + 'params': { + 'sele': 'hetero OR mol' + }, + 'type': 'ball+stick' +}, { + "type": "ball+stick", + "params": { + "sele": "not protein and not nucleic" + } +}] + + +def _assert_dict_list_equal(listdict0, listdict1): + for (dict0, dict1) in zip(listdict0, listdict1): + for (key0, key1) in zip(sorted(dict0.keys()), sorted(dict1.keys())): + assert key0 == key1 + assert dict0.get(key0) == dict1.get(key1) + + +def test_API_promise_to_have(): + + # for Jupyter notebook extension + nv._jupyter_nbextension_paths() + + view = nv.demo() + + # trigger _set_size + with patch.object(view, '_remote_call') as mock_call: + view.layout.width = '100px' + view.layout.height = '500px' + mock_call.assert_called_with('setSize', + args=['', '500px'], + target='Widget') + + # Structure + structure = nv.Structure() + structure.get_structure_string + assert hasattr(structure, 'id') + assert hasattr(structure, 'ext') + assert hasattr(structure, 'params') + + # Widget + nv.NGLWidget._set_coordinates + + nv.NGLWidget.add_component + nv.NGLWidget.add_trajectory + nv.NGLWidget._coordinates_dict + nv.NGLWidget.set_representations + nv.NGLWidget.clear + nv.NGLWidget.center + + # add component + view.add_component('rcsb://1tsu.pdb') + view.add_pdbid('1tsu') + + # display + js_utils.clean_error_output() + view._display_image() + + # show + try: + nv.show_pdbid('1tsu') + except: + pass + nv.show_url('https://dummy.pdb') + # other backends will be tested in other sections + + # constructor + ngl_traj = get_mocked_traj() + nv.NGLWidget(ngl_traj, parameters=dict(background_color='black')) + nv.NGLWidget(ngl_traj, representations=[dict(type='cartoon', params={})]) + + view.parameters + view.camera + view.camera = 'perspective' + view._request_stage_parameters() + view._ngl_repr_dict = REPR_DICT + + view._update_background_color(change=dict(new='blue')) + view.on_loaded(change=dict(new=True)) + view.on_loaded(change=dict(new=False)) + + view._first_time_loaded = False + view + view._first_time_loaded = True + view + view._init_gui = True + view + view._theme = 'dark' + view + + view.display(gui=True, style='ngl') + view.display(gui=False) + view.display(gui=True, style='ipywidgets') + view._set_sync_camera([view]) + view._set_unsync_camera([view]) + view._set_selection('.CA') + view.color_by('atomindex') + representations = [dict(type='cartoon', params=dict())] + view.representations = representations + repr_parameters = dict(opacity=0.3, params=dict()) + view.update_representation(parameters=repr_parameters) + view._remove_representation() + view.clear() + view.add_representation('surface', selection='*', useWorker=True) + view.add_representation('surface', selection='*', component=1) + view.center() + view._on_render_image(change=dict(new='xyz')) + view.render_image() + view.render_image(frame=2) + view.download_image() + + msg = dict(type='request_frame', data=dict()) + view._handle_nglview_custom_msg(None, msg=msg, buffers=[]) + msg = dict(type='repr_parameters', data=dict(name='hello')) + view._handle_nglview_custom_msg(None, msg=msg, buffers=[]) + view.loaded = True + msg = dict(type='request_loaded', data=True) + view._handle_nglview_custom_msg(None, msg=msg, buffers=[]) + view.loaded = False + msg = dict(type='request_loaded', data=True) + view._handle_nglview_custom_msg(None, msg=msg, buffers=[]) + msg = dict(type='all_reprs_info', data=REPR_DICT) + view._handle_nglview_custom_msg(None, msg=msg, buffers=[]) + msg = dict(type='stage_parameters', data=dict()) + view._handle_nglview_custom_msg(None, msg=msg, buffers=[]) + # test negative frame (it will be set to self.count - 1) + view.frame = -1 + msg = dict(type='request_frame', data=dict()) + # async_message + msg = {'type': 'async_message', 'data': 'ok'} + view._handle_nglview_custom_msg(None, msg, []) + # render_image + r = view.render_image() + msg = {'type': 'image_data', 'ID': r.model_id, 'data': b'YmxhIGJsYQ=='} + view._handle_nglview_custom_msg(None, msg, []) + view.loaded = True + view.show_only([ + 0, + ]) + view._js_console() + view._get_full_params() + + # iter + for c in view: + assert isinstance(c, nv.widget.ComponentViewer) # @unittest.skipUnless(has_pytraj, 'skip if not having pytraj') From 0d065b4db72e28ea14c3d8b6a800f1ba18f55182 Mon Sep 17 00:00:00 2001 From: himkt Date: Thu, 2 Oct 2025 19:00:18 +0900 Subject: [PATCH 4/7] debug: run test_add_trajectory --- tests/test_widget.py | 64 ++++++++++++++++++++++---------------------- 1 file changed, 32 insertions(+), 32 deletions(-) diff --git a/tests/test_widget.py b/tests/test_widget.py index 156c1724..604b19a3 100644 --- a/tests/test_widget.py +++ b/tests/test_widget.py @@ -245,38 +245,38 @@ def test_API_promise_to_have(): assert isinstance(c, nv.widget.ComponentViewer) -# @unittest.skipUnless(has_pytraj, 'skip if not having pytraj') -# @unittest.skipUnless(has_mdtraj, 'skip if not having mdtraj') -# def test_add_trajectory(): -# view = nv.NGLWidget(default=False) - -# def update_coords(view=view): -# view.frame = 1000 -# view.frame = 0 - -# p_traj = pt.load(nv.datafiles.TRR, nv.datafiles.PDB) -# view.add_trajectory(p_traj) -# m_traj = md.load(nv.datafiles.XTC, top=nv.datafiles.PDB) -# view.add_trajectory(m_traj) -# # trigger updating coordinates -# update_coords() -# assert len(view._coordinates_dict.keys()) == 2 -# if has_MDAnalysis: -# from MDAnalysis import Universe -# mda_traj = Universe(nv.datafiles.PDB, nv.datafiles.TRR) -# view.add_trajectory(mda_traj) -# update_coords() -# assert len(view._coordinates_dict.keys()) == 3 -# if has_HTMD: -# from htmd import Molecule -# htmd_traj = Molecule(nv.datafiles.PDB) -# htmd_traj.filter('protein') -# view.add_trajectory(htmd_traj) -# update_coords() -# if has_MDAnalysis: -# assert len(view._coordinates_dict.keys()) == 4 -# else: -# assert len(view._coordinates_dict.keys()) == 3 +@unittest.skipUnless(has_pytraj, 'skip if not having pytraj') +@unittest.skipUnless(has_mdtraj, 'skip if not having mdtraj') +def test_add_trajectory(): + view = nv.NGLWidget(default=False) + + def update_coords(view=view): + view.frame = 1000 + view.frame = 0 + + p_traj = pt.load(nv.datafiles.TRR, nv.datafiles.PDB) + view.add_trajectory(p_traj) + m_traj = md.load(nv.datafiles.XTC, top=nv.datafiles.PDB) + view.add_trajectory(m_traj) + # trigger updating coordinates + update_coords() + assert len(view._coordinates_dict.keys()) == 2 + if has_MDAnalysis: + from MDAnalysis import Universe + mda_traj = Universe(nv.datafiles.PDB, nv.datafiles.TRR) + view.add_trajectory(mda_traj) + update_coords() + assert len(view._coordinates_dict.keys()) == 3 + if has_HTMD: + from htmd import Molecule + htmd_traj = Molecule(nv.datafiles.PDB) + htmd_traj.filter('protein') + view.add_trajectory(htmd_traj) + update_coords() + if has_MDAnalysis: + assert len(view._coordinates_dict.keys()) == 4 + else: + assert len(view._coordinates_dict.keys()) == 3 # def test_API_promise_to_have_add_more_backend(): From 3f530d38f9491d3e48afe4b1f44b402d98698014 Mon Sep 17 00:00:00 2001 From: himkt Date: Thu, 2 Oct 2025 19:08:50 +0900 Subject: [PATCH 5/7] debug: run tests except for test_add_trajectory --- tests/test_widget.py | 1216 +++++++++++++++++++++--------------------- 1 file changed, 608 insertions(+), 608 deletions(-) diff --git a/tests/test_widget.py b/tests/test_widget.py index 604b19a3..b24867da 100644 --- a/tests/test_widget.py +++ b/tests/test_widget.py @@ -245,665 +245,665 @@ def test_API_promise_to_have(): assert isinstance(c, nv.widget.ComponentViewer) -@unittest.skipUnless(has_pytraj, 'skip if not having pytraj') -@unittest.skipUnless(has_mdtraj, 'skip if not having mdtraj') -def test_add_trajectory(): - view = nv.NGLWidget(default=False) - - def update_coords(view=view): - view.frame = 1000 - view.frame = 0 - - p_traj = pt.load(nv.datafiles.TRR, nv.datafiles.PDB) - view.add_trajectory(p_traj) - m_traj = md.load(nv.datafiles.XTC, top=nv.datafiles.PDB) - view.add_trajectory(m_traj) - # trigger updating coordinates - update_coords() - assert len(view._coordinates_dict.keys()) == 2 - if has_MDAnalysis: - from MDAnalysis import Universe - mda_traj = Universe(nv.datafiles.PDB, nv.datafiles.TRR) - view.add_trajectory(mda_traj) - update_coords() - assert len(view._coordinates_dict.keys()) == 3 - if has_HTMD: - from htmd import Molecule - htmd_traj = Molecule(nv.datafiles.PDB) - htmd_traj.filter('protein') - view.add_trajectory(htmd_traj) - update_coords() - if has_MDAnalysis: - assert len(view._coordinates_dict.keys()) == 4 - else: - assert len(view._coordinates_dict.keys()) == 3 - - -# def test_API_promise_to_have_add_more_backend(): - -# @nv.register_backend('dummy') -# class MyLovelyClass(nv.Structure, nv.Trajectory): -# pass - -# assert 'dummy' in nv.BACKENDS - - -# def test_handling_n_components_changed(): -# view = nv.NGLWidget() -# n_traj = get_mocked_traj() -# view.add_trajectory(n_traj) -# # fake updating n_components and _repr_dict from front-end -# view._ngl_repr_dict = REPR_DICT -# view.n_components = 1 -# view.remove_component(n_traj.id) -# # fake updating n_components from front-end -# view._ngl_repr_dict = {'c0': {}} -# view.n_components = 0 - - -# def test_base_adaptor(): -# # abstract base class -# def func_0(): -# nv.Structure().get_structure_string() - -# def func_1(): -# nv.Trajectory().get_coordinates(1) - -# def func_2(): -# nv.Trajectory().n_frames - -# pytest.raises(NotImplementedError, func_0) -# pytest.raises(NotImplementedError, func_1) -# pytest.raises(NotImplementedError, func_2) - - -# def test_coordinates_dict(): -# traj = get_mocked_traj() -# view = nv.NGLWidget(traj) -# view.frame = 1 -# coords = view._coordinates_dict[0] -# aa_eq(coords, traj.get_coordinates(1)) - -# # dummy -# view._send_binary = False -# view._coordinates_dict = {0: coords} -# # increase coverage for IndexError: make index=1000 (which is larger than n_frames) -# view._set_coordinates(1000) - - -# def test_load_data(): -# view = default_view() - -# # load blob with ext -# blob = open(nv.datafiles.PDB).read() -# view._load_data(blob, ext='pdb') - -# # raise if passing blob but does not provide ext -# with pytest.raises(ValueError): -# view._load_data(blob) - -# # raise if passing dummy name - -# with pytest.raises( -# ValueError, -# match= -# 'you must provide file extension if using file-like object or text content' -# ): -# view._load_data("hahahaha") - -# # load PyTrajectory -# t0 = get_mocked_traj() -# view._load_data(t0) - -# # load current folder -# view._load_data(get_fn('tz2.pdb')) - - -# def test_representations(): -# view = default_view() -# view.representations = DEFAULT_REPR -# view.add_cartoon() -# representations_2 = DEFAULT_REPR[:] -# representations_2.append({'type': 'cartoon', 'params': {'sele': 'all'}}) -# _assert_dict_list_equal(view.representations, representations_2) +# @unittest.skipUnless(has_pytraj, 'skip if not having pytraj') +# @unittest.skipUnless(has_mdtraj, 'skip if not having mdtraj') +# def test_add_trajectory(): +# view = nv.NGLWidget(default=False) + +# def update_coords(view=view): +# view.frame = 1000 +# view.frame = 0 + +# p_traj = pt.load(nv.datafiles.TRR, nv.datafiles.PDB) +# view.add_trajectory(p_traj) +# m_traj = md.load(nv.datafiles.XTC, top=nv.datafiles.PDB) +# view.add_trajectory(m_traj) +# # trigger updating coordinates +# update_coords() +# assert len(view._coordinates_dict.keys()) == 2 +# if has_MDAnalysis: +# from MDAnalysis import Universe +# mda_traj = Universe(nv.datafiles.PDB, nv.datafiles.TRR) +# view.add_trajectory(mda_traj) +# update_coords() +# assert len(view._coordinates_dict.keys()) == 3 +# if has_HTMD: +# from htmd import Molecule +# htmd_traj = Molecule(nv.datafiles.PDB) +# htmd_traj.filter('protein') +# view.add_trajectory(htmd_traj) +# update_coords() +# if has_MDAnalysis: +# assert len(view._coordinates_dict.keys()) == 4 +# else: +# assert len(view._coordinates_dict.keys()) == 3 + + +def test_API_promise_to_have_add_more_backend(): + + @nv.register_backend('dummy') + class MyLovelyClass(nv.Structure, nv.Trajectory): + pass + + assert 'dummy' in nv.BACKENDS + + +def test_handling_n_components_changed(): + view = nv.NGLWidget() + n_traj = get_mocked_traj() + view.add_trajectory(n_traj) + # fake updating n_components and _repr_dict from front-end + view._ngl_repr_dict = REPR_DICT + view.n_components = 1 + view.remove_component(n_traj.id) + # fake updating n_components from front-end + view._ngl_repr_dict = {'c0': {}} + view.n_components = 0 + + +def test_base_adaptor(): + # abstract base class + def func_0(): + nv.Structure().get_structure_string() + + def func_1(): + nv.Trajectory().get_coordinates(1) + + def func_2(): + nv.Trajectory().n_frames + + pytest.raises(NotImplementedError, func_0) + pytest.raises(NotImplementedError, func_1) + pytest.raises(NotImplementedError, func_2) + + +def test_coordinates_dict(): + traj = get_mocked_traj() + view = nv.NGLWidget(traj) + view.frame = 1 + coords = view._coordinates_dict[0] + aa_eq(coords, traj.get_coordinates(1)) + + # dummy + view._send_binary = False + view._coordinates_dict = {0: coords} + # increase coverage for IndexError: make index=1000 (which is larger than n_frames) + view._set_coordinates(1000) + + +def test_load_data(): + view = default_view() + + # load blob with ext + blob = open(nv.datafiles.PDB).read() + view._load_data(blob, ext='pdb') + + # raise if passing blob but does not provide ext + with pytest.raises(ValueError): + view._load_data(blob) + + # raise if passing dummy name + + with pytest.raises( + ValueError, + match= + 'you must provide file extension if using file-like object or text content' + ): + view._load_data("hahahaha") + + # load PyTrajectory + t0 = get_mocked_traj() + view._load_data(t0) + + # load current folder + view._load_data(get_fn('tz2.pdb')) + + +def test_representations(): + view = default_view() + view.representations = DEFAULT_REPR + view.add_cartoon() + representations_2 = DEFAULT_REPR[:] + representations_2.append({'type': 'cartoon', 'params': {'sele': 'all'}}) + _assert_dict_list_equal(view.representations, representations_2) + + # accept dict too (to specify seperate reprs for different component + def func(): + view.representations = {'0': MagicMock()} + + # Representations + # make fake params + try: + view._ngl_repr_dict = {'c0': {'0': {'parameters': {}}}} + except (KeyError, TraitError): + # in real application, we are not allowed to assign values + pass + + view._ngl_repr_dict = REPR_DICT + representation_widget = RepresentationControl(view, 0, 0) + representation_widget + representation_widget._on_parameters_changed(change=dict(new=dict())) -# # accept dict too (to specify seperate reprs for different component -# def func(): -# view.representations = {'0': MagicMock()} -# # Representations -# # make fake params -# try: -# view._ngl_repr_dict = {'c0': {'0': {'parameters': {}}}} -# except (KeyError, TraitError): -# # in real application, we are not allowed to assign values -# pass +def test_representation_control(): + view = nv.demo() + repr_control = view._display_repr() + + repr_control.name = 'surface' + repr_control.name = 'cartoon' + repr_control.repr_index = 1 + repr_control.component_index = 1 + + +def test_add_repr_shortcut(): + view = default_view() + assert isinstance(view, nv.NGLWidget), 'must be instance of NGLWidget' + + # add + view.add_cartoon(color='residueindex') + view.add_rope(color='red') + + # update + view.update_cartoon(opacity=0.4) + view.update_rope(coor='blue') + + # remove + view.remove_cartoon() + view.remove_rope() + + +def test_color_scheme(): + view = nv.demo() + scheme = nv.color._ColorScheme([['red', '1-6'], ['yellow', '20-30']], + 'what') + view.clear() + view.add_cartoon(color=scheme) + + +def test_add_new_shape(): + view = nv.NGLWidget() + sphere = ('sphere', [0, 0, 9], [1, 0, 0], 1.5) + arrow = ('arrow', [1, 2, 7], [30, 3, 3], [1, 0, 1], 1.0) + c0 = view._add_shape([sphere, arrow], name='my_shape') + + # Shape + c1 = view.shape.add_arrow([1, 2, 7], [30, 3, 3], [1, 0, 1], 1.0) + assert len(view._ngl_component_ids) == 2 + view.remove_component(c0) + assert len(view._ngl_component_ids) == 1 -# view._ngl_repr_dict = REPR_DICT -# representation_widget = RepresentationControl(view, 0, 0) -# representation_widget -# representation_widget._on_parameters_changed(change=dict(new=dict())) + view.remove_component(c1) + assert len(view._ngl_component_ids) == 0 -# def test_representation_control(): -# view = nv.demo() -# repr_control = view._display_repr() +def test_add_buffer(): + view = nv.NGLWidget() + view + kwargs = { + "position": [0, 0, 0, 1, 1, 1], + "color": [1, 0, 0, 255, 0, 0], + "radius": [1., 2.] + } -# repr_control.name = 'surface' -# repr_control.name = 'cartoon' -# repr_control.repr_index = 1 -# repr_control.component_index = 1 + view.shape.add_buffer('sphere', **kwargs) -# def test_add_repr_shortcut(): -# view = default_view() -# assert isinstance(view, nv.NGLWidget), 'must be instance of NGLWidget' +def test_remote_call(): + # how to test JS? + view = default_view() + view._remote_call('centerView', target='stage') -# # add -# view.add_cartoon(color='residueindex') -# view.add_rope(color='red') + fn = 'notebooks/tz2.pdb' + kwargs = {'defaultRepresentation': True} + view._remote_call('loadFile', target='stage', args=[ + fn, + ], kwargs=kwargs) -# # update -# view.update_cartoon(opacity=0.4) -# view.update_rope(coor='blue') -# # remove -# view.remove_cartoon() -# view.remove_rope() +def test_download_image(): + """just make sure it can be called + """ + view = default_view() + view.download_image('myname.png', 2, False, False, True) -# def test_color_scheme(): -# view = nv.demo() -# scheme = nv.color._ColorScheme([['red', '1-6'], ['yellow', '20-30']], -# 'what') -# view.clear() -# view.add_cartoon(color=scheme) +def test_show_structure_file(): + view = nv.show_structure_file(nv.datafiles.PDB) -# def test_add_new_shape(): -# view = nv.NGLWidget() -# sphere = ('sphere', [0, 0, 9], [1, 0, 0], 1.5) -# arrow = ('arrow', [1, 2, 7], [30, 3, 3], [1, 0, 1], 1.0) -# c0 = view._add_shape([sphere, arrow], name='my_shape') +def test_show_file(): + view = nv.show_file(nv.datafiles.PDB) -# # Shape -# c1 = view.shape.add_arrow([1, 2, 7], [30, 3, 3], [1, 0, 1], 1.0) -# assert len(view._ngl_component_ids) == 2 -# view.remove_component(c0) -# assert len(view._ngl_component_ids) == 1 -# view.remove_component(c1) -# assert len(view._ngl_component_ids) == 0 +def test_show_text(): + text = open(nv.datafiles.PDB).read() + nv.show_text(text) -# def test_add_buffer(): -# view = nv.NGLWidget() -# view -# kwargs = { -# "position": [0, 0, 0, 1, 1, 1], -# "color": [1, 0, 0, 255, 0, 0], -# "radius": [1., 2.] -# } +@pytest.mark.skipif(not has_ase, reason='skip if not having ase') +def test_show_ase(): + from ase import Atom, Atoms + dimer = Atoms([Atom('X', (0, 0, 0)), Atom('X', (0, 0, 1))]) + dimer.set_positions([(1, 2, 3), (4, 5, 6.2)]) + nv.show_ase(dimer) -# view.shape.add_buffer('sphere', **kwargs) +@pytest.mark.skipif(not has_pymatgen, reason='skip if not having pymatgen') +def test_show_pymatgen(): + from pymatgen.core import Lattice, Structure + lattice = Lattice.cubic(4.2) + structure = Structure(lattice, ["Cs", "Cl"], [[0, 0, 0], [0.5, 0.5, 0.5]]) + view = nv.show_pymatgen(structure) + view -# def test_remote_call(): -# # how to test JS? -# view = default_view() -# view._remote_call('centerView', target='stage') -# fn = 'notebooks/tz2.pdb' -# kwargs = {'defaultRepresentation': True} -# view._remote_call('loadFile', target='stage', args=[ -# fn, -# ], kwargs=kwargs) +@pytest.mark.skipif(not has_qcelemental, + reason='skip if not having qcelemental') +def test_show_qcelemental(): + import qcelemental as qcel + mol = qcel.models.Molecule.from_data("He 0 0 0") + view = nv.show_qcelemental(mol) + view -# def test_download_image(): -# """just make sure it can be called -# """ -# view = default_view() -# view.download_image('myname.png', 2, False, False, True) +@pytest.mark.skipif(not has_bio, reason='skip if not having biopython') +def test_show_biopython(): + from Bio.PDB import PDBParser + parser = PDBParser() + structure = parser.get_structure('protein', nv.datafiles.PDB) + nv.show_biopython(structure) -# def test_show_structure_file(): -# view = nv.show_structure_file(nv.datafiles.PDB) +@pytest.mark.skipif(not has_simpletraj, reason='skip if not having simpletraj') +def test_show_simpletraj(): + traj = nv.SimpletrajTrajectory(nv.datafiles.XTC, nv.datafiles.GRO) + view = nv.show_simpletraj(traj) + view + view.frame = 3 -# def test_show_file(): -# view = nv.show_file(nv.datafiles.PDB) +@pytest.mark.skipif(not has_mdtraj, reason='skip if not having mdtraj') +def test_show_mdtraj(): + import mdtraj as md + traj = md.load(nv.datafiles.PDB) + view = nv.show_mdtraj(traj) + + +@pytest.mark.skipif(not has_HTMD, reason='skip if not having HTMD') +def test_show_htmd(): + from htmd import Molecule + fn = nv.datafiles.PDB + traj = Molecule(fn) + view = nv.show_htmd(traj) + # trigger updating cooridnates + view.frame = 100 + index = 0 + view.frame = index + xyz_htmd = np.squeeze(traj.coords[:, :, index]) + aa_eq(view._coordinates_dict[0], xyz_htmd) + + +@pytest.mark.skipif(not has_MDAnalysis, reason='skip if not having MDAnalysis') +def test_show_MDAnalysis(): + from MDAnalysis import Universe + tn, fn = nv.datafiles.PDB, nv.datafiles.PDB + u = Universe(fn, tn) + view = nv.show_mdanalysis(u) + + +@pytest.mark.skipif(not has_parmed, reason='skip if not having ParmEd') +def test_show_parmed(): + import parmed as pmd + fn = nv.datafiles.PDB + parm = pmd.load_file(fn) + view = nv.show_parmed(parm) -# def test_show_text(): -# text = open(nv.datafiles.PDB).read() -# nv.show_text(text) + ngl_traj = nv.ParmEdTrajectory(parm) + ngl_traj.only_save_1st_model = False + ngl_traj.get_structure_string() -# @pytest.mark.skipif(not has_ase, reason='skip if not having ase') -# def test_show_ase(): -# from ase import Atom, Atoms -# dimer = Atoms([Atom('X', (0, 0, 0)), Atom('X', (0, 0, 1))]) -# dimer.set_positions([(1, 2, 3), (4, 5, 6.2)]) -# nv.show_ase(dimer) +def test_encode_and_decode(): + xyz = np.arange(100).astype('f4') + shape = xyz.shape + b64_str = encode_base64(xyz) + new_xyz = decode_base64(b64_str, dtype='f4', shape=shape) + aa_eq(xyz, new_xyz) -# @pytest.mark.skipif(not has_pymatgen, reason='skip if not having pymatgen') -# def test_show_pymatgen(): -# from pymatgen.core import Lattice, Structure -# lattice = Lattice.cubic(4.2) -# structure = Structure(lattice, ["Cs", "Cl"], [[0, 0, 0], [0.5, 0.5, 0.5]]) -# view = nv.show_pymatgen(structure) -# view +def test_structure_file(): + for fn in [get_fn('tz2.pdb'), nv.datafiles.GRO]: + content = open(fn, 'r').read() + fs1 = nv.FileStructure(fn) + assert content == fs1.get_structure_string() -# @pytest.mark.skipif(not has_qcelemental, -# reason='skip if not having qcelemental') -# def test_show_qcelemental(): -# import qcelemental as qcel + # gz + fn = get_fn('tz2_2.pdb.gz') + fs2 = nv.FileStructure(fn) + content = gzip.open(fn).read() + assert content == fs2.get_structure_string() -# mol = qcel.models.Molecule.from_data("He 0 0 0") -# view = nv.show_qcelemental(mol) -# view + +def test_camelize_parameters(): + view = nv.NGLWidget() + view.parameters = dict(background_color='black') + assert 'backgroundColor' in view._parameters -# @pytest.mark.skipif(not has_bio, reason='skip if not having biopython') -# def test_show_biopython(): -# from Bio.PDB import PDBParser -# parser = PDBParser() -# structure = parser.get_structure('protein', nv.datafiles.PDB) -# nv.show_biopython(structure) +def test_component_for_duck_typing(): + # FIXME: deprecate duck typing? + # syntax looks ugly. + view = NGLWidget() + traj = get_mocked_traj() + # add 3 components (trajectory is a component) + view.add_component(get_fn('tz2.pdb')) + view.add_component(get_fn('tz2_2.pdb.gz')) + view.add_trajectory(traj) + view.component_0.add_representation('cartoon') -# @pytest.mark.skipif(not has_simpletraj, reason='skip if not having simpletraj') -# def test_show_simpletraj(): -# traj = nv.SimpletrajTrajectory(nv.datafiles.XTC, nv.datafiles.GRO) -# view = nv.show_simpletraj(traj) -# view -# view.frame = 3 + c0 = view[0] + c1 = view[1] + assert hasattr(view, 'component_0') + assert hasattr(view, 'component_1') + assert hasattr(view, 'trajectory_0') + assert hasattr(view.trajectory_0, 'n_frames') + assert hasattr(view.trajectory_0, 'get_coordinates') + assert hasattr(view.trajectory_0, 'get_structure_string') + c0.show() + c0.hide() -# @pytest.mark.skipif(not has_mdtraj, reason='skip if not having mdtraj') -# def test_show_mdtraj(): -# import mdtraj as md -# traj = md.load(nv.datafiles.PDB) -# view = nv.show_mdtraj(traj) + # 2 components left + view.remove_component(c0.id) + # c1 become 1st component + assert not hasattr(view, 'component_2') + assert len(view._ngl_component_ids) == 2 + # negative indexing + assert view[0]._index == c1._index -# @pytest.mark.skipif(not has_HTMD, reason='skip if not having HTMD') -# def test_show_htmd(): -# from htmd import Molecule -# fn = nv.datafiles.PDB -# traj = Molecule(fn) -# view = nv.show_htmd(traj) -# # trigger updating cooridnates -# view.frame = 100 -# index = 0 -# view.frame = index -# xyz_htmd = np.squeeze(traj.coords[:, :, index]) -# aa_eq(view._coordinates_dict[0], xyz_htmd) +def test_trajectory_show_hide_sending_cooridnates(): + view = NGLWidget() -# @pytest.mark.skipif(not has_MDAnalysis, reason='skip if not having MDAnalysis') -# def test_show_MDAnalysis(): -# from MDAnalysis import Universe -# tn, fn = nv.datafiles.PDB, nv.datafiles.PDB -# u = Universe(fn, tn) -# view = nv.show_mdanalysis(u) + traj0 = get_mocked_traj() + traj1 = get_mocked_traj() + view.add_trajectory(traj0) + view.add_trajectory(traj1) -# @pytest.mark.skipif(not has_parmed, reason='skip if not having ParmEd') -# def test_show_parmed(): -# import parmed as pmd -# fn = nv.datafiles.PDB -# parm = pmd.load_file(fn) -# view = nv.show_parmed(parm) + for traj in view._trajlist: + assert traj.shown -# ngl_traj = nv.ParmEdTrajectory(parm) -# ngl_traj.only_save_1st_model = False -# ngl_traj.get_structure_string() + view.frame = 1 + def copy_coordinate_dict(view): + # make copy to avoid memory free + return {k: v.copy() for k, v in view._coordinates_dict.items()} -# def test_encode_and_decode(): -# xyz = np.arange(100).astype('f4') -# shape = xyz.shape + coordinates_dict = copy_coordinate_dict(view) + aa_eq(coordinates_dict[0], traj0.get_coordinates(1)) + aa_eq(coordinates_dict[1], traj1.get_coordinates(1)) -# b64_str = encode_base64(xyz) -# new_xyz = decode_base64(b64_str, dtype='f4', shape=shape) -# aa_eq(xyz, new_xyz) - - -# def test_structure_file(): -# for fn in [get_fn('tz2.pdb'), nv.datafiles.GRO]: -# content = open(fn, 'r').read() -# fs1 = nv.FileStructure(fn) -# assert content == fs1.get_structure_string() - -# # gz -# fn = get_fn('tz2_2.pdb.gz') -# fs2 = nv.FileStructure(fn) -# content = gzip.open(fn).read() -# assert content == fs2.get_structure_string() - - -# def test_camelize_parameters(): -# view = nv.NGLWidget() -# view.parameters = dict(background_color='black') -# assert 'backgroundColor' in view._parameters - - -# def test_component_for_duck_typing(): -# # FIXME: deprecate duck typing? -# # syntax looks ugly. -# view = NGLWidget() -# traj = get_mocked_traj() - -# # add 3 components (trajectory is a component) -# view.add_component(get_fn('tz2.pdb')) -# view.add_component(get_fn('tz2_2.pdb.gz')) -# view.add_trajectory(traj) -# view.component_0.add_representation('cartoon') - -# c0 = view[0] -# c1 = view[1] -# assert hasattr(view, 'component_0') -# assert hasattr(view, 'component_1') -# assert hasattr(view, 'trajectory_0') -# assert hasattr(view.trajectory_0, 'n_frames') -# assert hasattr(view.trajectory_0, 'get_coordinates') -# assert hasattr(view.trajectory_0, 'get_structure_string') - -# c0.show() -# c0.hide() - -# # 2 components left -# view.remove_component(c0.id) -# # c1 become 1st component -# assert not hasattr(view, 'component_2') -# assert len(view._ngl_component_ids) == 2 - -# # negative indexing -# assert view[0]._index == c1._index - - -# def test_trajectory_show_hide_sending_cooridnates(): -# view = NGLWidget() - -# traj0 = get_mocked_traj() -# traj1 = get_mocked_traj() - -# view.add_trajectory(traj0) -# view.add_trajectory(traj1) - -# for traj in view._trajlist: -# assert traj.shown - -# view.frame = 1 - -# def copy_coordinate_dict(view): -# # make copy to avoid memory free -# return {k: v.copy() for k, v in view._coordinates_dict.items()} - -# coordinates_dict = copy_coordinate_dict(view) -# aa_eq(coordinates_dict[0], traj0.get_coordinates(1)) -# aa_eq(coordinates_dict[1], traj1.get_coordinates(1)) - -# # hide 0 -# view.hide([ -# 0, -# ]) -# assert not view._trajlist[0].shown -# assert view._trajlist[1].shown - -# # update frame so view can update its coordinates -# view.frame = 2 -# coordinates_dict = copy_coordinate_dict(view) -# assert coordinates_dict[0].shape[0] == 0 -# aa_eq(coordinates_dict[1], traj1.get_coordinates(2)) - -# # hide 0, 1 -# view.hide([0, 1]) -# assert not view._trajlist[0].shown -# assert not view._trajlist[1].shown -# view.frame = 3 -# coordinates_dict = copy_coordinate_dict(view) -# assert coordinates_dict[0].shape[0] == 0 -# assert coordinates_dict[1].shape[0] == 0 - -# # slicing, show only component 1 -# view[1].show() -# view.frame = 0 -# assert not view._trajlist[0].shown -# assert view._trajlist[1].shown -# coordinates_dict = copy_coordinate_dict(view) -# assert coordinates_dict[0].shape[0] == 0 -# aa_eq(coordinates_dict[1], traj1.get_coordinates(0)) - -# # show all -# view[1].show() -# view[0].show() -# view.show(indices='all') -# view.show(indices=[ -# 0, -# ]) -# view.show(indices=[0, 1]) -# view.frame = 1 -# assert view._trajlist[1].shown -# coordinates_dict = copy_coordinate_dict(view) -# aa_eq(coordinates_dict[0], traj0.get_coordinates(1)) -# aa_eq(coordinates_dict[1], traj1.get_coordinates(1)) - -# # hide all -# view[1].hide() -# view[0].hide() -# view.frame = 2 -# assert not view._trajlist[0].shown -# assert not view._trajlist[1].shown -# coordinates_dict = copy_coordinate_dict(view) -# assert coordinates_dict[0].shape[0] == 0 -# assert coordinates_dict[1].shape[0] == 0 - - -# def test_existing_js_files(): -# from glob import glob -# jsfiles = glob(os.path.join(os.path.dirname(nv.__file__), 'nbextension', '*js')) -# mapfiles = glob(os.path.join(os.path.dirname(nv.__file__), 'nbextension', '*map')) - -# assert len(jsfiles) == 2 -# assert len(mapfiles) == 1 - - -# def test_add_structure(): -# view = nv.NGLWidget() -# with pytest.raises(ValueError): -# # raise if not is instance of nv.Structure -# view.add_structure(nv.datafiles.PDB) - - -# def test_add_struture_then_trajectory(): -# view = nv.show_structure_file(get_fn('tz2.pdb')) -# view.loaded = True -# traj = get_mocked_traj() -# view.add_trajectory(traj) -# view.frame = 3 -# coords = view._coordinates_dict[1].copy() -# expected = traj.get_coordinates(3) -# aa_eq(coords, expected) -# view.loaded = False -# view.add_trajectory(traj) - - -# def test_loaded_attribute(): -# traj = get_mocked_traj() -# structure = nv.FileStructure(nv.datafiles.PDB) - -# # False, empty constructor -# view = nv.NGLWidget() -# view.loaded = False -# view.add_structure(structure) -# view.add_trajectory(traj) -# view - -# # False, constructor with a single Structure -# view = nv.NGLWidget(structure) -# view.loaded = False -# view.add_trajectory(traj) -# view - -# # True -# view = nv.NGLWidget() -# view.loaded = True -# view.add_structure(structure) -# view.add_trajectory(traj) -# view - -# # False then True, empty constructor -# view = nv.NGLWidget() -# view.loaded = False -# view.add_structure(structure) -# view.loaded = True -# view.add_trajectory(traj) -# view - -# # False then True, constructor with a Trajectory -# view = nv.NGLWidget(traj) -# view.loaded = False -# view.add_structure(structure) -# view.loaded = True -# view.add_trajectory(traj) -# view - - -# def test_widget_utils(): -# box = HBox() -# i0 = IntText() -# i0._ngl_name = 'i0' -# i1 = IntText() -# i1._ngl_name = 'i1' -# box.children = [i0, i1] - -# assert i0 is widget_utils.get_widget_by_name(box, 'i0') -# assert i1 is widget_utils.get_widget_by_name(box, 'i1') - -# box.children = [i1, i0] -# assert i0 is widget_utils.get_widget_by_name(box, 'i0') -# assert i1 is widget_utils.get_widget_by_name(box, 'i1') - -# assert widget_utils.get_widget_by_name(box, 'i100') is None -# assert widget_utils.get_widget_by_name(None, 'i100') is None - - -# def test_adaptor_raise(): -# with pytest.raises(ValueError): -# nv.FileStructure('hellotheredda.pdb') - - -# def test_theme(): -# from nglview import theme -# # FIXME: fill me - - -# def test_interpolate(): -# # dummy test -# traj = get_mocked_traj() -# interpolate.linear(0, 0.4, traj, step=1) - - -# def dummy_test_to_increase_coverage(): -# nv.__version__ - - -# def test_viewer_control(): -# view = nv.demo() -# view - -# mat = [11, 12, 13, 14, 21, 22, 23, 24, 31, 32, 33, 34, 41, 42, 43, 44] - -# vector = [0, 1, 2] - -# view.control.align(mat) -# view.control.rotate(mat) -# view.control.translate(vector) -# view.control.apply_matrix(mat) -# view.control.center(vector) -# view.control.orient(mat) -# view.control.zoom(0.3) -# view.control.rotate(mat) -# view.control.spin(vector, 0.1) - - -# def test_queuing_messages(): -# view = nv.NGLWidget() -# view.add_component(nv.datafiles.PDB) -# view.download_image() -# view -# assert [f._method_name for f in view._callbacks_before_loaded] == \ -# [ -# 'loadFile', -# '_downloadImage'] -# assert [f['methodName'] for f in view._ngl_msg_archive] == \ -# ['loadFile'] - -# # display 2nd time -# view -# assert [f['methodName'] for f in view._ngl_msg_archive] == \ -# ['loadFile'] - - -# @patch('nglview.NGLWidget._unset_serialization') -# def test_write_html(mock_unset): -# from nglview.color import ColormakerRegistry as cm -# from nglview.theme import ThemeManager -# import ipywidgets.embed as embed - -# tm = ThemeManager() -# traj0 = get_mocked_traj() -# traj1 = get_mocked_traj() -# view = nv.NGLWidget() -# view.add_trajectory(traj0) -# view.add_trajectory(traj1) -# view.gui_style = 'ngl' -# view._gui_theme = 'dark' -# display(view) -# fp = StringIO() - -# with patch.object(embed, 'embed_snippet') as mock_embed_snippet: -# mock_embed_snippet.return_value = 'ok' -# nv.write_html(fp, [view], frame_range=(0, 3)) -# mock_embed_snippet.assert_called_with([tm, cm, view]) -# mock_unset.assert_called_with() -# assert len(view._ngl_coordinate_resource[0]) == 3 -# assert len(view._ngl_coordinate_resource[1]) == 3 - -# # box -# with patch.object(embed, 'embed_snippet') as mock_embed_snippet: -# mock_embed_snippet.return_value = 'ok' -# nv.write_html(fp, [HBox([view])], frame_range=(0, 3)) -# # FIXME: assertion? - - -# def test_trim_messages(): -# view = nv.demo() -# view.remove_component(view[0]) -# assert view._ngl_msg_archive == [] -# view.add_component(nv.datafiles.ALA3) -# assert len(view._ngl_msg_archive) == 1 -# assert view._ngl_msg_archive[0]['methodName'] == 'loadFile' - -# view = nv.demo() -# c = view.add_component(nv.datafiles.ALA3) -# view.remove_component(c) -# assert len(view._ngl_msg_archive) == 1 -# assert view._ngl_msg_archive[0]['methodName'] == 'loadFile' - - -# def test_fullscreen(): -# v = nv.demo() -# fs = nv.widget.Fullscreen(v, [v]) -# fs.fullscreen() -# with patch.object(v, 'handle_resize'): -# fs._fullscreen_changed(MagicMock(new=True, old=False)) -# assert v.handle_resize.called -# # just run the code -# fs._fullscreen_changed(MagicMock(new=True, old=False)) -# fs._fullscreen_changed(MagicMock(new=False, old=True)) + # hide 0 + view.hide([ + 0, + ]) + assert not view._trajlist[0].shown + assert view._trajlist[1].shown + + # update frame so view can update its coordinates + view.frame = 2 + coordinates_dict = copy_coordinate_dict(view) + assert coordinates_dict[0].shape[0] == 0 + aa_eq(coordinates_dict[1], traj1.get_coordinates(2)) + + # hide 0, 1 + view.hide([0, 1]) + assert not view._trajlist[0].shown + assert not view._trajlist[1].shown + view.frame = 3 + coordinates_dict = copy_coordinate_dict(view) + assert coordinates_dict[0].shape[0] == 0 + assert coordinates_dict[1].shape[0] == 0 + + # slicing, show only component 1 + view[1].show() + view.frame = 0 + assert not view._trajlist[0].shown + assert view._trajlist[1].shown + coordinates_dict = copy_coordinate_dict(view) + assert coordinates_dict[0].shape[0] == 0 + aa_eq(coordinates_dict[1], traj1.get_coordinates(0)) + + # show all + view[1].show() + view[0].show() + view.show(indices='all') + view.show(indices=[ + 0, + ]) + view.show(indices=[0, 1]) + view.frame = 1 + assert view._trajlist[1].shown + coordinates_dict = copy_coordinate_dict(view) + aa_eq(coordinates_dict[0], traj0.get_coordinates(1)) + aa_eq(coordinates_dict[1], traj1.get_coordinates(1)) + + # hide all + view[1].hide() + view[0].hide() + view.frame = 2 + assert not view._trajlist[0].shown + assert not view._trajlist[1].shown + coordinates_dict = copy_coordinate_dict(view) + assert coordinates_dict[0].shape[0] == 0 + assert coordinates_dict[1].shape[0] == 0 + + +def test_existing_js_files(): + from glob import glob + jsfiles = glob(os.path.join(os.path.dirname(nv.__file__), 'nbextension', '*js')) + mapfiles = glob(os.path.join(os.path.dirname(nv.__file__), 'nbextension', '*map')) + + assert len(jsfiles) == 2 + assert len(mapfiles) == 1 + + +def test_add_structure(): + view = nv.NGLWidget() + with pytest.raises(ValueError): + # raise if not is instance of nv.Structure + view.add_structure(nv.datafiles.PDB) + + +def test_add_struture_then_trajectory(): + view = nv.show_structure_file(get_fn('tz2.pdb')) + view.loaded = True + traj = get_mocked_traj() + view.add_trajectory(traj) + view.frame = 3 + coords = view._coordinates_dict[1].copy() + expected = traj.get_coordinates(3) + aa_eq(coords, expected) + view.loaded = False + view.add_trajectory(traj) + + +def test_loaded_attribute(): + traj = get_mocked_traj() + structure = nv.FileStructure(nv.datafiles.PDB) + + # False, empty constructor + view = nv.NGLWidget() + view.loaded = False + view.add_structure(structure) + view.add_trajectory(traj) + view + + # False, constructor with a single Structure + view = nv.NGLWidget(structure) + view.loaded = False + view.add_trajectory(traj) + view + + # True + view = nv.NGLWidget() + view.loaded = True + view.add_structure(structure) + view.add_trajectory(traj) + view + + # False then True, empty constructor + view = nv.NGLWidget() + view.loaded = False + view.add_structure(structure) + view.loaded = True + view.add_trajectory(traj) + view + + # False then True, constructor with a Trajectory + view = nv.NGLWidget(traj) + view.loaded = False + view.add_structure(structure) + view.loaded = True + view.add_trajectory(traj) + view + + +def test_widget_utils(): + box = HBox() + i0 = IntText() + i0._ngl_name = 'i0' + i1 = IntText() + i1._ngl_name = 'i1' + box.children = [i0, i1] + + assert i0 is widget_utils.get_widget_by_name(box, 'i0') + assert i1 is widget_utils.get_widget_by_name(box, 'i1') + + box.children = [i1, i0] + assert i0 is widget_utils.get_widget_by_name(box, 'i0') + assert i1 is widget_utils.get_widget_by_name(box, 'i1') + + assert widget_utils.get_widget_by_name(box, 'i100') is None + assert widget_utils.get_widget_by_name(None, 'i100') is None + + +def test_adaptor_raise(): + with pytest.raises(ValueError): + nv.FileStructure('hellotheredda.pdb') + + +def test_theme(): + from nglview import theme + # FIXME: fill me + + +def test_interpolate(): + # dummy test + traj = get_mocked_traj() + interpolate.linear(0, 0.4, traj, step=1) + + +def dummy_test_to_increase_coverage(): + nv.__version__ + + +def test_viewer_control(): + view = nv.demo() + view + + mat = [11, 12, 13, 14, 21, 22, 23, 24, 31, 32, 33, 34, 41, 42, 43, 44] + + vector = [0, 1, 2] + + view.control.align(mat) + view.control.rotate(mat) + view.control.translate(vector) + view.control.apply_matrix(mat) + view.control.center(vector) + view.control.orient(mat) + view.control.zoom(0.3) + view.control.rotate(mat) + view.control.spin(vector, 0.1) + + +def test_queuing_messages(): + view = nv.NGLWidget() + view.add_component(nv.datafiles.PDB) + view.download_image() + view + assert [f._method_name for f in view._callbacks_before_loaded] == \ + [ + 'loadFile', + '_downloadImage'] + assert [f['methodName'] for f in view._ngl_msg_archive] == \ + ['loadFile'] + + # display 2nd time + view + assert [f['methodName'] for f in view._ngl_msg_archive] == \ + ['loadFile'] + + +@patch('nglview.NGLWidget._unset_serialization') +def test_write_html(mock_unset): + from nglview.color import ColormakerRegistry as cm + from nglview.theme import ThemeManager + import ipywidgets.embed as embed + + tm = ThemeManager() + traj0 = get_mocked_traj() + traj1 = get_mocked_traj() + view = nv.NGLWidget() + view.add_trajectory(traj0) + view.add_trajectory(traj1) + view.gui_style = 'ngl' + view._gui_theme = 'dark' + display(view) + fp = StringIO() + + with patch.object(embed, 'embed_snippet') as mock_embed_snippet: + mock_embed_snippet.return_value = 'ok' + nv.write_html(fp, [view], frame_range=(0, 3)) + mock_embed_snippet.assert_called_with([tm, cm, view]) + mock_unset.assert_called_with() + assert len(view._ngl_coordinate_resource[0]) == 3 + assert len(view._ngl_coordinate_resource[1]) == 3 + + # box + with patch.object(embed, 'embed_snippet') as mock_embed_snippet: + mock_embed_snippet.return_value = 'ok' + nv.write_html(fp, [HBox([view])], frame_range=(0, 3)) + # FIXME: assertion? + + +def test_trim_messages(): + view = nv.demo() + view.remove_component(view[0]) + assert view._ngl_msg_archive == [] + view.add_component(nv.datafiles.ALA3) + assert len(view._ngl_msg_archive) == 1 + assert view._ngl_msg_archive[0]['methodName'] == 'loadFile' + + view = nv.demo() + c = view.add_component(nv.datafiles.ALA3) + view.remove_component(c) + assert len(view._ngl_msg_archive) == 1 + assert view._ngl_msg_archive[0]['methodName'] == 'loadFile' + + +def test_fullscreen(): + v = nv.demo() + fs = nv.widget.Fullscreen(v, [v]) + fs.fullscreen() + with patch.object(v, 'handle_resize'): + fs._fullscreen_changed(MagicMock(new=True, old=False)) + assert v.handle_resize.called + # just run the code + fs._fullscreen_changed(MagicMock(new=True, old=False)) + fs._fullscreen_changed(MagicMock(new=False, old=True)) From bc9f0a8f011fd317af21cdda40e4287f11d7fd6d Mon Sep 17 00:00:00 2001 From: himkt Date: Thu, 2 Oct 2025 20:23:08 +0900 Subject: [PATCH 6/7] chore: restore test_add_trajectory skipping pytraj --- tests/test_widget.py | 64 ++++++++++++++++++++++---------------------- 1 file changed, 32 insertions(+), 32 deletions(-) diff --git a/tests/test_widget.py b/tests/test_widget.py index b24867da..36a05b60 100644 --- a/tests/test_widget.py +++ b/tests/test_widget.py @@ -245,38 +245,38 @@ def test_API_promise_to_have(): assert isinstance(c, nv.widget.ComponentViewer) -# @unittest.skipUnless(has_pytraj, 'skip if not having pytraj') -# @unittest.skipUnless(has_mdtraj, 'skip if not having mdtraj') -# def test_add_trajectory(): -# view = nv.NGLWidget(default=False) - -# def update_coords(view=view): -# view.frame = 1000 -# view.frame = 0 - -# p_traj = pt.load(nv.datafiles.TRR, nv.datafiles.PDB) -# view.add_trajectory(p_traj) -# m_traj = md.load(nv.datafiles.XTC, top=nv.datafiles.PDB) -# view.add_trajectory(m_traj) -# # trigger updating coordinates -# update_coords() -# assert len(view._coordinates_dict.keys()) == 2 -# if has_MDAnalysis: -# from MDAnalysis import Universe -# mda_traj = Universe(nv.datafiles.PDB, nv.datafiles.TRR) -# view.add_trajectory(mda_traj) -# update_coords() -# assert len(view._coordinates_dict.keys()) == 3 -# if has_HTMD: -# from htmd import Molecule -# htmd_traj = Molecule(nv.datafiles.PDB) -# htmd_traj.filter('protein') -# view.add_trajectory(htmd_traj) -# update_coords() -# if has_MDAnalysis: -# assert len(view._coordinates_dict.keys()) == 4 -# else: -# assert len(view._coordinates_dict.keys()) == 3 +@unittest.skipUnless(has_pytraj, 'skip if not having pytraj') +@unittest.skipUnless(has_mdtraj, 'skip if not having mdtraj') +def test_add_trajectory(): + view = nv.NGLWidget(default=False) + + def update_coords(view=view): + view.frame = 1000 + view.frame = 0 + + # p_traj = pt.load(nv.datafiles.TRR, nv.datafiles.PDB) + # view.add_trajectory(p_traj) + m_traj = md.load(nv.datafiles.XTC, top=nv.datafiles.PDB) + view.add_trajectory(m_traj) + # trigger updating coordinates + update_coords() + assert len(view._coordinates_dict.keys()) == 2 - 1 + if has_MDAnalysis: + from MDAnalysis import Universe + mda_traj = Universe(nv.datafiles.PDB, nv.datafiles.TRR) + view.add_trajectory(mda_traj) + update_coords() + assert len(view._coordinates_dict.keys()) == 3 - 1 + if has_HTMD: + from htmd import Molecule + htmd_traj = Molecule(nv.datafiles.PDB) + htmd_traj.filter('protein') + view.add_trajectory(htmd_traj) + update_coords() + if has_MDAnalysis: + assert len(view._coordinates_dict.keys()) == 4 - 1 + else: + assert len(view._coordinates_dict.keys()) == 3 - 1 def test_API_promise_to_have_add_more_backend(): From 26ee544dec0a4b0dab9a69b1e5f34da9e041e298 Mon Sep 17 00:00:00 2001 From: himkt Date: Thu, 2 Oct 2025 23:21:44 +0900 Subject: [PATCH 7/7] chore: skip pytraj for Python 3.13 or later --- tests/test_widget.py | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/tests/test_widget.py b/tests/test_widget.py index 36a05b60..6b17e6ad 100644 --- a/tests/test_widget.py +++ b/tests/test_widget.py @@ -3,6 +3,7 @@ import unittest from unittest.mock import MagicMock, patch from io import StringIO +import sys import numpy as np import pytest @@ -254,19 +255,25 @@ def update_coords(view=view): view.frame = 1000 view.frame = 0 - # p_traj = pt.load(nv.datafiles.TRR, nv.datafiles.PDB) - # view.add_trajectory(p_traj) + # FIXME: remove this workaround. + # https://github.com/nglviewer/nglview/pull/1167#issuecomment-3360759056 + with_pytraj = sys.version_info < (3, 13) + offset = 0 if with_pytraj else 1 + + if with_pytraj: + p_traj = pt.load(nv.datafiles.TRR, nv.datafiles.PDB) + view.add_trajectory(p_traj) m_traj = md.load(nv.datafiles.XTC, top=nv.datafiles.PDB) view.add_trajectory(m_traj) # trigger updating coordinates update_coords() - assert len(view._coordinates_dict.keys()) == 2 - 1 + assert len(view._coordinates_dict.keys()) == 2 - offset if has_MDAnalysis: from MDAnalysis import Universe mda_traj = Universe(nv.datafiles.PDB, nv.datafiles.TRR) view.add_trajectory(mda_traj) update_coords() - assert len(view._coordinates_dict.keys()) == 3 - 1 + assert len(view._coordinates_dict.keys()) == 3 - offset if has_HTMD: from htmd import Molecule htmd_traj = Molecule(nv.datafiles.PDB) @@ -274,9 +281,9 @@ def update_coords(view=view): view.add_trajectory(htmd_traj) update_coords() if has_MDAnalysis: - assert len(view._coordinates_dict.keys()) == 4 - 1 + assert len(view._coordinates_dict.keys()) == 4 - offset else: - assert len(view._coordinates_dict.keys()) == 3 - 1 + assert len(view._coordinates_dict.keys()) == 3 - offset def test_API_promise_to_have_add_more_backend():