def test_iterator(): """Test ImagePathIterator.""" ipi = ImagePathIterator('foo{0}') ipi._stop = 10 with pytest.raises(RuntimeError, match='10 images'): for ii in ipi: pass
def test_save_matplotlib_figures(gallery_conf, ext, req_mpl, req_pil): """Test matplotlib figure save.""" if ext == 'svg': gallery_conf['image_scrapers'] = (matplotlib_svg_scraper(),) import matplotlib.pyplot as plt # nest these so that Agg can be set plt.plot(1, 1) fname_template = os.path.join(gallery_conf['gallery_dir'], 'image{0}.png') image_path_iterator = ImagePathIterator(fname_template) block = ('',) * 3 block_vars = dict(image_path_iterator=image_path_iterator) image_rst = save_figures(block, block_vars, gallery_conf) assert len(image_path_iterator) == 1 fname = '/image1.{0}'.format(ext) assert fname in image_rst fname = gallery_conf['gallery_dir'] + fname assert os.path.isfile(fname) # Test capturing 2 images with shifted start number image_path_iterator.next() image_path_iterator.next() plt.plot(1, 1) plt.figure() plt.plot(1, 1) image_rst = save_figures(block, block_vars, gallery_conf) assert len(image_path_iterator) == 5 for ii in range(4, 6): fname = '/image{0}.{1}'.format(ii, ext) assert fname in image_rst fname = gallery_conf['gallery_dir'] + fname assert os.path.isfile(fname)
def test_output_indentation(gallery_conf): """Test whether indentation of code output is retained.""" compiler = codeop.Compile() test_string = r"\n".join([ " A B", "A 1 2", "B 3 4" ]) code = "print('" + test_string + "')" code_block = ("code", code, 1) script_vars = { "execute_script": True, "image_path_iterator": ImagePathIterator("temp.png"), "src_file": __file__, "memory_delta": [], } output = sg.execute_code_block( compiler, code_block, {}, script_vars, gallery_conf ) output_test_string = "\n".join( [line[4:] for line in output.strip().split("\n")[-3:]] ) assert output_test_string == test_string.replace(r"\n", "\n")
def test_save_mayavi_figures(gallery_conf, req_mpl, req_pil): """Test file naming when saving figures. Requires mayavi.""" Image = _get_image() try: from mayavi import mlab except ImportError: raise pytest.skip('Mayavi not installed') import matplotlib.pyplot as plt mlab.options.offscreen = True gallery_conf.update( image_scrapers=(matplotlib_scraper, mayavi_scraper)) fname_template = os.path.join(gallery_conf['gallery_dir'], 'image{0}.png') image_path_iterator = ImagePathIterator(fname_template) block = ('',) * 3 block_vars = dict(image_path_iterator=image_path_iterator) plt.axes([-0.1, -0.1, 1.2, 1.2]) plt.pcolor([[0]], cmap='Greens') mlab.test_plot3d() image_rst = save_figures(block, block_vars, gallery_conf) assert len(plt.get_fignums()) == 0 assert len(image_path_iterator) == 2 assert '/image0.png' not in image_rst assert '/image1.png' in image_rst assert '/image2.png' in image_rst assert '/image3.png' not in image_rst assert not os.path.isfile(fname_template.format(0)) assert os.path.isfile(fname_template.format(1)) assert os.path.isfile(fname_template.format(2)) assert not os.path.isfile(fname_template.format(0)) with Image.open(fname_template.format(1)) as img: pixels = np.asarray(img.convert("RGB")) assert (pixels == [247, 252, 245]).all() # plt first # Test next-value handling, plus image_scrapers modification gallery_conf.update(image_scrapers=(matplotlib_scraper,)) mlab.test_plot3d() plt.axes([-0.1, -0.1, 1.2, 1.2]) plt.pcolor([[0]], cmap='Reds') image_rst = save_figures(block, block_vars, gallery_conf) assert len(plt.get_fignums()) == 0 assert len(image_path_iterator) == 3 assert '/image1.png' not in image_rst assert '/image2.png' not in image_rst assert '/image3.png' in image_rst assert '/image4.png' not in image_rst assert not os.path.isfile(fname_template.format(0)) for ii in range(3): assert os.path.isfile(fname_template.format(ii + 1)) assert not os.path.isfile(fname_template.format(4)) with Image.open(fname_template.format(3)) as img: pixels = np.asarray(img.convert("RGB")) assert (pixels == [255, 245, 240]).all()
def script_vars(tmpdir): fake_main = importlib.util.module_from_spec( importlib.util.spec_from_loader('__main__', None)) fake_main.__dict__.update({'__doc__': ''}) script_vars = { "execute_script": True, "image_path_iterator": ImagePathIterator(str(tmpdir.join("temp.png"))), "src_file": __file__, "memory_delta": [], "fake_main": fake_main, } return script_vars
def test_custom_scraper(gallery_conf, monkeypatch): """Test custom scrapers.""" # Test the API contract for custom scrapers complete_args = (gallery_conf, gallery_conf['gallery_dir'], True, False) with monkeypatch.context() as m: m.setattr(sphinx_gallery, '_get_sg_image_scraper', lambda: _custom_func, raising=False) for cust in (_custom_func, 'sphinx_gallery'): gallery_conf.update(image_scrapers=[cust]) # smoke test that it works _complete_gallery_conf(*complete_args, check_keys=False) # degenerate # without the monkey patch to add sphinx_gallery._get_sg_image_scraper, # we should get an error gallery_conf.update(image_scrapers=['sphinx_gallery']) with pytest.raises(ConfigError, match="has no attribute '_get_sg_image_scraper'"): _complete_gallery_conf(*complete_args, check_keys=False) # other degenerate conditions gallery_conf.update(image_scrapers=['foo']) with pytest.raises(ConfigError, match='Unknown image scraper'): _complete_gallery_conf(*complete_args, check_keys=False) gallery_conf.update(image_scrapers=[_custom_func]) fname_template = os.path.join(gallery_conf['gallery_dir'], 'image{0}.png') image_path_iterator = ImagePathIterator(fname_template) block = ('', ) * 3 block_vars = dict(image_path_iterator=image_path_iterator) with pytest.raises(ExtensionError, match='did not produce expected image'): save_figures(block, block_vars, gallery_conf) gallery_conf.update(image_scrapers=[lambda x, y, z: 1.]) with pytest.raises(ExtensionError, match='was not a string'): save_figures(block, block_vars, gallery_conf) # degenerate string interface gallery_conf.update(image_scrapers=['sphinx_gallery']) with monkeypatch.context() as m: m.setattr(sphinx_gallery, '_get_sg_image_scraper', 'foo', raising=False) with pytest.raises(ConfigError, match='^Unknown image.*\n.*callable'): _complete_gallery_conf(*complete_args, check_keys=False) with monkeypatch.context() as m: m.setattr(sphinx_gallery, '_get_sg_image_scraper', lambda: 'foo', raising=False) with pytest.raises(ConfigError, match='^Scraper.*was not callable'): _complete_gallery_conf(*complete_args, check_keys=False)
def test_capture_repr(gallery_conf, capture_repr, code, expected_out): """Tests output capturing with various capture_repr settings.""" compiler = codeop.Compile() code_block = ('code', code, 1) script_vars = { "execute_script": True, "image_path_iterator": ImagePathIterator("temp.png"), "src_file": __file__, "memory_delta": [], } gallery_conf['capture_repr'] = capture_repr output = sg.execute_code_block(compiler, code_block, {}, script_vars, gallery_conf) assert _clean_output(output) == expected_out
def test_empty_output_box(gallery_conf): """Tests that `print(__doc__)` doesn't produce an empty output box.""" compiler = codeop.Compile() code_block = ("code", "print(__doc__)", 1) script_vars = { "execute_script": True, "image_path_iterator": ImagePathIterator("temp.png"), "src_file": __file__, "memory_delta": [], } example_globals = {'__doc__': ''} output = sg.execute_code_block(compiler, code_block, example_globals, script_vars, gallery_conf) assert output.isspace()
def test_custom_scraper(gallery_conf, monkeypatch): """Test custom scrapers.""" # custom finders with monkeypatch.context() as m: m.setattr(sphinx_gallery, '_get_sg_image_scraper', lambda: _custom_func, raising=False) for cust in (_custom_func, 'sphinx_gallery'): gallery_conf.update(image_scrapers=[cust]) fname_template = os.path.join(gallery_conf['gallery_dir'], 'image{0}.png') image_path_iterator = ImagePathIterator(fname_template) block = ('', ) * 3 block_vars = dict(image_path_iterator=image_path_iterator) # degenerate gallery_conf.update(image_scrapers=['foo']) complete_args = (gallery_conf, gallery_conf['gallery_dir'], True, False) with pytest.raises(ValueError, match='Unknown image scraper'): _complete_gallery_conf(*complete_args) gallery_conf.update( image_scrapers=[lambda x, y, z: y['image_path_iterator'].next()]) with pytest.raises(RuntimeError, match='did not produce expected image'): save_figures(block, block_vars, gallery_conf) gallery_conf.update(image_scrapers=[lambda x, y, z: 1.]) with pytest.raises(TypeError, match='was not a string'): save_figures(block, block_vars, gallery_conf) # degenerate string interface gallery_conf.update(image_scrapers=['sphinx_gallery']) with monkeypatch.context() as m: m.setattr(sphinx_gallery, '_get_sg_image_scraper', 'foo', raising=False) with pytest.raises(ValueError, match='^Unknown image.*\n.*callable'): _complete_gallery_conf(*complete_args) with monkeypatch.context() as m: m.setattr(sphinx_gallery, '_get_sg_image_scraper', lambda: 'foo', raising=False) with pytest.raises(ValueError, match='^Scraper.*was not callable'): _complete_gallery_conf(*complete_args)
def test_save_matplotlib_figures_hidpi(gallery_conf): """Test matplotlib hidpi figure save.""" ext = 'png' gallery_conf['image_srcset'] = ["2x"] import matplotlib.pyplot as plt # nest these so that Agg can be set plt.plot(1, 1) fname_template = os.path.join(gallery_conf['gallery_dir'], 'image{0}.png') image_path_iterator = ImagePathIterator(fname_template) block = ('', ) * 3 block_vars = dict(image_path_iterator=image_path_iterator) image_rst = save_figures(block, block_vars, gallery_conf) fname = f'/image1.{ext}' assert fname in image_rst assert f'/image1_2_0x.{ext} 2.0x' in image_rst assert len(image_path_iterator) == 1 fname = gallery_conf['gallery_dir'] + fname fnamehi = gallery_conf['gallery_dir'] + f'/image1_2_0x.{ext}' assert os.path.isfile(fname) assert os.path.isfile(fnamehi) # Test capturing 2 images with shifted start number image_path_iterator.next() image_path_iterator.next() plt.plot(1, 1) plt.figure() plt.plot(1, 1) image_rst = save_figures(block, block_vars, gallery_conf) assert len(image_path_iterator) == 5 for ii in range(4, 6): fname = f'/image{ii}.{ext}' assert fname in image_rst fname = gallery_conf['gallery_dir'] + fname assert os.path.isfile(fname) fname = f'/image{ii}_2_0x.{ext}' assert fname in image_rst fname = gallery_conf['gallery_dir'] + fname assert os.path.isfile(fname)
def test_save_matplotlib_figures(gallery_conf): """Test matplotlib figure save""" import matplotlib.pyplot as plt # nest these so that Agg can be set plt.plot(1, 1) fname_template = os.path.join(gallery_conf['gallery_dir'], 'image{0}.png') image_path_iterator = ImagePathIterator(fname_template) block = ('',) * 3 block_vars = dict(image_path_iterator=image_path_iterator) image_rst = save_figures(block, block_vars, gallery_conf) assert len(image_path_iterator) == 1 assert '/image1.png' in image_rst # Test capturing 2 images with shifted start number image_path_iterator.next() image_path_iterator.next() plt.plot(1, 1) plt.figure() plt.plot(1, 1) image_rst = save_figures(block, block_vars, gallery_conf) assert len(image_path_iterator) == 5 assert '/image4.png' in image_rst assert '/image5.png' in image_rst
def test_save_mayavi_figures(gallery_conf): """Test file naming when saving figures. Requires mayavi.""" try: from mayavi import mlab except ImportError: raise pytest.skip('Mayavi not installed') import matplotlib.pyplot as plt mlab.options.offscreen = True gallery_conf.update(image_scrapers=(matplotlib_scraper, mayavi_scraper)) fname_template = os.path.join(gallery_conf['gallery_dir'], 'image{0}.png') image_path_iterator = ImagePathIterator(fname_template) block = ('', ) * 3 block_vars = dict(image_path_iterator=image_path_iterator) plt.axes([-0.1, -0.1, 1.2, 1.2]) plt.pcolor([[0]], cmap='Greens') mlab.test_plot3d() image_rst = save_figures(block, block_vars, gallery_conf) assert len(plt.get_fignums()) == 0 assert len(image_path_iterator) == 2 assert '/image0.png' not in image_rst assert '/image1.png' in image_rst assert '/image2.png' in image_rst assert '/image3.png' not in image_rst assert not os.path.isfile(fname_template.format(0)) assert os.path.isfile(fname_template.format(1)) assert os.path.isfile(fname_template.format(2)) assert not os.path.isfile(fname_template.format(0)) with Image.open(fname_template.format(1)) as img: pixels = np.asarray(img.convert("RGB")) assert (pixels == [247, 252, 245]).all() # plt first # Test next-value handling, plus image_scrapers modification gallery_conf.update(image_scrapers=(matplotlib_scraper, )) mlab.test_plot3d() plt.axes([-0.1, -0.1, 1.2, 1.2]) plt.pcolor([[0]], cmap='Reds') image_rst = save_figures(block, block_vars, gallery_conf) assert len(plt.get_fignums()) == 0 assert len(image_path_iterator) == 3 assert '/image1.png' not in image_rst assert '/image2.png' not in image_rst assert '/image3.png' in image_rst assert '/image4.png' not in image_rst assert not os.path.isfile(fname_template.format(0)) for ii in range(3): assert os.path.isfile(fname_template.format(ii + 1)) assert not os.path.isfile(fname_template.format(4)) with Image.open(fname_template.format(3)) as img: pixels = np.asarray(img.convert("RGB")) assert (pixels == [255, 245, 240]).all() # custom finders gallery_conf.update(image_scrapers=[lambda x, y, z: '']) image_rst = save_figures(block, block_vars, gallery_conf) assert len(image_path_iterator) == 3 # degenerate gallery_conf.update(image_scrapers=['foo']) with pytest.raises(ValueError, match='Unknown image scraper'): _complete_gallery_conf(gallery_conf, gallery_conf['gallery_dir'], True, False) gallery_conf.update( image_scrapers=[lambda x, y, z: y['image_path_iterator'].next()]) with pytest.raises(RuntimeError, match='did not produce expected image'): save_figures(block, block_vars, gallery_conf) gallery_conf.update(image_scrapers=[lambda x, y, z: 1.]) with pytest.raises(TypeError, match='was not a string'): save_figures(block, block_vars, gallery_conf)