<commit_before>"""
Interface between loop object and ebtel++ simulation
"""
import os
import copy
import warnings
import toolz
import pickle

import numpy as np
import h5py
import astropy.units as u
try:
    import distributed
except ImportError:
    warnings.warn('Dask library required for NEI calculation')

from synthesizAR.atomic import Element
from .util import write_xml

class EbtelInterface(object):
    """
    Interface to the Enthalpy-Based Thermal Evolution of Loops (EBTEL) model

    Parameters
    ----------
    base_config : `dict`
        Config dictionary with default parameters for all loops.
    heating_model : object
        Heating model class for configuring event times and rates
    config_dir : `str`
        Path to configuration file directory
    results_dir : `str`
        Path to results file directory
    """

    def __init__(self, base_config, heating_model, config_dir, results_dir):
        """
        Create EBTEL interface
        """
        self.name = 'EBTEL'
        self.base_config = base_config
        self.heating_model = heating_model
        self.heating_model.base_config = base_config
        self.config_dir = config_dir
        self.results_dir = results_dir
        if not os.path.exists(self.config_dir):
            os.makedirs(self.config_dir)
        if not os.path.exists(self.results_dir):
            os.makedirs(self.results_dir)

    def configure_input(self, loop):
        """
        Configure EBTEL input for a given loop object.
        """
        output_filename = os.path.join(self.config_dir, loop.name+'.xml')
        output_dict = copy.deepcopy(self.base_config)
        output_dict['output_filename'] = os.path.join(self.results_dir, loop.name)
        output_dict['loop_length'] = loop.full_length.to(u.cm).value / 2.0
        event_properties = self.heating_model.calculate_event_properties(loop)
        events = []
        for i in range(event_properties['magnitude'].shape[0]):
            events.append({'event': {'magnitude': event_properties['magnitude'][i],
                                     'rise_start': event_properties['rise_start'][i],
                                     'rise_end': event_properties['rise_end'][i],
                                     'decay_start': event_properties['decay_start'][i],
                                     'decay_end': event_properties['decay_end'][i]}})
        output_dict['heating']['events'] = events
        write_xml(output_dict, output_filename)
        output_dict['config_filename'] = output_filename
        loop.hydro_configuration = output_dict

    def load_results(self, loop):
        """
        Load EBTEL output for a given loop object.

        Parameters
        ----------
        loop : `synthesizAR.Loop` object
        """
        # load text
        N_s = loop.field_aligned_coordinate.shape[0]
        _tmp = np.loadtxt(loop.hydro_configuration['output_filename'])

        # reshape into a 1D loop structure with units
        time = _tmp[:, 0]*u.s
        electron_temperature = np.outer(_tmp[:, 1], np.ones(N_s))*u.K
        ion_temperature = np.outer(_tmp[:, 2], np.ones(N_s))*u.K
        density = np.outer(_tmp[:, 3], np.ones(N_s))*(u.cm**(-3))
        velocity = np.outer(_tmp[:, -2], np.ones(N_s))*u.cm/u.s
        # flip sign of velocity where the radial distance from center is maximum
        # FIXME: this is probably not the best way to do this...
        r = np.sqrt(np.sum(loop.coordinates.cartesian.xyz.value**2, axis=0))
        i_mirror = np.where(np.diff(np.sign(np.gradient(r))))[0]
        if i_mirror.shape[0] > 0:
            i_mirror = i_mirror[0] + 1
        else:
            # If the first method fails, just set it at the midpoint
            i_mirror = int(N_s / 2) if N_s % 2 == 0 else int((N_s - 1) / 2)
        velocity[:, i_mirror:] = -velocity[:, i_mirror:]

        return time, electron_temperature, ion_temperature, density, velocity

    @staticmethod
    def calculate_ionization_fraction(field, emission_model, **kwargs):
        """
        Solve the time-dependent ionization balance equation for all loops and all elements

        This method computes the time dependent ion population fractions for each element in
        the emission model and each loop in the active region and compiles the results to a single
        HDF5 file. To do this efficiently, it uses the dask.distributed library to take advantage of
        multiple processes/cores/machines and compute the population fractions in parallel. It returns
        an asynchronous `~distributed.client.Future` object which holds the state of the submitted
        tasks.

        Parameters
        ----------
        field : `~synthesizAR.Field`
        emission_model : `~synthesizAR.atomic.EmissionModel`

        Other Parameters
        ---------------------
        temperature : `~astropy.units.Quantity`

        Returns
        --------
        future : `~distributed.client.Future`
        """
        client = distributed.get_client()
        unique_elements = list(set([ion.element_name for ion in emission_model]))
        temperature = kwargs.get('temperature', emission_model.temperature)

        #futures = []

        #for el_name in unique_elements:
        el_name = unique_elements[0]
        el = Element(el_name, temperature)
        rate_matrix = el._rate_matrix()
        ioneq = el.equilibrium_ionization(rate_matrix=rate_matrix)
        partial_compute = toolz.curry(EbtelInterface.compute_nei)(
            el, rate_matrix=rate_matrix, initial_condition=ioneq)
        partial_write = toolz.curry(EbtelInterface.write_to_hdf5)(
            element_name=el_name, savefile=emission_model.ionization_fraction_savefile)
        nei = client.map(partial_compute, field.loops)
        futures = client.map(partial_write, nei, field.loops)
        #distributed.wait(_futures)
        # Append only futures without complete status
        #futures += [f for f in _futures if f.status != 'finished']

        return futures

    @staticmethod
    def compute_nei(element, loop, rate_matrix, initial_condition):
        """
        Compute NEI populations for a given element and loop
        """
        y = element.non_equilibrium_ionization(
            loop.time, loop.electron_temperature[:, 0], loop.density[:, 0], rate_matrix,
            initial_condition)
        # Fake a spatial axis by tiling the same result at each s coordinate
        return np.repeat(y.value[:, np.newaxis, :], loop.field_aligned_coordinate.shape[0], axis=1)

    @staticmethod
    def write_to_hdf5(data, loop, element_name, savefile):
        """
        Collect and store all NEI populations in a single HDF5 file
        """
        lock = distributed.Lock('hdf5_ebtel_nei')
        with lock:
            with h5py.File(savefile, 'a') as hf:
                grp = hf.create_group(loop.name) if loop.name not in hf else hf[loop.name]
                if element_name not in grp:
                    dset = grp.create_dataset(element_name, data=data)
                else:
                    dset = grp[element_name]
                    dset[:, :, :] = data
                dset.attrs['unit'] = ''
                dset.attrs['description'] = 'non-equilibrium ionization fractions'
<commit_msg>fix call to wait<commit_after>"""
Interface between loop object and ebtel++ simulation
"""
import os
import copy
import warnings
import toolz
import pickle

import numpy as np
import h5py
import astropy.units as u
try:
    import distributed
except ImportError:
    warnings.warn('Dask library required for NEI calculation')

from synthesizAR.atomic import Element
from .util import write_xml

class EbtelInterface(object):
    """
    Interface to the Enthalpy-Based Thermal Evolution of Loops (EBTEL) model

    Parameters
    ----------
    base_config : `dict`
        Config dictionary with default parameters for all loops.
    heating_model : object
        Heating model class for configuring event times and rates
    config_dir : `str`
        Path to configuration file directory
    results_dir : `str`
        Path to results file directory
    """

    def __init__(self, base_config, heating_model, config_dir, results_dir):
        """
        Create EBTEL interface
        """
        self.name = 'EBTEL'
        self.base_config = base_config
        self.heating_model = heating_model
        self.heating_model.base_config = base_config
        self.config_dir = config_dir
        self.results_dir = results_dir
        if not os.path.exists(self.config_dir):
            os.makedirs(self.config_dir)
        if not os.path.exists(self.results_dir):
            os.makedirs(self.results_dir)

    def configure_input(self, loop):
        """
        Configure EBTEL input for a given loop object.
        """
        output_filename = os.path.join(self.config_dir, loop.name+'.xml')
        output_dict = copy.deepcopy(self.base_config)
        output_dict['output_filename'] = os.path.join(self.results_dir, loop.name)
        output_dict['loop_length'] = loop.full_length.to(u.cm).value / 2.0
        event_properties = self.heating_model.calculate_event_properties(loop)
        events = []
        for i in range(event_properties['magnitude'].shape[0]):
            events.append({'event': {'magnitude': event_properties['magnitude'][i],
                                     'rise_start': event_properties['rise_start'][i],
                                     'rise_end': event_properties['rise_end'][i],
                                     'decay_start': event_properties['decay_start'][i],
                                     'decay_end': event_properties['decay_end'][i]}})
        output_dict['heating']['events'] = events
        write_xml(output_dict, output_filename)
        output_dict['config_filename'] = output_filename
        loop.hydro_configuration = output_dict

    def load_results(self, loop):
        """
        Load EBTEL output for a given loop object.

        Parameters
        ----------
        loop : `synthesizAR.Loop` object
        """
        # load text
        N_s = loop.field_aligned_coordinate.shape[0]
        _tmp = np.loadtxt(loop.hydro_configuration['output_filename'])

        # reshape into a 1D loop structure with units
        time = _tmp[:, 0]*u.s
        electron_temperature = np.outer(_tmp[:, 1], np.ones(N_s))*u.K
        ion_temperature = np.outer(_tmp[:, 2], np.ones(N_s))*u.K
        density = np.outer(_tmp[:, 3], np.ones(N_s))*(u.cm**(-3))
        velocity = np.outer(_tmp[:, -2], np.ones(N_s))*u.cm/u.s
        # flip sign of velocity where the radial distance from center is maximum
        # FIXME: this is probably not the best way to do this...
        r = np.sqrt(np.sum(loop.coordinates.cartesian.xyz.value**2, axis=0))
        i_mirror = np.where(np.diff(np.sign(np.gradient(r))))[0]
        if i_mirror.shape[0] > 0:
            i_mirror = i_mirror[0] + 1
        else:
            # If the first method fails, just set it at the midpoint
            i_mirror = int(N_s / 2) if N_s % 2 == 0 else int((N_s - 1) / 2)
        velocity[:, i_mirror:] = -velocity[:, i_mirror:]

        return time, electron_temperature, ion_temperature, density, velocity

    @staticmethod
    def calculate_ionization_fraction(field, emission_model, **kwargs):
        """
        Solve the time-dependent ionization balance equation for all loops and all elements

        This method computes the time dependent ion population fractions for each element in
        the emission model and each loop in the active region and compiles the results to a single
        HDF5 file. To do this efficiently, it uses the dask.distributed library to take advantage of
        multiple processes/cores/machines and compute the population fractions in parallel. It returns
        an asynchronous `~distributed.client.Future` object which holds the state of the submitted
        tasks.

        Parameters
        ----------
        field : `~synthesizAR.Field`
        emission_model : `~synthesizAR.atomic.EmissionModel`

        Other Parameters
        ---------------------
        temperature : `~astropy.units.Quantity`

        Returns
        --------
        future : `~distributed.client.Future`
        """
        client = distributed.get_client()
        unique_elements = list(set([ion.element_name for ion in emission_model]))
        temperature = kwargs.get('temperature', emission_model.temperature)

        futures = {}
        for el_name in unique_elements:
            el = Element(el_name, temperature)
            rate_matrix = el._rate_matrix()
            ioneq = el.equilibrium_ionization(rate_matrix=rate_matrix)
            partial_compute = toolz.curry(EbtelInterface.compute_nei)(
                el, rate_matrix=rate_matrix, initial_condition=ioneq)
            partial_write = toolz.curry(EbtelInterface.write_to_hdf5)(
                element_name=el_name, savefile=emission_model.ionization_fraction_savefile)
            nei = client.map(partial_compute, field.loops)
            futures[el_name] = client.map(partial_write, nei, field.loops)
            distributed.client.wait(futures[el_name])

        return futures

    @staticmethod
    def compute_nei(element, loop, rate_matrix, initial_condition):
        """
        Compute NEI populations for a given element and loop
        """
        y = element.non_equilibrium_ionization(
            loop.time, loop.electron_temperature[:, 0], loop.density[:, 0], rate_matrix,
            initial_condition)
        # Fake a spatial axis by tiling the same result at each s coordinate
        return np.repeat(y.value[:, np.newaxis, :], loop.field_aligned_coordinate.shape[0], axis=1)

    @staticmethod
    def write_to_hdf5(data, loop, element_name, savefile):
        """
        Collect and store all NEI populations in a single HDF5 file
        """
        lock = distributed.Lock('hdf5_ebtel_nei')
        with lock:
            with h5py.File(savefile, 'a') as hf:
                grp = hf.create_group(loop.name) if loop.name not in hf else hf[loop.name]
                if element_name not in grp:
                    dset = grp.create_dataset(element_name, data=data)
                else:
                    dset = grp[element_name]
                    dset[:, :, :] = data
                dset.attrs['unit'] = ''
                dset.attrs['description'] = 'non-equilibrium ionization fractions'
<|endoftext|>


<commit_before>import unittest
from survey import core

class UriCheckTests(unittest.TestCase):
    """Tests for Uris"""

    def testHttpURI(self):
        gooduri = core.UriCheck()
        httpuristart = 'http://www.opera.com/'
        self.assertTrue(gooduri.ishttpURI(httpuristart))

    def testHttpsURI(self):
        gooduri = core.UriCheck()
        httpuristart = 'https://www.opera.com/'
        self.assertTrue(gooduri.ishttpURI(httpuristart))

    def testUpperCaseHttpURI(self):
        gooduri = core.UriCheck()
        httpuristart = 'HTTP://www.opera.com/'
        self.assertTrue(gooduri.ishttpURI(httpuristart))

    def testHttpURIWrong(self):
        gooduri = core.UriCheck()
        httpurifalse = 'mailto:foo@example.org'
        self.assertFalse(gooduri.ishttpURI(httpurifalse))

    def testLeadingSpaceHttpURI(self):
        gooduri = core.UriCheck()
        httpuristart = '  http://www.opera.com/'
        self.assertTrue(gooduri.ishttpURI(httpuristart))

    def testTrailingSpaceHttpURI(self):
        gooduri = core.UriCheck()
        httpuristart = 'http://www.opera.com/   '
        self.assertTrue(gooduri.ishttpURI(httpuristart))

class HttpRequestsTests(unittest.TestCase):
    """Tests for HTTP"""

    def setUp(self):
        "Starting a Web server"
        pass

    def testGetRequestStatusOK(self):
        "Check if everything is ok"
        pass

    def testGetRequestStatus4xx(self):
        "Check if we advertise the right message when 4xx"
        pass

    def testGetRequestLocation(self):
        "Check if we grab the right location when there is a redirection"
        pass

class CssTests(unittest.TestCase):
    """Tests for CSS requests"""

    def setUp(self):
        self.css = core.Css()
        self.req = core.HttpRequests()

    def testCssList(self):
        "For a given Web site, check if we get the right list of linked stylesheets"
        WebSiteUri = 'http://www.opera.com/'
        expected = [
        'http://www.opera.com/css/handheld.css',
        'http://www.opera.com/css/screen.css',
        'http://www.opera.com/css/print.css',
        'http://www.opera.com/css/pages/home.css']
        content = self.req.getContent(WebSiteUri)
        actual = self.css.getCssUriList(content, WebSiteUri)
        # we need to compare ordered list.
        actual.sort()
        expected.sort()
        self.assertListEqual(expected, actual)

    def testRulesList(self):
        "for a given CSS do we list the right list of rules"
        pass

    def testHasStyleElement(self):
        "for a given URI, is there a style element? return True if there is."
        content = "<!doctype><title>foo</title>foo"
        self.assertTrue(self.css.hasStyleElement(content))

    def testStyleElementRules(self):
        "When there is a style element, do we gest the expected rules?"
        # we might need to normalize to cope for spaces in the test.
        content = "<!doctype><title>foo</title>foo"
        expected = ".foo {color: #fff;}"
        actual = self.css.getStyleElementRules(content)
        self.assertEqual(expected, actual)

def main():
    unittest.main()

if __name__ == '__main__':
    main()
<commit_msg>adding teardown of classes<commit_after>import unittest
from survey import core

class UriCheckTests(unittest.TestCase):
    """Tests for Uris"""

    def testHttpURI(self):
        gooduri = core.UriCheck()
        httpuristart = 'http://www.opera.com/'
        self.assertTrue(gooduri.ishttpURI(httpuristart))

    def testHttpsURI(self):
        gooduri = core.UriCheck()
        httpuristart = 'https://www.opera.com/'
        self.assertTrue(gooduri.ishttpURI(httpuristart))

    def testUpperCaseHttpURI(self):
        gooduri = core.UriCheck()
        httpuristart = 'HTTP://www.opera.com/'
        self.assertTrue(gooduri.ishttpURI(httpuristart))

    def testHttpURIWrong(self):
        gooduri = core.UriCheck()
        httpurifalse = 'mailto:foo@example.org'
        self.assertFalse(gooduri.ishttpURI(httpurifalse))

    def testLeadingSpaceHttpURI(self):
        gooduri = core.UriCheck()
        httpuristart = '  http://www.opera.com/'
        self.assertTrue(gooduri.ishttpURI(httpuristart))

    def testTrailingSpaceHttpURI(self):
        gooduri = core.UriCheck()
        httpuristart = 'http://www.opera.com/   '
        self.assertTrue(gooduri.ishttpURI(httpuristart))

class HttpRequestsTests(unittest.TestCase):
    """Tests for HTTP"""

    def setUp(self):
        "Starting a Web server"
        pass

    def testGetRequestStatusOK(self):
        "Check if everything is ok"
        pass

    def testGetRequestStatus4xx(self):
        "Check if we advertise the right message when 4xx"
        pass

    def testGetRequestLocation(self):
        "Check if we grab the right location when there is a redirection"
        pass

class CssTests(unittest.TestCase):
    """Tests for CSS requests"""

    def setUp(self):
        self.css = core.Css()
        self.req = core.HttpRequests()

    def tearDown(self):
        self.css = None
        self.req = None

    def testCssList(self):
        "For a given Web site, check if we get the right list of linked stylesheets"
        WebSiteUri = 'http://www.opera.com/'
        expected = [
        'http://www.opera.com/css/handheld.css',
        'http://www.opera.com/css/screen.css',
        'http://www.opera.com/css/print.css',
        'http://www.opera.com/css/pages/home.css']
        content = self.req.getContent(WebSiteUri)
        actual = self.css.getCssUriList(content, WebSiteUri)
        # we need to compare ordered list.
        actual.sort()
        expected.sort()
        self.assertListEqual(expected, actual)

    def testRulesList(self):
        "for a given CSS do we list the right list of rules"
        pass

    def testHasStyleElement(self):
        "for a given URI, is there a style element? return True if there is."
        content = "<!doctype><title>foo</title>foo"
        self.assertTrue(self.css.hasStyleElement(content))

    def testStyleElementRules(self):
        "When there is a style element, do we get the expected rules?"
        # we might need to normalize to cope for spaces in the test.
        content = "<!doctype><title>foo</title>foo"
        expected = ".foo {color: #fff;}"
        actual = self.css.getStyleElementRules(content)
        self.assertEqual(expected, actual)

def main():
    unittest.main()

if __name__ == '__main__':
    main()
<|endoftext|>


<commit_before>
from nose.tools import *

from libeeyore.eeyoreoptions import EeyoreOptions

from libeeyore.usererrorexception import EeyUserErrorException

@raises( EeyUserErrorException )
def test_no_args():
    EeyoreOptions( [ "progname" ] )

@raises( EeyUserErrorException )
def test_one_arg():
    EeyoreOptions( [ "progname", "infile.eeyoreparsetree" ] )

def test_parse_to_cpp():
    opts = EeyoreOptions(
        [ "progname", "infile.eeyoreparsetree", "outfile.cpp" ] )

    assert_equal( opts.infile.filetype, EeyoreOptions.PARSE_TREE )
    assert_equal( opts.infile.filename, "infile.eeyoreparsetree" )

    assert_equal( opts.outfile.filetype, EeyoreOptions.CPP )
    assert_equal( opts.outfile.filename, "outfile.cpp" )

def test_eeyore_to_lexed():
    opts = EeyoreOptions(
        [ "progname", "infile.eeyore", "outfile.eeyorelexed" ] )

    assert_equal( opts.infile.filetype, EeyoreOptions.SOURCE )
    assert_equal( opts.infile.filename, "infile.eeyore" )

    assert_equal( opts.outfile.filetype, EeyoreOptions.LEXED )
    assert_equal( opts.outfile.filename, "outfile.eeyorelexed" )

<commit_msg>Added exe file type to options.<commit_after>
from nose.tools import *

from libeeyore.eeyoreoptions import EeyoreOptions

from libeeyore.usererrorexception import EeyUserErrorException

@raises( EeyUserErrorException )
def test_no_args():
    EeyoreOptions( [ "progname" ] )

@raises( EeyUserErrorException )
def test_one_arg():
    EeyoreOptions( [ "progname", "infile.eeyoreparsetree" ] )

def test_parse_to_cpp():
    opts = EeyoreOptions(
        [ "progname", "infile.eeyoreparsetree", "outfile.cpp" ] )

    assert_equal( opts.infile.filetype, EeyoreOptions.PARSE_TREE )
    assert_equal( opts.infile.filename, "infile.eeyoreparsetree" )

    assert_equal( opts.outfile.filetype, EeyoreOptions.CPP )
    assert_equal( opts.outfile.filename, "outfile.cpp" )

def test_eeyore_to_lexed():
    opts = EeyoreOptions(
        [ "progname", "infile.eeyore", "outfile.eeyorelexed" ] )

    assert_equal( opts.infile.filetype, EeyoreOptions.SOURCE )
    assert_equal( opts.infile.filename, "infile.eeyore" )

    assert_equal( opts.outfile.filetype, EeyoreOptions.LEXED )
    assert_equal( opts.outfile.filename, "outfile.eeyorelexed" )

def test_eeyore_to_exe():
    opts = EeyoreOptions(
        [ "progname", "infile.eeyore", "outfile" ] )

    assert_equal( opts.infile.filetype, EeyoreOptions.SOURCE )
    assert_equal( opts.infile.filename, "infile.eeyore" )

    assert_equal( opts.outfile.filetype, EeyoreOptions.EXE )
    assert_equal( opts.outfile.filename, "outfile" )

<|endoftext|>


<commit_before>import sublime
import sublime_plugin
import subprocess
import os

if sublime.platform() == 'windows':
    import ctypes
    from ctypes import c_int32, c_uint32, c_void_p, c_wchar_p, POINTER

    class CHOOSECOLOR(ctypes.Structure):
        """
        Data mapping representation contained for the color chooser
        """
        _fields_ = [('lStructSize', c_uint32),
                    ('hwndOwner', c_void_p),
                    ('hInstance', c_void_p),
                    ('rgbResult', c_uint32),
                    ('lpCustColors', POINTER(c_uint32)),
                    ('Flags', c_uint32),
                    ('lCustData', c_void_p),
                    ('lpfnHook', c_void_p),
                    ('lpTemplateName', c_wchar_p)]

    CustomColorArray = c_uint32 * 16
    CC_SOLIDCOLOR = 0x80
    CC_RGBINIT = 0x01
    CC_FULLOPEN = 0x02

    ChooseColorW = ctypes.windll.Comdlg32.ChooseColorW
    ChooseColorW.argtypes = [POINTER(CHOOSECOLOR)]
    ChooseColorW.restype = c_int32

    GetDC = ctypes.windll.User32.GetDC
    GetDC.argtypes = [c_void_p]
    GetDC.restype = c_void_p

    ReleaseDC = ctypes.windll.User32.ReleaseDC
    ReleaseDC.argtypes = [c_void_p, c_void_p]  # hwnd, hdc
    ReleaseDC.restype = c_int32

class RainmeterColorPickCommand(sublime_plugin.TextCommand):

    def run(self, edit):
        sel = self.view.sel()
        start_color = None
        start_color_osx = None
        start_color_win = 0x000000

        # Get the currently selected color - if any
        if len(sel) > 0:
            selected = self.view.substr(self.view.word(sel[0])).strip()
            if selected.startswith('#'):
                selected = selected[1:]
            if self.__is_valid_hex_color(selected):
                if len(selected) > 6:
                    selected = selected[0:6]
                start_color = "#" + selected
                start_color_osx = selected
                start_color_win = self.__hexstr_to_bgr(selected)

        if sublime.platform() == 'windows':

            s = sublime.load_settings("ColorPicker.sublime-settings")
            custom_colors = s.get("custom_colors", ['0'] * 16)

            if len(custom_colors) < 16:
                custom_colors = ['0'] * 16
                s.set('custom_colors', custom_colors)

            cc = CHOOSECOLOR()
            ctypes.memset(ctypes.byref(cc), 0, ctypes.sizeof(cc))
            cc.lStructSize = ctypes.sizeof(cc)
            cc.hwndOwner = None
            cc.Flags = CC_SOLIDCOLOR | CC_FULLOPEN | CC_RGBINIT
            cc.rgbResult = c_uint32(start_color_win)
            cc.lpCustColors = self.__to_custom_color_array(custom_colors)

            if ChooseColorW(ctypes.byref(cc)):
                color = self.__bgr_to_hexstr(cc.rgbResult)
            else:
                color = None

        elif sublime.platform() == 'osx':
            location = os.path.join(sublime.packages_path(),
                                    'Rainmeter',
                                    'lib',
                                    'osx_colorpicker')
            args = [location]

            if not os.access(location, os.X_OK):
                os.chmod(location, 0o755)

            if start_color_osx:
                args.append('-startColor')
                args.append(start_color_osx)

        else:
            location = os.path.join(sublime.packages_path(),
                                    'Rainmeter',
                                    'lib',
                                    'linux_colorpicker.py')
            args = [location]

            if not os.access(location, os.X_OK):
                os.chmod(location, 0o755)

            if start_color:
                args.append(start_color)

        if sublime.platform() == 'osx' or sublime.platform() == 'linux':
            proc = subprocess.Popen(args, stdout=subprocess.PIPE)
            color = proc.communicate()[0].strip()

        if color:
            # Replace all regions with color
            for region in sel:
                word = self.view.word(region)
                # If the selected word is a valid color, replace it
                if self.__is_valid_hex_color(self.view.substr(word)):
                    if len(self.view.substr(word)) > 6:
                        word = sublime.Region(word.a, word.a + 6)
                    # Include '#' if present
                    self.view.replace(edit, word, color)
                # If the selected region starts with a #, keep it
                elif self.view.substr(region).startswith('#'):
                    reduced = sublime.Region(region.begin() + 1, region.end())
                    if self.__is_valid_hex_color(self.view.substr(reduced)):
                        if len(reduced) > 6:
                            reduced = sublime.Region(reduced.a, reduced.a + 6)
                        self.view.replace(edit, reduced, color)
                    else:
                        self.view.replace(edit, region, '#' + color)
                # Otherwise just replace the selected region
                else:
                    self.view.replace(edit, region, color)

    @classmethod
    def __to_custom_color_array(cls, custom_colors):
        cc = CustomColorArray()
        for i in range(16):
            cc[i] = int(custom_colors[i])
        return cc

    @classmethod
    def __from_custom_color_array(cls, custom_colors):
        cc = [0] * 16
        for i in range(16):
            cc[i] = str(custom_colors[i])
        return cc

    @classmethod
    def __is_valid_hex_color(cls, string):
        if len(string) not in (3, 6, 8):
            return False
        try:
            return 0 <= int(string, 16) <= 0xffffffff
        except ValueError:
            return False

    byte_table = list(['{0:02X}'.format(b) for b in range(256)])

    @classmethod
    def __bgr_to_hexstr(cls, bgr):
        # 0x00BBGGRR
        b = cls.byte_table[(bgr >> 16) & 0xff]
        g = cls.byte_table[(bgr >> 8) & 0xff]
        r = cls.byte_table[bgr & 0xff]

        return r + g + b

    @classmethod
    def __hexstr_to_bgr(cls, hexstr):
        if len(hexstr) == 3:
            hexstr = hexstr[0] + hexstr[0] + hexstr[1] + \
                hexstr[1] + hexstr[2] + hexstr[2]

        red = int(hexstr[0:2], 16)
        green = int(hexstr[2:4], 16)
        blue = int(hexstr[4:6], 16)

        return (blue << 16) | (green << 8) | red
<commit_msg>Added docstring to colorpicker<commit_after>"""This module is about the integration with the color picker.

The color picker can detect a color in a substring
and launch a tool to display the current color,
change it and thus also replace the old color.

It supports both ways Rainmeter defines color.

* RRGGBB
* RRGGBBAA
* RRR,GGG,BBB
* RRR,GGG,BBB,AAA

which is hexadecimal and decimal format.
"""
import os
import subprocess

import sublime
import sublime_plugin

if sublime.platform() == 'windows':
    import ctypes
    from ctypes import c_int32, c_uint32, c_void_p, c_wchar_p, POINTER

    class CHOOSECOLOR(ctypes.Structure): # pylint: disable=R0903; this extends a data class
        """Data mapping representation contained for the color chooser."""

        _fields_ = [('lStructSize', c_uint32),
                    ('hwndOwner', c_void_p),
                    ('hInstance', c_void_p),
                    ('rgbResult', c_uint32),
                    ('lpCustColors', POINTER(c_uint32)),
                    ('Flags', c_uint32),
                    ('lCustData', c_void_p),
                    ('lpfnHook', c_void_p),
                    ('lpTemplateName', c_wchar_p)]

    CustomColorArray = c_uint32 * 16
    CC_SOLIDCOLOR = 0x80
    CC_RGBINIT = 0x01
    CC_FULLOPEN = 0x02

    ChooseColorW = ctypes.windll.Comdlg32.ChooseColorW
    ChooseColorW.argtypes = [POINTER(CHOOSECOLOR)]
    ChooseColorW.restype = c_int32

    GetDC = ctypes.windll.User32.GetDC
    GetDC.argtypes = [c_void_p]
    GetDC.restype = c_void_p

    ReleaseDC = ctypes.windll.User32.ReleaseDC
    ReleaseDC.argtypes = [c_void_p, c_void_p]  # hwnd, hdc
    ReleaseDC.restype = c_int32

class RainmeterColorPickCommand(sublime_plugin.TextCommand): # pylint: disable=R0903; we only need one method
    """Sublime Text integration running this through an action."""

    def run(self, edit):
        """Method is provided by Sublime Text through the super class TextCommand.

        This is run automatically if you initialize the command
        through an "command": "rainmeter_color_pick" command.
        """
        sel = self.view.sel()
        start_color = None
        start_color_osx = None
        start_color_win = 0x000000

        # Get the currently selected color - if any
        if len(sel) > 0:
            selected = self.view.substr(self.view.word(sel[0])).strip()
            if selected.startswith('#'):
                selected = selected[1:]
            if self.__is_valid_hex_color(selected):
                if len(selected) > 6:
                    selected = selected[0:6]
                start_color = "#" + selected
                start_color_osx = selected
                start_color_win = self.__hexstr_to_bgr(selected)

        if sublime.platform() == 'windows':

            settings = sublime.load_settings("ColorPicker.sublime-settings")
            custom_colors = settings.get("custom_colors", ['0'] * 16)

            if len(custom_colors) < 16:
                custom_colors = ['0'] * 16
                settings.set('custom_colors', custom_colors)

            choose_color = CHOOSECOLOR()
            ctypes.memset(ctypes.byref(choose_color), 0, ctypes.sizeof(choose_color))
            choose_color.lStructSize = ctypes.sizeof(choose_color)
            choose_color.hwndOwner = None
            choose_color.Flags = CC_SOLIDCOLOR | CC_FULLOPEN | CC_RGBINIT
            choose_color.rgbResult = c_uint32(start_color_win)
            choose_color.lpCustColors = self.__to_custom_color_array(custom_colors)

            if ChooseColorW(ctypes.byref(choose_color)):
                color = self.__bgr_to_hexstr(choose_color.rgbResult)
            else:
                color = None

        elif sublime.platform() == 'osx':
            location = os.path.join(sublime.packages_path(),
                                    'Rainmeter',
                                    'lib',
                                    'osx_colorpicker')
            args = [location]

            if not os.access(location, os.X_OK):
                os.chmod(location, 0o755)

            if start_color_osx:
                args.append('-startColor')
                args.append(start_color_osx)

        else:
            location = os.path.join(sublime.packages_path(),
                                    'Rainmeter',
                                    'lib',
                                    'linux_colorpicker.py')
            args = [location]

            if not os.access(location, os.X_OK):
                os.chmod(location, 0o755)

            if start_color:
                args.append(start_color)

        if sublime.platform() == 'osx' or sublime.platform() == 'linux':
            proc = subprocess.Popen(args, stdout=subprocess.PIPE)
            color = proc.communicate()[0].strip()

        if color:
            # Replace all regions with color
            for region in sel:
                word = self.view.word(region)
                # If the selected word is a valid color, replace it
                if self.__is_valid_hex_color(self.view.substr(word)):
                    if len(self.view.substr(word)) > 6:
                        word = sublime.Region(word.a, word.a + 6)
                    # Include '#' if present
                    self.view.replace(edit, word, color)
                # If the selected region starts with a #, keep it
                elif self.view.substr(region).startswith('#'):
                    reduced = sublime.Region(region.begin() + 1, region.end())
                    if self.__is_valid_hex_color(self.view.substr(reduced)):
                        if len(reduced) > 6:
                            reduced = sublime.Region(reduced.a, reduced.a + 6)
                        self.view.replace(edit, reduced, color)
                    else:
                        self.view.replace(edit, region, '#' + color)
                # Otherwise just replace the selected region
                else:
                    self.view.replace(edit, region, color)

    @classmethod
    def __to_custom_color_array(cls, custom_colors):
        cca = CustomColorArray()
        for i in range(16):
            cca[i] = int(custom_colors[i])
        return cca

    @classmethod
    def __from_custom_color_array(cls, custom_colors):
        cca = [0] * 16
        for i in range(16):
            cca[i] = str(custom_colors[i])
        return cca

    @classmethod
    def __is_valid_hex_color(cls, string):
        if len(string) not in (3, 6, 8):
            return False
        try:
            return 0 <= int(string, 16) <= 0xffffffff
        except ValueError:
            return False

    byte_table = list(['{0:02X}'.format(b) for b in range(256)])

    @classmethod
    def __bgr_to_hexstr(cls, bgr):
        # 0x00BBGGRR
        blue = cls.byte_table[(bgr >> 16) & 0xff]
        green = cls.byte_table[(bgr >> 8) & 0xff]
        red = cls.byte_table[bgr & 0xff]

        return red + green + blue

    @classmethod
    def __hexstr_to_bgr(cls, hexstr):
        if len(hexstr) == 3:
            hexstr = hexstr[0] + hexstr[0] + hexstr[1] + \
                hexstr[1] + hexstr[2] + hexstr[2]

        red = int(hexstr[0:2], 16)
        green = int(hexstr[2:4], 16)
        blue = int(hexstr[4:6], 16)

        return (blue << 16) | (green << 8) | red
<|endoftext|>


<commit_before>import sys

import click

from .base import Report

TMPL_FILENAME = click.style('{filename}', underline=True) + ' ({num_errors})'

TMPL_LOCATION = click.style(
    '{line:>5}{position_splitter}{character:<3} ',
    dim=True,
)

TMPL_TOOLINFO = click.style('({tool}:{code})', fg='yellow', dim=True)

TAB = ' ' * 8

class ConsoleReport(Report):
    def execute(self, collector):
        issues = collector.get_grouped_issues()

        total_issues = 0
        for filename in sorted(issues.keys()):
            file_issues = issues[filename]
            total_issues += len(file_issues)

            self.output(TMPL_FILENAME.format(
                filename=self.relative_filename(filename),
                num_errors=len(file_issues),
            ))

            for issue in file_issues:
                location = TMPL_LOCATION.format(
                    line=issue.line,
                    position_splitter=' ' if issue.character is None else ':',
                    character=issue.character or '',
                )

                toolinfo = TMPL_TOOLINFO.format(
                    tool=issue.tool,
                    code=issue.code,
                )

                message = issue.message
                if '\n' in message:
                    pad = '\n' + (' ' * len(click.unstyle(location)))

                    message = pad.join(
                        issue.message.replace('\t', TAB).splitlines()
                    )

                    toolinfo = pad + toolinfo
                else:
                    toolinfo = ' ' + toolinfo

                self.output(location + message + toolinfo)

            self.output('')

        is_windows = sys.platform == 'win32'
        if total_issues:
            self.output(
                click.style(
                    '{icon}{num_issues} issues found.'.format(
                        icon='' if is_windows else u'\u2717 ',  # noqa: @2to3
                        num_issues=total_issues,
                    ),
                    fg='yellow',
                    bold=True,
                )
            )
        else:
            self.output(
                click.style(
                    '{icon}No issues found!'.format(
                        icon='' if is_windows else u'\u2714 ',  # noqa: @2to3
                    ),
                    fg='green',
                    bold=True,
                )
            )

<commit_msg>Fixed a unicode issue<commit_after>import sys

import click

from .base import Report

TMPL_FILENAME = click.style('{filename}', underline=True) + ' ({num_errors})'

TMPL_LOCATION = click.style(
    '{line:>5}{position_splitter}{character:<3} ',
    dim=True,
)

TMPL_TOOLINFO = click.style('({tool}:{code})', fg='yellow', dim=True)

TAB = ' ' * 8

class ConsoleReport(Report):
    def execute(self, collector):
        issues = collector.get_grouped_issues()

        total_issues = 0
        for filename in sorted(issues.keys()):
            file_issues = issues[filename]
            total_issues += len(file_issues)

            self.output(TMPL_FILENAME.format(
                filename=self.relative_filename(filename),
                num_errors=len(file_issues),
            ))

            for issue in file_issues:
                location = TMPL_LOCATION.format(
                    line=issue.line,
                    position_splitter=' ' if issue.character is None else ':',
                    character=issue.character or '',
                )

                toolinfo = TMPL_TOOLINFO.format(
                    tool=issue.tool,
                    code=issue.code,
                )

                message = issue.message
                if '\n' in message:
                    pad = '\n' + (' ' * len(click.unstyle(location)))

                    message = pad.join(
                        issue.message.replace('\t', TAB).splitlines()
                    )

                    toolinfo = pad + toolinfo
                else:
                    toolinfo = ' ' + toolinfo

                self.output(location + message + toolinfo)

            self.output('')

        is_windows = sys.platform == 'win32'
        if total_issues:
            self.output(
                click.style(
                    u'{icon}{num_issues} issues found.'.format(  # noqa: @2to3
                        icon='' if is_windows else u'\u2717 ',  # noqa: @2to3
                        num_issues=total_issues,
                    ),
                    fg='yellow',
                    bold=True,
                )
            )
        else:
            self.output(
                click.style(
                    u'{icon}No issues found!'.format(  # noqa: @2to3
                        icon='' if is_windows else u'\u2714 ',  # noqa: @2to3
                    ),
                    fg='green',
                    bold=True,
                )
            )

<|endoftext|>


<commit_before>from nose.tools import raises, assert_raises

from pydigree.population import Population
from pydigree.individual import Individual
from pydigree.genotypes import Alleles, SparseAlleles, ChromosomeTemplate
from pydigree.genotypes import LabelledAlleles, InheritanceSpan
from pydigree.exceptions import NotMeaningfulError
import numpy as np

#############
# Alleles tests
#############

def test_alleles():
    a = Alleles(['1', '2', '3', ''])
    b = Alleles(['1', '3', '2', ''])

    assert a.nmark() == b.nmark() == 4

    # Test missingness
    assert a.missingcode == ''
    assert (a.missing == np.array([False, False, False, True])).all()
    assert (a.missing == b.missing).all()

    eq = (a == b)
    assert (eq == np.array([True, False, False, True])).all()

    # Test copy span
    z = Alleles(np.zeros(10))
    o = Alleles(np.ones(10))

    z.copy_span(o, 5, 8)
    expected_value = np.array(
        [0.,  0.,  0.,  0.,  0.,  1.,  1.,  1.,  0.,  0.])
    assert all(z == expected_value)

    # Test empty_like
    a = Alleles(np.zeros(10))
    b = a.empty_like()
    expected_value = Alleles(np.zeros(10), dtype=a.dtype)
    assert all(b == expected_value)

#############
# SparseAlleles tests
#############

def test_sparsealleles():
    a = SparseAlleles(['1', '2', '3', ''])
    b = SparseAlleles(['1', '3', '2', ''])

    assert a.nmark() == b.nmark() == 4
    assert (a.missing == np.array([False, False, False, True])).all()
    assert (a.missing == b.missing).all()

    # Test todense
    assert (a.todense() == ['1', '2', '3', '']).all()
    assert isinstance(a.todense(), Alleles)

    # Test equality between chromosome equality
    eq = (a == b)
    assert (eq == np.array([True, False, False, True])).all()
    assert ((a == b.todense()) == np.array([True, False, False, True])).all()
    assert np.all((a != b) == np.logical_not(eq))

def test_alleles_meaninglesscomparisions():
    # Comparsions like >, <, >=, <= aren't meaningful for genotypes
    a = Alleles(['1', '2', '3', ''])
    b = Alleles(['1', '3', '2', ''])

    # Can't test an expression so we make a throwaway function to test
    assert_raises(NotMeaningfulError, lambda x, y: x < y, a, b)
    assert_raises(NotMeaningfulError, lambda x, y: x > y, a, b)
    assert_raises(NotMeaningfulError, lambda x, y: x >= y, a, b)
    assert_raises(NotMeaningfulError, lambda x, y: x <= y, a, b)

def test_sparsealleles_meaninglesscomparisions():
    # Comparsions like >, <, >=, <= aren't meaningful for genotypes
    a = SparseAlleles(['1', '2', '3', ''])
    b = SparseAlleles(['1', '3', '2', ''])

    # Can't test an expression so we make a throwaway function to test
    assert_raises(NotMeaningfulError, lambda x, y: x < y, a, b)
    assert_raises(NotMeaningfulError, lambda x, y: x > y, a, b)
    assert_raises(NotMeaningfulError, lambda x, y: x >= y, a, b)
    assert_raises(NotMeaningfulError, lambda x, y: x <= y, a, b)

@raises(ValueError)
def test_sparse_wrongtypecomparsion():
    a = SparseAlleles(['1', '2', '3', ''])
    a == 3

@raises(ValueError)
def test_sparse_wrongsizecomparision():
    a = SparseAlleles(['1', '2', '3', ''])
    b = SparseAlleles(['1', '3'])
    a == b

@raises(ValueError)
def test_sparse_norefscalarcomparison():
    a = SparseAlleles(['1', '2', '3', ''])
    a == '3'

def test_array2missing():
    missingcode = 0
    vals = np.array([0, 1, 0, 0, 1, 0, 2], dtype=np.uint)
    assert all(SparseAlleles._array2missing(vals, missingcode) == np.array([0, 2, 3, 5]))

def test_array2nonref():
    refcode = 0
    missingcode = 0
    vals = np.array([0, 1, 0, 0, 1, 0, 2], dtype=np.uint)
    o = SparseAlleles._array2nonref(vals, refcode, missingcode)
    assert o == {1: 1, 4: 1, 6: 2}

#############
# InheritanceSpan
#############

def test_inhertancespan():
    # Inheritance span doesnt really do much. In fact, the only
    # reason it has an __eq__ method is for unittesting some LabelledAlleles
    # methods.
    IS = InheritanceSpan
    a = IS(1, 0, 0, 0, 50)
    b = IS(1, 0, 0, 0, 50)
    c = IS(2, 1, 1, 30, 40)
    assert a == b
    assert a != c and b != c
#############
# LabelledAlleles
#############

def test_labelledalleles():
    IS = InheritanceSpan

    ngenos = 50
    p = Population()
    c = ChromosomeTemplate()
    for i in xrange(ngenos):
        c.add_genotype()
    p.add_chromosome(c)

    a = Individual(p, 1)
    actual = LabelledAlleles.founder_chromosome(a, 0, 0, chromobj=c)
    expected = LabelledAlleles(spans=[IS(a, 0, 0, 0, ngenos)], chromobj=c)
    assert actual == expected

def test_labelledallele_delabeler():
    ngenos = 10  # Number of genotypes per chromosome
    if ngenos % 2 == 1:
        raise ValueError('Even number of genotypes needed')

    p = Population()
    c = ChromosomeTemplate()
    for i in xrange(ngenos):
        c.add_genotype()
    p.add_chromosome(c)

    a = Individual(p, 1)
    a._init_genotypes(blankchroms=False)
    a.genotypes[0][0] = Alleles([1]*ngenos)
    a.genotypes[0][1] = Alleles([2]*ngenos)

    b = Individual(p, 2)
    b._init_genotypes(blankchroms=False)
    b.genotypes[0][0] = Alleles([3] * ngenos)
    b.genotypes[0][1] = Alleles([4] * ngenos)

    chromatid_spans = [InheritanceSpan(a, 0, 0, 0, ngenos/2),
                       InheritanceSpan(b, 0, 1, ngenos/2, ngenos)]
    chromatid = LabelledAlleles(spans=chromatid_spans, chromobj=c)

    expected_value = [1]*(ngenos/2) + [4] * (ngenos/2)
    expected_value = Alleles(expected_value)

    actual_value = chromatid.delabel()
    assert all(actual_value == expected_value)

<commit_msg>test sparse equals<commit_after>from nose.tools import raises, assert_raises

from pydigree.population import Population
from pydigree.individual import Individual
from pydigree.genotypes import Alleles, SparseAlleles, ChromosomeTemplate
from pydigree.genotypes import LabelledAlleles, InheritanceSpan
from pydigree.exceptions import NotMeaningfulError
import numpy as np

#############
# Alleles tests
#############

def test_alleles():
    a = Alleles(['1', '2', '3', ''])
    b = Alleles(['1', '3', '2', ''])

    assert a.nmark() == b.nmark() == 4

    # Test missingness
    assert a.missingcode == ''
    assert (a.missing == np.array([False, False, False, True])).all()
    assert (a.missing == b.missing).all()

    eq = (a == b)
    assert (eq == np.array([True, False, False, True])).all()

    # Test copy span
    z = Alleles(np.zeros(10))
    o = Alleles(np.ones(10))

    z.copy_span(o, 5, 8)
    expected_value = np.array(
        [0.,  0.,  0.,  0.,  0.,  1.,  1.,  1.,  0.,  0.])
    assert all(z == expected_value)

    # Test empty_like
    a = Alleles(np.zeros(10))
    b = a.empty_like()
    expected_value = Alleles(np.zeros(10), dtype=a.dtype)
    assert all(b == expected_value)

#############
# SparseAlleles tests
#############

def test_sparsealleles():
    a = SparseAlleles(['1', '2', '3', ''])
    b = SparseAlleles(['1', '3', '2', ''])

    assert a.nmark() == b.nmark() == 4
    assert (a.missing == np.array([False, False, False, True])).all()
    assert (a.missing == b.missing).all()

    # Test todense
    assert (a.todense() == ['1', '2', '3', '']).all()
    assert isinstance(a.todense(), Alleles)

    # Test equality between chromosome equality
    eq = (a == b)
    assert (eq == np.array([True, False, False, True])).all()
    assert ((a == b.todense()) == np.array([True, False, False, True])).all()
    assert np.all((a != b) == np.logical_not(eq))

def test_alleles_meaninglesscomparisions():
    # Comparsions like >, <, >=, <= aren't meaningful for genotypes
    a = Alleles(['1', '2', '3', ''])
    b = Alleles(['1', '3', '2', ''])

    # Can't test an expression so we make a throwaway function to test
    assert_raises(NotMeaningfulError, lambda x, y: x < y, a, b)
    assert_raises(NotMeaningfulError, lambda x, y: x > y, a, b)
    assert_raises(NotMeaningfulError, lambda x, y: x >= y, a, b)
    assert_raises(NotMeaningfulError, lambda x, y: x <= y, a, b)

def test_sparsealleles_meaninglesscomparisions():
    # Comparsions like >, <, >=, <= aren't meaningful for genotypes
    a = SparseAlleles(['1', '2', '3', ''])
    b = SparseAlleles(['1', '3', '2', ''])

    # Can't test an expression so we make a throwaway function to test
    assert_raises(NotMeaningfulError, lambda x, y: x < y, a, b)
    assert_raises(NotMeaningfulError, lambda x, y: x > y, a, b)
    assert_raises(NotMeaningfulError, lambda x, y: x >= y, a, b)
    assert_raises(NotMeaningfulError, lambda x, y: x <= y, a, b)

@raises(ValueError)
def test_sparse_wrongtypecomparsion():
    a = SparseAlleles(['1', '2', '3', ''])
    a == 3

@raises(ValueError)
def test_sparse_wrongsizecomparision():
    a = SparseAlleles(['1', '2', '3', ''])
    b = SparseAlleles(['1', '3'])
    a == b

@raises(ValueError)
def test_sparse_norefscalarcomparison():
    a = SparseAlleles(['1', '2', '3', ''])
    a == '3'

def test_sparseeq():
    a = SparseAlleles([1,2,3,4])
    b = SparseAlleles([1,3,3,4])

    obs = (a == b)
    expected = np.array([True, False, True, True])
    assert np.all(obs == expected)

def test_array2missing():
    missingcode = 0
    vals = np.array([0, 1, 0, 0, 1, 0, 2], dtype=np.uint)
    assert all(SparseAlleles._array2missing(vals, missingcode) == np.array([0, 2, 3, 5]))

def test_array2nonref():
    refcode = 0
    missingcode = 0
    vals = np.array([0, 1, 0, 0, 1, 0, 2], dtype=np.uint)
    o = SparseAlleles._array2nonref(vals, refcode, missingcode)
    assert o == {1: 1, 4: 1, 6: 2}

#############
# InheritanceSpan
#############

def test_inhertancespan():
    # Inheritance span doesnt really do much. In fact, the only
    # reason it has an __eq__ method is for unittesting some LabelledAlleles
    # methods.
    IS = InheritanceSpan
    a = IS(1, 0, 0, 0, 50)
    b = IS(1, 0, 0, 0, 50)
    c = IS(2, 1, 1, 30, 40)
    assert a == b
    assert a != c and b != c
#############
# LabelledAlleles
#############

def test_labelledalleles():
    IS = InheritanceSpan

    ngenos = 50
    p = Population()
    c = ChromosomeTemplate()
    for i in xrange(ngenos):
        c.add_genotype()
    p.add_chromosome(c)

    a = Individual(p, 1)
    actual = LabelledAlleles.founder_chromosome(a, 0, 0, chromobj=c)
    expected = LabelledAlleles(spans=[IS(a, 0, 0, 0, ngenos)], chromobj=c)
    assert actual == expected

def test_labelledallele_delabeler():
    ngenos = 10  # Number of genotypes per chromosome
    if ngenos % 2 == 1:
        raise ValueError('Even number of genotypes needed')

    p = Population()
    c = ChromosomeTemplate()
    for i in xrange(ngenos):
        c.add_genotype()
    p.add_chromosome(c)

    a = Individual(p, 1)
    a._init_genotypes(blankchroms=False)
    a.genotypes[0][0] = Alleles([1]*ngenos)
    a.genotypes[0][1] = Alleles([2]*ngenos)

    b = Individual(p, 2)
    b._init_genotypes(blankchroms=False)
    b.genotypes[0][0] = Alleles([3] * ngenos)
    b.genotypes[0][1] = Alleles([4] * ngenos)

    chromatid_spans = [InheritanceSpan(a, 0, 0, 0, ngenos/2),
                       InheritanceSpan(b, 0, 1, ngenos/2, ngenos)]
    chromatid = LabelledAlleles(spans=chromatid_spans, chromobj=c)

    expected_value = [1]*(ngenos/2) + [4] * (ngenos/2)
    expected_value = Alleles(expected_value)

    actual_value = chromatid.delabel()
    assert all(actual_value == expected_value)

<|endoftext|>


<commit_before>### based on "test_exemplars" in test_validate.py
### not sure all these imports are needed
import unittest
import pytest
import logging, os, re, unicodedata
from lxml.etree import RelaxNG, parse, DocumentInvalid
import sldr.UnicodeSets as usets

def iscldr(ldml):
    i = ldml.ldml.root.find(".//identity/special/sil:identity", {v:k for k,v in ldml.ldml.namespaces.items()})
    if i is not None and i.get('source', "") == "cldr":
        return True
    return False

def test_autonym(ldml):
    """ Test that all characters in the autonym are in the main exemplar """
    if iscldr(ldml):    # short circuit CLDR for now until they/we resolve the faults in their data
        return
    filename = os.path.basename(ldml.ldml.fname)    # get filename for reference

#   get main exemplar
    main = None
    for e in ldml.ldml.root.findall('.//characters/exemplarCharacters'):
        t = e.get('type', None)
        if t: continue
        main_exem = e.text
        if len(main_exem) <= 2:
#            assert False, filename + " has empty main exemplar"    ### 2021-10-22 nuf.xml is example
            return
        main = usets.parse(main_exem, 'NFD')[0].asSet()
        break
    if not main:
#        assert False, filename + " has no main exemplar" ### should be target of another test
        return

#   get language id
    lid = filename[:-4] #.replace("_", "-")
    #langid = ldml.ldml.root.find("identity/language").get("type")
    ### should be target of another test:
    ### could check that filename.split('_')[0] == langid
    #assert filename.split('_')[0] == langid, filename + " " + langid + " don't correspond"

#   get name of this language
    names = ldml.ldml.root.find("localeDisplayNames/languages")
    if names is None:
#        assert False, filename + " has no localeDisplayNames"
        return
    autonym = names.findall('language[@type="{0}"]'.format(lid))
    if autonym is None or len(autonym) < 1:
        assert False, filename + " " + lid + ": Name of language in this language is missing"
        return
    autonym_text = unicodedata.normalize("NFD", autonym[0].text.lower())
    if len(autonym_text) < 1:
        assert False, filename + " " + lid + ": Name of language in this language is empty"
        return
#   The real test: is every character in lower case version of autonym in main exemplar?
    mainre = "^(" + "|".join(sorted(main, key=lambda x: (-len(x), x)) + ["\\s", ",", "-"]) + ")*$"
    assert re.match(mainre, autonym_text) is not None, \
                filename + " " + lid + ": Name of language (" + autonym_text \
                + ") contains characters not in main exemplar " + main_exem

<commit_msg>handle case where text is missing<commit_after>### based on "test_exemplars" in test_validate.py
### not sure all these imports are needed
import unittest
import pytest
import logging, os, re, unicodedata
from lxml.etree import RelaxNG, parse, DocumentInvalid
import sldr.UnicodeSets as usets

def iscldr(ldml):
    i = ldml.ldml.root.find(".//identity/special/sil:identity", {v:k for k,v in ldml.ldml.namespaces.items()})
    if i is not None and i.get('source', "") == "cldr":
        return True
    return False

def test_autonym(ldml):
    """ Test that all characters in the autonym are in the main exemplar """
    if iscldr(ldml):    # short circuit CLDR for now until they/we resolve the faults in their data
        return
    filename = os.path.basename(ldml.ldml.fname)    # get filename for reference

#   get main exemplar
    main = None
    for e in ldml.ldml.root.findall('.//characters/exemplarCharacters'):
        t = e.get('type', None)
        if t: continue
        main_exem = e.text
        if main_exem and len(main_exem) <= 2:       ### 2021-10-22 pcg_Taml.xml is example where text is missing
#            assert False, filename + " has empty main exemplar" ### 2021-10-22 nuf.xml is ex where text is "[]"
            return
        main = usets.parse(main_exem, 'NFD')[0].asSet()
        break
    if not main:
#        assert False, filename + " has no main exemplar" ### should be target of another test
        return

#   get language id
    lid = filename[:-4] #.replace("_", "-")
    #langid = ldml.ldml.root.find("identity/language").get("type")
    ### should be target of another test:
    ### could check that filename.split('_')[0] == langid
    #assert filename.split('_')[0] == langid, filename + " " + langid + " don't correspond"

#   get name of this language
    names = ldml.ldml.root.find("localeDisplayNames/languages")
    if names is None:
#        assert False, filename + " has no localeDisplayNames"
        return
    autonym = names.findall('language[@type="{0}"]'.format(lid))
    if autonym is None or len(autonym) < 1:
        assert False, filename + " " + lid + ": Name of language in this language is missing"
        return
    autonym_text = unicodedata.normalize("NFD", autonym[0].text.lower())
    if len(autonym_text) < 1:
        assert False, filename + " " + lid + ": Name of language in this language is empty"
        return
#   The real test: is every character in lower case version of autonym in main exemplar?
    mainre = "^(" + "|".join(sorted(main, key=lambda x: (-len(x), x)) + ["\\s", ",", "-"]) + ")*$"
    assert re.match(mainre, autonym_text) is not None, \
                filename + " " + lid + ": Name of language (" + autonym_text \
                + ") contains characters not in main exemplar " + main_exem

<|endoftext|>


<commit_before>from __future__ import unicode_literals

import threading

import mock

from mopidy import backend as backend_api

import pykka

import spotify

from mopidy_spotify import backend, library, playback, playlists

def get_backend(config, session_mock=None):
    obj = backend.SpotifyBackend(config=config, audio=None)
    if session_mock:
        obj._session = session_mock
    else:
        obj._session = mock.Mock()
        obj._session.playlist_container = []
    obj._event_loop = mock.Mock()
    return obj

def test_uri_schemes(spotify_mock, config):
    backend = get_backend(config)

    assert 'spotify' in backend.uri_schemes

def test_init_sets_up_the_providers(spotify_mock, config):
    backend = get_backend(config)

    assert isinstance(backend.library, library.SpotifyLibraryProvider)
    assert isinstance(backend.library, backend_api.LibraryProvider)

    assert isinstance(backend.playback, playback.SpotifyPlaybackProvider)
    assert isinstance(backend.playback, backend_api.PlaybackProvider)

    assert isinstance(backend.playlists, playlists.SpotifyPlaylistsProvider)
    assert isinstance(backend.playlists, backend_api.PlaylistsProvider)

def test_init_disables_playlists_provider_if_not_allowed(spotify_mock, config):
    config['spotify']['allow_playlists'] = False

    backend = get_backend(config)

    assert backend.playlists is None

def test_on_start_creates_configured_session(spotify_mock, config):
    cache_location_mock = mock.PropertyMock()
    settings_location_mock = mock.PropertyMock()
    config_mock = spotify_mock.Config.return_value
    type(config_mock).cache_location = cache_location_mock
    type(config_mock).settings_location = settings_location_mock

    get_backend(config).on_start()

    spotify_mock.Config.assert_called_once_with()
    config_mock.load_application_key_file.assert_called_once_with(mock.ANY)
    cache_location_mock.assert_called_once_with('/my/cache/dir')
    settings_location_mock.assert_called_once_with('/my/settings/dir')
    spotify_mock.Session.assert_called_once_with(config_mock)

def test_on_start_disallows_network_if_config_is_set(spotify_mock, config):
    session = spotify_mock.Session.return_value
    allow_network_mock = mock.PropertyMock()
    type(session.connection).allow_network = allow_network_mock
    config['spotify']['allow_network'] = False

    get_backend(config).on_start()

    allow_network_mock.assert_called_once_with(False)

def test_on_start_configures_preferred_bitrate(spotify_mock, config):
    session = spotify_mock.Session.return_value
    preferred_bitrate_mock = mock.PropertyMock()
    type(session).preferred_bitrate = preferred_bitrate_mock
    config['spotify']['bitrate'] = 320

    get_backend(config).on_start()

    preferred_bitrate_mock.assert_called_once_with(
        spotify.Bitrate.BITRATE_320k)

def test_on_start_configures_volume_normalization(spotify_mock, config):
    session = spotify_mock.Session.return_value
    volume_normalization_mock = mock.PropertyMock()
    type(session).volume_normalization = volume_normalization_mock
    config['spotify']['volume_normalization'] = False

    get_backend(config).on_start()

    volume_normalization_mock.assert_called_once_with(False)

def test_on_start_adds_connection_state_changed_handler_to_session(
        spotify_mock, config):
    session = spotify_mock.Session.return_value

    get_backend(config).on_start()

    assert (mock.call(
        spotify_mock.SessionEvent.CONNECTION_STATE_UPDATED,
        backend.on_connection_state_changed,
        backend.SpotifyBackend._logged_in,
        backend.SpotifyBackend._logged_out,
        backend.SpotifyBackend._online,
        mock.ANY)
        in session.on.call_args_list)

def test_on_start_adds_play_token_lost_handler_to_session(
        spotify_mock, config):
    session = spotify_mock.Session.return_value

    obj = get_backend(config)
    obj.on_start()

    assert (mock.call(
        spotify_mock.SessionEvent.PLAY_TOKEN_LOST,
        backend.on_play_token_lost, mock.ANY)
        in session.on.call_args_list)

def test_on_start_starts_the_pyspotify_event_loop(spotify_mock, config):
    backend = get_backend(config)
    backend.on_start()

    spotify_mock.EventLoop.assert_called_once_with(backend._session)
    spotify_mock.EventLoop.return_value.start.assert_called_once_with()

def test_on_start_logs_in(spotify_mock, config):
    backend = get_backend(config)
    backend.on_start()

    spotify_mock.Session.return_value.login.assert_called_once_with(
        'alice', 'password')

def test_on_stop_logs_out_and_waits_for_logout_to_complete(
        spotify_mock, config, caplog):
    backend = get_backend(config)
    backend._logged_out = mock.Mock()

    backend.on_stop()

    assert 'Logging out of Spotify' in caplog.text()
    backend._session.logout.assert_called_once_with()
    backend._logged_out.wait.assert_called_once_with()
    backend._event_loop.stop.assert_called_once_with()

def test_on_connection_state_changed_when_logged_out(spotify_mock, caplog):
    session_mock = spotify_mock.Session.return_value
    session_mock.connection.state = spotify_mock.ConnectionState.LOGGED_OUT
    logged_in_event = threading.Event()
    logged_out_event = threading.Event()
    online_event = threading.Event()
    actor_mock = mock.Mock(spec=backend.SpotifyBackend)

    backend.on_connection_state_changed(
        session_mock, logged_in_event, logged_out_event, online_event,
        actor_mock)

    assert 'Logged out of Spotify' in caplog.text()
    assert not logged_in_event.is_set()
    assert logged_out_event.is_set()
    assert not online_event.is_set()

def test_on_connection_state_changed_when_logged_in(spotify_mock, caplog):
    session_mock = spotify_mock.Session.return_value
    session_mock.connection.state = spotify_mock.ConnectionState.LOGGED_IN
    logged_in_event = threading.Event()
    logged_out_event = threading.Event()
    online_event = threading.Event()
    actor_mock = mock.Mock(spec=backend.SpotifyBackend)

    backend.on_connection_state_changed(
        session_mock, logged_in_event, logged_out_event, online_event,
        actor_mock)

    assert 'Logged in to Spotify in online mode' in caplog.text()
    assert logged_in_event.is_set()
    assert not logged_out_event.is_set()
    assert online_event.is_set()
    actor_mock.on_logged_in.assert_called_once_with()

def test_on_connection_state_changed_when_disconnected(spotify_mock, caplog):
    session_mock = spotify_mock.Session.return_value
    session_mock.connection.state = spotify_mock.ConnectionState.DISCONNECTED
    logged_in_event = threading.Event()
    logged_out_event = threading.Event()
    online_event = threading.Event()
    actor_mock = mock.Mock(spec=backend.SpotifyBackend)

    backend.on_connection_state_changed(
        session_mock, logged_in_event, logged_out_event, online_event,
        actor_mock)

    assert 'Disconnected from Spotify' in caplog.text()
    assert not online_event.is_set()

def test_on_connection_state_changed_when_offline(spotify_mock, caplog):
    session_mock = spotify_mock.Session.return_value
    session_mock.connection.state = spotify_mock.ConnectionState.OFFLINE
    logged_in_event = threading.Event()
    logged_out_event = threading.Event()
    online_event = threading.Event()
    actor_mock = mock.Mock(spec=backend.SpotifyBackend)

    backend.on_connection_state_changed(
        session_mock, logged_in_event, logged_out_event, online_event,
        actor_mock)

    assert 'Logged in to Spotify in offline mode' in caplog.text()
    assert logged_in_event.is_set()
    assert not logged_out_event.is_set()
    assert not online_event.is_set()

def test_on_logged_in_event_activates_private_session(
        spotify_mock, config, caplog):
    session_mock = spotify_mock.Session.return_value
    private_session_mock = mock.PropertyMock()
    type(session_mock.social).private_session = private_session_mock
    config['spotify']['private_session'] = True
    backend = get_backend(config, session_mock)

    backend.on_logged_in()

    assert 'Spotify private session activated' in caplog.text()
    private_session_mock.assert_called_once_with(True)

def test_on_play_token_lost_messages_the_actor(spotify_mock, caplog):
    session_mock = spotify_mock.Session.return_value
    actor_mock = mock.Mock(spec=backend.SpotifyBackend)

    backend.on_play_token_lost(session_mock, actor_mock)

    assert 'Spotify play token lost' in caplog.text()
    actor_mock.on_play_token_lost.assert_called_once_with()

def test_on_play_token_lost_event_when_playing(spotify_mock, config, caplog):
    session_mock = spotify_mock.Session.return_value
    session_mock.player.state = spotify_mock.PlayerState.PLAYING
    backend = get_backend(config, session_mock)
    backend.playback = mock.Mock(spec=playback.SpotifyPlaybackProvider)

    backend.on_play_token_lost()

    assert (
        'Spotify has been paused because your account is '
        'being used somewhere else.' in caplog.text())
    backend.playback.pause.assert_called_once_with()

def test_on_play_token_lost_event_when_not_playing(
        spotify_mock, config, caplog):
    session_mock = spotify_mock.Session.return_value
    session_mock.player.state = spotify_mock.PlayerState.UNLOADED
    backend = get_backend(config, session_mock)
    backend.playback = mock.Mock(spec=playback.SpotifyPlaybackProvider)

    backend.on_play_token_lost()

    assert 'Spotify has been paused' not in caplog.text()
    assert backend.playback.pause.call_count == 0
<commit_msg>tests: Remove unused import<commit_after>from __future__ import unicode_literals

import threading

import mock

from mopidy import backend as backend_api

import spotify

from mopidy_spotify import backend, library, playback, playlists

def get_backend(config, session_mock=None):
    obj = backend.SpotifyBackend(config=config, audio=None)
    if session_mock:
        obj._session = session_mock
    else:
        obj._session = mock.Mock()
        obj._session.playlist_container = []
    obj._event_loop = mock.Mock()
    return obj

def test_uri_schemes(spotify_mock, config):
    backend = get_backend(config)

    assert 'spotify' in backend.uri_schemes

def test_init_sets_up_the_providers(spotify_mock, config):
    backend = get_backend(config)

    assert isinstance(backend.library, library.SpotifyLibraryProvider)
    assert isinstance(backend.library, backend_api.LibraryProvider)

    assert isinstance(backend.playback, playback.SpotifyPlaybackProvider)
    assert isinstance(backend.playback, backend_api.PlaybackProvider)

    assert isinstance(backend.playlists, playlists.SpotifyPlaylistsProvider)
    assert isinstance(backend.playlists, backend_api.PlaylistsProvider)

def test_init_disables_playlists_provider_if_not_allowed(spotify_mock, config):
    config['spotify']['allow_playlists'] = False

    backend = get_backend(config)

    assert backend.playlists is None

def test_on_start_creates_configured_session(spotify_mock, config):
    cache_location_mock = mock.PropertyMock()
    settings_location_mock = mock.PropertyMock()
    config_mock = spotify_mock.Config.return_value
    type(config_mock).cache_location = cache_location_mock
    type(config_mock).settings_location = settings_location_mock

    get_backend(config).on_start()

    spotify_mock.Config.assert_called_once_with()
    config_mock.load_application_key_file.assert_called_once_with(mock.ANY)
    cache_location_mock.assert_called_once_with('/my/cache/dir')
    settings_location_mock.assert_called_once_with('/my/settings/dir')
    spotify_mock.Session.assert_called_once_with(config_mock)

def test_on_start_disallows_network_if_config_is_set(spotify_mock, config):
    session = spotify_mock.Session.return_value
    allow_network_mock = mock.PropertyMock()
    type(session.connection).allow_network = allow_network_mock
    config['spotify']['allow_network'] = False

    get_backend(config).on_start()

    allow_network_mock.assert_called_once_with(False)

def test_on_start_configures_preferred_bitrate(spotify_mock, config):
    session = spotify_mock.Session.return_value
    preferred_bitrate_mock = mock.PropertyMock()
    type(session).preferred_bitrate = preferred_bitrate_mock
    config['spotify']['bitrate'] = 320

    get_backend(config).on_start()

    preferred_bitrate_mock.assert_called_once_with(
        spotify.Bitrate.BITRATE_320k)

def test_on_start_configures_volume_normalization(spotify_mock, config):
    session = spotify_mock.Session.return_value
    volume_normalization_mock = mock.PropertyMock()
    type(session).volume_normalization = volume_normalization_mock
    config['spotify']['volume_normalization'] = False

    get_backend(config).on_start()

    volume_normalization_mock.assert_called_once_with(False)

def test_on_start_adds_connection_state_changed_handler_to_session(
        spotify_mock, config):
    session = spotify_mock.Session.return_value

    get_backend(config).on_start()

    assert (mock.call(
        spotify_mock.SessionEvent.CONNECTION_STATE_UPDATED,
        backend.on_connection_state_changed,
        backend.SpotifyBackend._logged_in,
        backend.SpotifyBackend._logged_out,
        backend.SpotifyBackend._online,
        mock.ANY)
        in session.on.call_args_list)

def test_on_start_adds_play_token_lost_handler_to_session(
        spotify_mock, config):
    session = spotify_mock.Session.return_value

    obj = get_backend(config)
    obj.on_start()

    assert (mock.call(
        spotify_mock.SessionEvent.PLAY_TOKEN_LOST,
        backend.on_play_token_lost, mock.ANY)
        in session.on.call_args_list)

def test_on_start_starts_the_pyspotify_event_loop(spotify_mock, config):
    backend = get_backend(config)
    backend.on_start()

    spotify_mock.EventLoop.assert_called_once_with(backend._session)
    spotify_mock.EventLoop.return_value.start.assert_called_once_with()

def test_on_start_logs_in(spotify_mock, config):
    backend = get_backend(config)
    backend.on_start()

    spotify_mock.Session.return_value.login.assert_called_once_with(
        'alice', 'password')

def test_on_stop_logs_out_and_waits_for_logout_to_complete(
        spotify_mock, config, caplog):
    backend = get_backend(config)
    backend._logged_out = mock.Mock()

    backend.on_stop()

    assert 'Logging out of Spotify' in caplog.text()
    backend._session.logout.assert_called_once_with()
    backend._logged_out.wait.assert_called_once_with()
    backend._event_loop.stop.assert_called_once_with()

def test_on_connection_state_changed_when_logged_out(spotify_mock, caplog):
    session_mock = spotify_mock.Session.return_value
    session_mock.connection.state = spotify_mock.ConnectionState.LOGGED_OUT
    logged_in_event = threading.Event()
    logged_out_event = threading.Event()
    online_event = threading.Event()
    actor_mock = mock.Mock(spec=backend.SpotifyBackend)

    backend.on_connection_state_changed(
        session_mock, logged_in_event, logged_out_event, online_event,
        actor_mock)

    assert 'Logged out of Spotify' in caplog.text()
    assert not logged_in_event.is_set()
    assert logged_out_event.is_set()
    assert not online_event.is_set()

def test_on_connection_state_changed_when_logged_in(spotify_mock, caplog):
    session_mock = spotify_mock.Session.return_value
    session_mock.connection.state = spotify_mock.ConnectionState.LOGGED_IN
    logged_in_event = threading.Event()
    logged_out_event = threading.Event()
    online_event = threading.Event()
    actor_mock = mock.Mock(spec=backend.SpotifyBackend)

    backend.on_connection_state_changed(
        session_mock, logged_in_event, logged_out_event, online_event,
        actor_mock)

    assert 'Logged in to Spotify in online mode' in caplog.text()
    assert logged_in_event.is_set()
    assert not logged_out_event.is_set()
    assert online_event.is_set()
    actor_mock.on_logged_in.assert_called_once_with()

def test_on_connection_state_changed_when_disconnected(spotify_mock, caplog):
    session_mock = spotify_mock.Session.return_value
    session_mock.connection.state = spotify_mock.ConnectionState.DISCONNECTED
    logged_in_event = threading.Event()
    logged_out_event = threading.Event()
    online_event = threading.Event()
    actor_mock = mock.Mock(spec=backend.SpotifyBackend)

    backend.on_connection_state_changed(
        session_mock, logged_in_event, logged_out_event, online_event,
        actor_mock)

    assert 'Disconnected from Spotify' in caplog.text()
    assert not online_event.is_set()

def test_on_connection_state_changed_when_offline(spotify_mock, caplog):
    session_mock = spotify_mock.Session.return_value
    session_mock.connection.state = spotify_mock.ConnectionState.OFFLINE
    logged_in_event = threading.Event()
    logged_out_event = threading.Event()
    online_event = threading.Event()
    actor_mock = mock.Mock(spec=backend.SpotifyBackend)

    backend.on_connection_state_changed(
        session_mock, logged_in_event, logged_out_event, online_event,
        actor_mock)

    assert 'Logged in to Spotify in offline mode' in caplog.text()
    assert logged_in_event.is_set()
    assert not logged_out_event.is_set()
    assert not online_event.is_set()

def test_on_logged_in_event_activates_private_session(
        spotify_mock, config, caplog):
    session_mock = spotify_mock.Session.return_value
    private_session_mock = mock.PropertyMock()
    type(session_mock.social).private_session = private_session_mock
    config['spotify']['private_session'] = True
    backend = get_backend(config, session_mock)

    backend.on_logged_in()

    assert 'Spotify private session activated' in caplog.text()
    private_session_mock.assert_called_once_with(True)

def test_on_play_token_lost_messages_the_actor(spotify_mock, caplog):
    session_mock = spotify_mock.Session.return_value
    actor_mock = mock.Mock(spec=backend.SpotifyBackend)

    backend.on_play_token_lost(session_mock, actor_mock)

    assert 'Spotify play token lost' in caplog.text()
    actor_mock.on_play_token_lost.assert_called_once_with()

def test_on_play_token_lost_event_when_playing(spotify_mock, config, caplog):
    session_mock = spotify_mock.Session.return_value
    session_mock.player.state = spotify_mock.PlayerState.PLAYING
    backend = get_backend(config, session_mock)
    backend.playback = mock.Mock(spec=playback.SpotifyPlaybackProvider)

    backend.on_play_token_lost()

    assert (
        'Spotify has been paused because your account is '
        'being used somewhere else.' in caplog.text())
    backend.playback.pause.assert_called_once_with()

def test_on_play_token_lost_event_when_not_playing(
        spotify_mock, config, caplog):
    session_mock = spotify_mock.Session.return_value
    session_mock.player.state = spotify_mock.PlayerState.UNLOADED
    backend = get_backend(config, session_mock)
    backend.playback = mock.Mock(spec=playback.SpotifyPlaybackProvider)

    backend.on_play_token_lost()

    assert 'Spotify has been paused' not in caplog.text()
    assert backend.playback.pause.call_count == 0
<|endoftext|>


<commit_before>from __future__ import absolute_import

import mock
from nose.tools import assert_equal, assert_not_equal
from storymarket import (Audio, Data, Photo, Text, Video, Category, Subtype, Org,
                         PricingScheme, RightsScheme)
from storymarket.content import User, BinaryContentManager
from StringIO import StringIO
from .fakeserver import FakeStorymarket
from .utils import (assert_isinstance, assert_list_api, assert_get_api,
                    assert_delete_api, assert_create_api, assert_update_api)

sm = FakeStorymarket()

# Use a predictable MIME boundary.

BOUNDARY = 'BOUNDARY'
def setup():
    BinaryContentManager._multipart_boundary = BOUNDARY
def teardown():
    BinaryContentManager._multipart_boundary = None

def test_content_apis():
    test_data = [
        (sm.audio,  Audio, 'audio', {'duration': '1:00'}),
        (sm.data,   Data,  'data',  {}),
        (sm.photos, Photo, 'photo', {'caption': 'Hi!'}),
        (sm.text,   Text,  'text',  {'content': 'Hi!'}),
        (sm.video,  Video, 'video', {'duration': '1:00'})
    ]

    # Data carefully constructed so that we've got both URLs and objects
    # for related data.
    create_update_data = {
        'category': '/content/sub_category/1/',
        'author': 'frank',
        'title': 'Sample API title',
        'org': sm.orgs.get(1),
        'tags': 'one, two, three',
        'rights_scheme': 1,
        'pricing_scheme': sm.pricing.get(1),
    }

    def assert_instance_delete(instance, manager):
        with mock.patch.object(manager, 'delete'):
            instance.delete()
            manager.delete.assert_called_with(instance)

    def assert_instance_save(instance, manager):
        with mock.patch.object(manager, 'update'):
            instance.save()
            manager.update.assert_called_with(instance)

    for (manager, cls, urlbit, extra_data) in test_data:
        list_url = 'content/%s/' % urlbit
        detail_url = 'content/%s/1/' % urlbit
        post_data = dict(create_update_data, **extra_data)
        instance = manager.get(1)

        yield assert_list_api, sm, manager.all, cls, list_url
        yield assert_get_api, sm, manager.get, cls, detail_url
        yield assert_delete_api, sm, manager.delete, cls, detail_url
        yield assert_instance_delete, instance, manager
        yield assert_create_api, sm, manager.create, instance, post_data, list_url
        yield assert_update_api, sm, manager.update, instance, post_data, detail_url
        yield assert_instance_save, instance, manager

def test_related_resource_properties():
    test_data = [
        ('author', User),
        ('category', Category),
        ('sub_type', Subtype),
        ('org', Org),
        ('pricing_scheme', PricingScheme),
        ('rights_scheme', RightsScheme),
        ('uploaded_by', User),
    ]

    resource = sm.audio.get(1)
    def check_related_resource_property(attname, cls):
        related = getattr(resource, attname)
        assert_isinstance(related, cls)

    for (attname, cls) in test_data:
        yield check_related_resource_property, attname, cls

def test_related_resource_properties_when_none():
    test_properties = ['author', 'category', 'org', 'pricing_scheme',
                       'rights_scheme', 'uploaded_by']

    def check_related_resource_property_when_none(attname):
        resource = sm.audio.get(1)
        setattr(resource, '_'+attname, None)
        assert_equal(getattr(resource, attname), None)

    for prop in test_properties:
        yield check_related_resource_property_when_none, prop

def test_blob_uploads():
    test_data = [
        (sm.audio, 'audio'),
        (sm.data, 'data'),
        (sm.photos, 'photo'),
        (sm.video, 'video')
    ]

    new_data = 'not really binary data'

    def check_blob_upload(manager, urlbit, data):
        resource = manager.get(1)
        expected_body = (
            '--%s\r\n' % BOUNDARY +
            'Content-Disposition: form-data; name="blob"\r\n' +
            'Content-Type: text/plain; charset=utf-8\r\n' +
            #'Content-Length: %s\r\n' % len(new_data) +
            '\r\n%s\r\n' % new_data +
            '--%s--\r\n' % BOUNDARY
        )

        # Try with
        resource.upload_blob(data)
        sm.assert_called('PUT', 'content/%s/1/blob/' % urlbit, body=expected_body)

    for (manager, urlbit) in test_data:
        # Check with both a string object and a fike-like object.
        yield check_blob_upload, manager, urlbit, new_data
        yield check_blob_upload, manager, urlbit, StringIO(new_data)

def test_user_eq():
    u1 = User({'username': 'u1', 'first_name': 'u', 'last_name': '1', 'email': '1@example.org'})
    u2 = User({'username': 'u2', 'first_name': 'u', 'last_name': '2', 'email': '2@example.org'})
    # Same username as u1, so == to u1.
    u3 = User({'username': 'u1', 'first_name': 'u', 'last_name': '3', 'email': '3@example.org'})

    assert_equal(u1, u1)
    assert_not_equal(u1, u2)
    assert_equal(u1, u3)<commit_msg>removed forgotten comment<commit_after>from __future__ import absolute_import

import mock
from nose.tools import assert_equal, assert_not_equal
from storymarket import (Audio, Data, Photo, Text, Video, Category, Subtype, Org,
                         PricingScheme, RightsScheme)
from storymarket.content import User, BinaryContentManager
from StringIO import StringIO
from .fakeserver import FakeStorymarket
from .utils import (assert_isinstance, assert_list_api, assert_get_api,
                    assert_delete_api, assert_create_api, assert_update_api)

sm = FakeStorymarket()

# Use a predictable MIME boundary.

BOUNDARY = 'BOUNDARY'
def setup():
    BinaryContentManager._multipart_boundary = BOUNDARY
def teardown():
    BinaryContentManager._multipart_boundary = None

def test_content_apis():
    test_data = [
        (sm.audio,  Audio, 'audio', {'duration': '1:00'}),
        (sm.data,   Data,  'data',  {}),
        (sm.photos, Photo, 'photo', {'caption': 'Hi!'}),
        (sm.text,   Text,  'text',  {'content': 'Hi!'}),
        (sm.video,  Video, 'video', {'duration': '1:00'})
    ]

    # Data carefully constructed so that we've got both URLs and objects
    # for related data.
    create_update_data = {
        'category': '/content/sub_category/1/',
        'author': 'frank',
        'title': 'Sample API title',
        'org': sm.orgs.get(1),
        'tags': 'one, two, three',
        'rights_scheme': 1,
        'pricing_scheme': sm.pricing.get(1),
    }

    def assert_instance_delete(instance, manager):
        with mock.patch.object(manager, 'delete'):
            instance.delete()
            manager.delete.assert_called_with(instance)

    def assert_instance_save(instance, manager):
        with mock.patch.object(manager, 'update'):
            instance.save()
            manager.update.assert_called_with(instance)

    for (manager, cls, urlbit, extra_data) in test_data:
        list_url = 'content/%s/' % urlbit
        detail_url = 'content/%s/1/' % urlbit
        post_data = dict(create_update_data, **extra_data)
        instance = manager.get(1)

        yield assert_list_api, sm, manager.all, cls, list_url
        yield assert_get_api, sm, manager.get, cls, detail_url
        yield assert_delete_api, sm, manager.delete, cls, detail_url
        yield assert_instance_delete, instance, manager
        yield assert_create_api, sm, manager.create, instance, post_data, list_url
        yield assert_update_api, sm, manager.update, instance, post_data, detail_url
        yield assert_instance_save, instance, manager

def test_related_resource_properties():
    test_data = [
        ('author', User),
        ('category', Category),
        ('sub_type', Subtype),
        ('org', Org),
        ('pricing_scheme', PricingScheme),
        ('rights_scheme', RightsScheme),
        ('uploaded_by', User),
    ]

    resource = sm.audio.get(1)
    def check_related_resource_property(attname, cls):
        related = getattr(resource, attname)
        assert_isinstance(related, cls)

    for (attname, cls) in test_data:
        yield check_related_resource_property, attname, cls

def test_related_resource_properties_when_none():
    test_properties = ['author', 'category', 'org', 'pricing_scheme',
                       'rights_scheme', 'uploaded_by']

    def check_related_resource_property_when_none(attname):
        resource = sm.audio.get(1)
        setattr(resource, '_'+attname, None)
        assert_equal(getattr(resource, attname), None)

    for prop in test_properties:
        yield check_related_resource_property_when_none, prop

def test_blob_uploads():
    test_data = [
        (sm.audio, 'audio'),
        (sm.data, 'data'),
        (sm.photos, 'photo'),
        (sm.video, 'video')
    ]

    new_data = 'not really binary data'

    def check_blob_upload(manager, urlbit, data):
        resource = manager.get(1)
        expected_body = (
            '--%s\r\n' % BOUNDARY +
            'Content-Disposition: form-data; name="blob"\r\n' +
            'Content-Type: text/plain; charset=utf-8\r\n' +
            '\r\n%s\r\n' % new_data +
            '--%s--\r\n' % BOUNDARY
        )

        # Try with
        resource.upload_blob(data)
        sm.assert_called('PUT', 'content/%s/1/blob/' % urlbit, body=expected_body)

    for (manager, urlbit) in test_data:
        # Check with both a string object and a fike-like object.
        yield check_blob_upload, manager, urlbit, new_data
        yield check_blob_upload, manager, urlbit, StringIO(new_data)

def test_user_eq():
    u1 = User({'username': 'u1', 'first_name': 'u', 'last_name': '1', 'email': '1@example.org'})
    u2 = User({'username': 'u2', 'first_name': 'u', 'last_name': '2', 'email': '2@example.org'})
    # Same username as u1, so == to u1.
    u3 = User({'username': 'u1', 'first_name': 'u', 'last_name': '3', 'email': '3@example.org'})

    assert_equal(u1, u1)
    assert_not_equal(u1, u2)
    assert_equal(u1, u3)<|endoftext|>


<commit_before>from pytest import fixture

from cdm.context import Context
from cassandra.cluster import Cluster

@fixture(scope="module")
def context():
    cluster = Cluster()
    session = cluster.connect()
    # create the keyspace
    ks = 'test_cdm'
    if 'test_cdm' not in cluster.metadata.keyspaces:
        q = "create KEYSPACE {} WITH replication = {{'class': 'SimpleStrategy', 'replication_factor': 1}}".format(ks)
        session.execute(q)
    session.set_keyspace(ks)

    return Context(session=session)

<commit_msg>preparing session<commit_after>from pytest import fixture

from cdm.context import Context
from cassandra.cluster import Cluster

session = None

@fixture
def context():
    global session
    if not session:
        cluster = Cluster()
        session = cluster.connect()

        # create the keyspace
        ks = 'test_cdm'
        if 'test_cdm' not in cluster.metadata.keyspaces:
            q = "create KEYSPACE {} WITH \
                    replication = {{'class': \
                    'SimpleStrategy', \
                    'replication_factor': 1}}".format(ks)
        session.execute(q)

        session.set_keyspace(ks)

    return Context(session=session)

<|endoftext|>