text:
"""
EvMenu

This implements a full menu system for Evennia. It is considerably
more flexible than the older contrib/menusystem.py and also uses
menu plugin modules.

To start the menu, just import the EvMenu class from this module,

```python

    from evennia.utils.evmenu import EvMenu

    EvMenu(caller, menu_module_path,
         startnode="node1",
         cmdset_mergetype="Replace", cmdset_priority=1,
         allow_quit=True, cmd_on_quit="look")
```

Where `caller` is the Object to use the menu on - it will get a new
cmdset while using the Menu. The menu_module_path is the python path
to a python module containing function defintions.  By adjusting the
keyword options of the Menu() initialization call you can start the
menu at different places in the menu definition file, adjust if the
menu command should overload the normal commands or not, etc.

The menu is defined in a module (this can be the same module as the
command definition too) with function defintions:

```python

    def node1(caller):
        # (this is the start node if called like above)
        # code
        return text, options

    def node_with_other_namen(caller, input_string):
        # code
        return text, options
```

Where caller is the object using the menu and input_string is the
command entered by the user on the *previous* node (the command
entered to get to this node). The node function code will only be
executed once per node-visit and the system will accept nodes with
both one or two arguments interchangeably.

The menu tree itself is available on the caller as
`caller.ndb._menutree`. This makes it a convenient place to store
temporary state variables between nodes, since this NAttribute is
deleted when the menu is exited.

The return values must be given in the above order, but each can be
returned as None as well. If the options are returned as None, the
menu is immediately exited and the default "look" command is called.

    text (str, tuple or None): Text shown at this node. If a tuple, the
        second element in the tuple is a help text to display at this
        node when the user enters the menu help command there.
    options (tuple, dict or None): (
        {'key': name,   # can also be a list of aliases. A special key is
                        # "_default", which marks this option as the default
                        # fallback when no other option matches the user input.
         'desc': description, # optional description
         'goto': nodekey,  # node to go to when chosen
         'exec': nodekey}, # node or callback to trigger as callback when chosen.
                           # If a node key is given, the node will be executed once
                           # but its return values are ignored. If a callable is
                           # given, it must accept one or two args, like any node.
        {...}, ...)

If key is not given, the option will automatically be identified by
its number 1..N.

Example:

```python

    # in menu_module.py

    def node1(caller):
        text = ("This is a node text",
                "This is help text for this node")
        options = ({"key": "testing",
                    "desc": "Select this to go to node 2",
                    "goto": "node2",
                    "exec": "callback1"},
                   {"desc": "Go to node 3.",
                    "goto": "node3"})
        return text, options

    def callback1(caller):
        # this is called when choosing the "testing" option in node1
        # (before going to node2). It needs not have return values.
        caller.msg("Callback called!")

    def node2(caller):
        text = '''
            This is node 2. It only allows you to go back
            to the original node1. This extra indent will
            be stripped. We don't include a help text.
            '''
        options = {"goto": "node1"}
        return text, options

    def node3(caller):
        text = "This ends the menu since there are no options."
        return text, None

```

When starting this menu with  `Menu(caller, "path.to.menu_module")`,
the first node will look something like this:

    This is a node text
    ______________________________________

    testing: Select this to go to node 2
    2: Go to node 3

Where you can both enter "testing" and "1" to select the first option.
If the client supports MXP, they may also mouse-click on "testing" to
do the same. When making this selection, a function "callback1" in the
same Using `help` will show the help text, otherwise a list of
available commands while in menu mode.

The menu tree is exited either by using the in-menu quit command or by
reaching a node without any options.

For a menu demo, import CmdTestMenu from this module and add it to
your default cmdset. Run it with this module, like `testmenu
evennia.utils.evmenu`.

"""
from __future__ import print_function
from builtins import object, range

from textwrap import dedent
from inspect import isfunction, getargspec
from django.conf import settings
from evennia import Command, CmdSet
from evennia.utils.evtable import EvTable
from evennia.utils.ansi import ANSIString, strip_ansi
from evennia.utils.utils import mod_import, make_iter, pad, m_len
from evennia.commands import cmdhandler

# read from protocol NAWS later?
_MAX_TEXT_WIDTH = settings.CLIENT_DEFAULT_WIDTH

# we use cmdhandler instead of evennia.syscmdkeys to
# avoid some cases of loading before evennia init'd
_CMD_NOMATCH = cmdhandler.CMD_NOMATCH
_CMD_NOINPUT = cmdhandler.CMD_NOINPUT

# Return messages

# i18n
from django.utils.translation import ugettext as _
_ERR_NOT_IMPLEMENTED = _("Menu node '{nodename}' is not implemented. Make another choice.")
_ERR_GENERAL = _("Error in menu node '{nodename}'.")
_ERR_NO_OPTION_DESC = _("No description.")
_HELP_FULL = _("Commands: <menu option>, help, quit")
_HELP_NO_QUIT = _("Commands: <menu option>, help")
_HELP_NO_OPTIONS = _("Commands: help, quit")
_HELP_NO_OPTIONS_NO_QUIT = _("Commands: help")
_HELP_NO_OPTION_MATCH = _("Choose an option or try 'help'.")

class EvMenuError(RuntimeError):
    """
    Error raised by menu when facing internal errors.

    """
    pass

#------------------------------------------------------------
#
# Menu command and command set
#
#------------------------------------------------------------

class CmdEvMenuNode(Command):
    """
    Menu options.
    """
    key = _CMD_NOINPUT
    aliases = [_CMD_NOMATCH]
    locks = "cmd:all()"
    help_category = "Menu"

    def func(self):
        """
        Implement all menu commands.
        """
        caller = self.caller
        menu = caller.ndb._menutree or self.session.ndb._menutree

        if not menu:
            err = "Menu object not found as %s.ndb._menutree!" % (caller)
            caller.msg(err)
            raise EvMenuError(err)

        menu.parse_input(self.raw_string)

class EvMenuCmdSet(CmdSet):
    """
    The Menu cmdset replaces the current cmdset.

    """
    key = "menu_cmdset"
    priority = 1
    mergetype = "Replace"
    no_objs = True
    no_exits = True
    no_channels = False

    def at_cmdset_creation(self):
        """
        Called when creating the set.
        """
        self.add(CmdEvMenuNode())

def dedent_strip_nodetext_formatter(nodetext, has_options):
    return dedent(nodetext).strip()

def dedent_nodetext_formatter(nodetext, has_options):
    return dedent(nodetext)

def evtable_options_formatter(optionlist):
    if not optionlist:
        return ""

    # column separation distance
    colsep = 4

    nlist = len(optionlist)

    # get the widest option line in the table.
    table_width_max = -1
    table = []
    for key, desc in optionlist:
        if not (key or desc):
            continue
        table_width_max = max(table_width_max,
                              max(m_len(p) for p in key.split("\n")) +
                              max(m_len(p) for p in desc.split("\n")) + colsep)
        raw_key = strip_ansi(key)
        if raw_key != key:
            # already decorations in key definition
            table.append(ANSIString(" {lc%s{lt%s{le: %s" % (raw_key, key, desc)))
        else:
            # add a default white color to key
            table.append(ANSIString(" {lc%s{lt{w%s{n{le: %s" % (raw_key, raw_key, desc)))

    ncols = (_MAX_TEXT_WIDTH // table_width_max) + 1 # number of ncols
    nlastcol = nlist % ncols # number of elements left in last row

    # get the amount of rows needed (start with 4 rows)
    nrows = 4
    while nrows * ncols < nlist:
        nrows += 1
    ncols = nlist // nrows # number of full columns
    nlastcol = nlist % nrows # number of elements in last column

    # get the final column count
    ncols = ncols + 1 if nlastcol > 0 else ncols
    if ncols > 1:
        # only extend if longer than one column
        table.extend([" " for i in range(nrows - nlastcol)])

    # build the actual table grid
    table = [table[icol * nrows : (icol * nrows) + nrows] for icol in range(0, ncols)]

    # adjust the width of each column
    for icol in range(len(table)):
        col_width = max(max(m_len(p) for p in part.split("\n")) for part in table[icol]) + colsep
        table[icol] = [pad(part, width=col_width + colsep, align="l") for part in table[icol]]

    # format the table into columns
    return unicode(EvTable(table=table, border="none"))

def underline_node_formatter(nodetext, optionstext):
    nodetext_width_max = max(m_len(line) for line in nodetext.split("\n"))
    options_width_max = max(m_len(line) for line in optionstext.split("\n"))
    total_width = max(options_width_max, nodetext_width_max)
    separator1 = "_" * total_width + "\n\n" if nodetext_width_max else ""
    separator2 = "\n" + "_" * total_width + "\n\n" if total_width else ""
    return separator1 + nodetext + separator2 + optionstext

def null_node_formatter(nodetext, optionstext):
    return nodetext + "\n\n" + optionstext

#------------------------------------------------------------
#
# Menu main class
#
#------------------------------------------------------------

class EvMenu(object):
    """
    This object represents an operational menu. It is initialized from
    a menufile.py instruction.

    """
    def __init__(self, caller, menudata, startnode="start",
                 cmdset_mergetype="Replace", cmdset_priority=1,
                 allow_quit=True, cmd_on_quit="look",
                 nodetext_formatter=None, options_formatter=None,
                 node_formatter=None):
        """
        Initialize the menu tree and start the caller onto the first node.

        Args:
            caller (Object, Player or Session): The user of the menu.
            menudata (str, module or dict): The full or relative path to the module
                holding the menu tree data. All global functions in this module
                whose name doesn't start with '_ ' will be parsed as menu nodes.
                Also the module itself is accepted as input. Finally, a dictionary
                menu tree can be given directly. This must then be a mapping
                `{"nodekey":callable,...}` where `callable` must be called as
                and return the data expected of a menu node. This allows for
                dynamic menu creation.
            startnode (str, optional): The starting node name in the menufile.
            cmdset_mergetype (str, optional): 'Replace' (default) means the menu
                commands will be exclusive - no other normal commands will
                be usable while the user is in the menu. 'Union' means the
                menu commands will be integrated with the existing commands
                (it will merge with `merge_priority`), if so, make sure that
                the menu's command names don't collide with existing commands
                in an unexpected way. Also the CMD_NOMATCH and CMD_NOINPUT will
                be overloaded by the menu cmdset. Other cmdser mergetypes
                has little purpose for the menu.
            cmdset_priority (int, optional): The merge priority for the
                menu command set. The default (1) is usually enough for most
                types of menus.
            allow_quit (bool, optional): Allow user to use quit or
                exit to leave the menu at any point. Recommended during
                development!
            cmd_on_quit (callable, str or None, optional): When exiting the menu
                (either by reaching a node with no options or by using the
                in-built quit command (activated with `allow_quit`), this
                callback function or command string will be executed.
                The callback function takes two parameters, the caller then the
                EvMenu object. This is called after cleanup is complete.
                Set to None to not call any command.
            nodetext_formatter (callable, optional): This callable should be on
                the form `function(nodetext, has_options)`, where `nodetext` is the
                node text string and `has_options` a boolean specifying if there
                are options associated with this node. It must return a formatted
                string.
            options_formatter (callable, optional): This callable should be on
                the form `function(optionlist)`, where ` optionlist is a list
                of option dictionaries, like
                [{"key":..., "desc",..., "goto": ..., "exec",...}, ...]
                Each dictionary describes each possible option. Note that this
                will also be called if there are no options, and so should be
                able to handle an empty list. This should
                be formatted into an options list and returned as a string,
                including the required separator to use between the node text
                and the options. If not given the default EvMenu style will be used.
            node_formatter (callable, optional): This callable should be on the
                form `func(nodetext, optionstext)` where the arguments are strings
                representing the node text and options respectively (possibly prepared
                by `nodetext_formatter`/`options_formatter` or by the default styles).
                It should return a string representing the final look of the node. This
                can e.g. be used to create line separators that take into account the
                dynamic width of the parts.

        Raises:
            EvMenuError: If the start/end node is not found in menu tree.

        """
        self._caller = caller
        self._startnode = startnode
        self._menutree = self._parse_menudata(menudata)

        if nodetext_formatter is not None:
            self._nodetext_formatter = nodetext_formatter
        else:
            self._nodetext_formatter = dedent_strip_nodetext_formatter

        if options_formatter is not None:
            self._options_formatter = options_formatter
        else:
            self._options_formatter = evtable_options_formatter

        if node_formatter is not None:
            self._node_formatter = node_formatter
        else:
            self._node_formatter = underline_node_formatter

        if startnode not in self._menutree:
            raise EvMenuError("Start node '%s' not in menu tree!" % startnode)

        # variables made available to the command
        self.allow_quit = allow_quit
        if isinstance(cmd_on_quit, str):
            self.cmd_on_quit = lambda caller, menu: caller.execute_cmd(cmd_on_quit)
        elif callable(cmd_on_quit):
            self.cmd_on_quit = cmd_on_quit
        else:
            self.cmd_on_quit = None
        self.default = None
        self.nodetext = None
        self.helptext = None
        self.options = None

        # store ourself on the object
        self._caller.ndb._menutree = self

        # set up the menu command on the caller
        menu_cmdset = EvMenuCmdSet()
        menu_cmdset.mergetype = str(cmdset_mergetype).lower().capitalize() or "Replace"
        menu_cmdset.priority = int(cmdset_priority)
        self._caller.cmdset.add(menu_cmdset)
        # start the menu
        self.goto(self._startnode, "")

    def _parse_menudata(self, menudata):
        """
        Parse a menufile for node functions and store in dictionary
        map. Alternatively, accept a pre-made mapping dictionary of
        node functions.

        Args:
            menudata (str, module or dict): The python.path to the menufile,
                or the python module itself. If a dict, this should be a
                mapping nodename:callable, where the callable must match
                the criteria for a menu node.

        Returns:
            menutree (dict): A {nodekey: func}

        """
        if isinstance(menudata, dict):
            # This is assumed to be a pre-loaded menu tree.
            return menudata
        else:
            # a python path of a module
            module = mod_import(menudata)
            return dict((key, func) for key, func in module.__dict__.items()
                        if isfunction(func) and not key.startswith("_"))

    def _format_node(self, nodetext, optionlist):
        """
        Format the node text + option section

        Args:
            nodetext (str): The node text
            optionlist (list): List of (key, desc) pairs.

        Returns:
            string (str): The options section, including
                all needed spaces.

        Notes:
            This will adjust the columns of the options, first to use
            a maxiumum of 4 rows (expanding in columns), then gradually
            growing to make use of the screen space.

        """

        # handle the node text
        nodetext = self._nodetext_formatter(nodetext, len(optionlist))

        # handle the options
        optionstext = self._options_formatter(optionlist)

        # format the entire node
        return self._node_formatter(nodetext, optionstext)

    def _execute_node(self, nodename, raw_string):
        """
        Execute a node.

        Args:
            nodename (str): Name of node.
            raw_string (str): The raw default string entered on the
                previous node (only used if the node accepts it as an
                argument)

        Returns:
            nodetext, options (tuple): The node text (a string or a
                tuple and the options tuple, if any.

        """
        try:
            node = self._menutree[nodename]
        except KeyError:
            self._caller.msg(_ERR_NOT_IMPLEMENTED.format(nodename=nodename))
            raise EvMenuError
        try:
            # the node should return data as (text, options)
            if len(getargspec(node).args) > 1:
                # a node accepting raw_string
                nodetext, options = node(self._caller, raw_string)
            else:
                # a normal node, only accepting caller
                nodetext, options = node(self._caller)
        except KeyError:
            self._caller.msg(_ERR_NOT_IMPLEMENTED.format(nodename=nodename))
            raise EvMenuError
        except Exception:
            self._caller.msg(_ERR_GENERAL.format(nodename=nodename))
            raise
        return nodetext, options

    def _display_nodetext(self):
        self._caller.msg(self.nodetext)

    def _display_helptext(self):
        self._caller.msg(self.helptext)

    def _callback_goto(self, callback, goto, raw_string):
        if callback:
            self.callback(callback, raw_string)
        if goto:
            self.goto(goto, raw_string)

    def parse_input(self, raw_string):
        """
        Processes the user' node inputs.

        Args:
            raw_string (str): The incoming raw_string from the menu
                command.
        """

        caller = self._caller
        cmd = raw_string.strip().lower()
        allow_quit = self.allow_quit

        if cmd in self.options:
            # this will take precedence over the default commands
            # below
            goto, callback = self.options[cmd]
            self._callback_goto(callback, goto, raw_string)
        elif cmd in ("look", "l"):
            self._display_nodetext()
        elif cmd in ("help", "h"):
            self._display_helptext()
        elif allow_quit and cmd in ("quit", "q", "exit"):
            self.close_menu()
        elif self.default:
            goto, callback = self.default
            self._callback_goto(callback, goto, raw_string)
        else:
            caller.msg(_HELP_NO_OPTION_MATCH)

        if not (self.options or self.default):
            # no options - we are at the end of the menu.
            self.close_menu()

    def callback(self, nodename, raw_string):
        """
        Run a node as a callback. This makes no use of the return
        values from the node.

        Args:
            nodename (str): Name of node.
            raw_string (str): The raw default string entered on the
                previous node (only used if the node accepts it as an
                argument)

        """
        if callable(nodename):
            # this is a direct callable - execute it directly
            try:
                if len(getargspec(nodename).args) > 1:
                    # callable accepting raw_string
                    nodename(self._caller, raw_string)
                else:
                    # normal callable, only the caller as arg
                    nodename(self._caller)
            except Exception:
                self._caller.msg(_ERR_GENERAL.format(nodename=nodename))
                raise
        else:
            # nodename is a string; lookup as node
            try:
                # execute the node; we make no use of the return values here.
                self._execute_node(nodename, raw_string)
            except EvMenuError:
                return

    def goto(self, nodename, raw_string):
        """
        Run a node by name

        Args:
            nodename (str): Name of node.
            raw_string (str): The raw default string entered on the
                previous node (only used if the node accepts it as an
                argument)

        """
        try:
            # execute the node, make use of the returns.
            nodetext, options = self._execute_node(nodename, raw_string)
        except EvMenuError:
            return

        # validation of the node return values
        helptext = ""
        if hasattr(nodetext, "__iter__"):
            if len(nodetext) > 1:
                nodetext, helptext = nodetext[:2]
            else:
                nodetext = nodetext[0]
        nodetext = str(nodetext) or ""
        options = [options] if isinstance(options, dict) else options

        # this will be displayed in the given order
        display_options = []
        # this is used for lookup
        self.options = {}
        self.default = None
        if options:
            for inum, dic in enumerate(options):
                # fix up the option dicts
                keys = make_iter(dic.get("key"))
                if "_default" in keys:
                    keys = [key for key in keys if key != "_default"]
                    desc = dic.get("desc", dic.get("text", _ERR_NO_OPTION_DESC).strip())
                    goto, execute = dic.get("goto", None), dic.get("exec", None)
                    self.default = (goto, execute)
                else:
                    keys = list(make_iter(dic.get("key", str(inum+1).strip()))) + [str(inum+1)]
                    desc = dic.get("desc", dic.get("text", _ERR_NO_OPTION_DESC).strip())
                    goto, execute = dic.get("goto", None), dic.get("exec", None)

                if keys:
                    display_options.append((keys[0], desc))
                    for key in keys:
                        if goto or execute:
                            self.options[strip_ansi(key).strip().lower()] = (goto, execute)

        self.nodetext = self._format_node(nodetext, display_options)

        # handle the helptext
        if helptext:
            self.helptext = helptext
        elif options:
            self.helptext = _HELP_FULL if self.allow_quit else _HELP_NO_QUIT
        else:
            self.helptext = _HELP_NO_OPTIONS if self.allow_quit else _HELP_NO_OPTIONS_NO_QUIT

        self._display_nodetext()

    def close_menu(self):
        """
        Shutdown menu; occurs when reaching the end node.
        """
        self._caller.cmdset.remove(EvMenuCmdSet)
        del self._caller.ndb._menutree
        if self.cmd_on_quit is not None:
            self.cmd_on_quit(self._caller, self)

# -------------------------------------------------------------------------------------------------
#
# Simple input shortcuts
#
# -------------------------------------------------------------------------------------------------

class CmdGetInput(Command):
    """
    Enter your data and press return.
    """
    key = _CMD_NOMATCH
    aliases = _CMD_NOINPUT

    def func(self):
        "This is called when user enters anything."
        caller = self.caller
        callback = caller.ndb._getinputcallback
        prompt = caller.ndb._getinputprompt
        result = self.raw_string

        ok = not callback(caller, prompt, result)
        if ok:
            # only clear the state if the callback does not return
            # anything
            del caller.ndb._getinputcallback
            del caller.ndb._getinputprompt
            caller.cmdset.remove(InputCmdSet)

class InputCmdSet(CmdSet):
    """
    This stores the input command
    """
    key = "input_cmdset"
    priority = 1
    mergetype = "Replace"
    no_objs = True
    no_exits = True
    no_channels = False

    def at_cmdset_creation(self):
        "called once at creation"
        self.add(CmdGetInput())

def get_input(caller, prompt, callback):
    """
    This is a helper function for easily request input from
    the caller.

    Args:
        caller (Player or Object): The entity being asked
            the question. This should usually be an object
            controlled by a user.
        prompt (str): This text will be shown to the user,
            in order to let them know their input is needed.
        callback (callable): A function that will be called
            when the user enters a reply. It must take three
            arguments: the `caller`, the `prompt` text and the
            `result` of the input given by the user. If the
            callback doesn't return anything or return False,
            the input prompt will be cleaned up and exited. If
            returning True, the prompt will remain and continue to
            accept input.

    Raises:
        RuntimeError: If the given callback is not callable.

    """
    if not callable(callback):
        raise RuntimeError("get_input: input callback is not callable.")
    caller.ndb._getinputcallback = callback
    caller.ndb._getinputprompt = prompt
    caller.cmdset.add(InputCmdSet)
    caller.msg(prompt)

#------------------------------------------------------------
#
# test menu strucure and testing command
#
#------------------------------------------------------------

def test_start_node(caller):
    text = """
    This is an example menu.

    If you enter anything except the valid options, your input will be
    recorded and you will be brought to a menu entry showing your
    input.

    Select options or use 'quit' to exit the menu.
    """
    options = ({"key": ("{yS{net", "s"),
                "desc": "Set an attribute on yourself.",
                "exec": lambda caller: caller.attributes.add("menuattrtest", "Test value"),
                "goto": "test_set_node"},
               {"key": ("{yL{nook", "l"),
                "desc": "Look and see a custom message.",
                "goto": "test_look_node"},
               {"key": ("{yV{niew", "v"),
                "desc": "View your own name",
                "goto": "test_view_node"},
               {"key": ("{yQ{nuit", "quit", "q", "Q"),
                "desc": "Quit this menu example.",
                "goto": "test_end_node"},
               {"key": "_default",
                "goto": "test_displayinput_node"})
    return text, options

def test_look_node(caller):
    text = ""
    options = {"key": ("{yL{nook", "l"),
               "desc": "Go back to the previous menu.",
               "goto": "test_start_node"}
    return text, options

def test_set_node(caller):
    text = ("""
    The attribute 'menuattrtest' was set to

            {w%s{n

    (check it with examine after quitting the menu).

    This node's has only one option, and one of its key aliases is the
    string "_default", meaning it will catch any input, in this case
    to return to the main menu.  So you can e.g. press <return> to go
    back now.
    """ % caller.db.menuattrtest,
    # optional help text for this node
    """
    This is the help entry for this node. It is created by returning
    the node text as a tuple - the second string in that tuple will be
    used as the help text.
    """)

    options = {"key": ("back (default)", "_default"),
               "desc": "back to main",
               "goto": "test_start_node"}
    return text, options

def test_view_node(caller):
    text = """
    Your name is {g%s{n!

    click {lclook{lthere{le to trigger a look command under MXP.
    This node's option has no explicit key (nor the "_default" key
    set), and so gets assigned a number automatically. You can infact
    -always- use numbers (1...N) to refer to listed options also if you
    don't see a string option key (try it!).
    """ % caller.key
    options = {"desc": "back to main",
               "goto": "test_start_node"}
    return text, options

def  test_displayinput_node(caller, raw_string):
    text = """
    You entered the text:

        "{w%s{n"

    ... which could now be handled or stored here in some way if this
    was not just an example.

    This node has an option with a single alias "_default", which
    makes it hidden from view. It catches all input (except the
    in-menu help/quit commands) and will, in this case, bring you back
    to the start node.
    """ % raw_string
    options = {"key": "_default",
              "goto": "test_start_node"}
    return text, options

def test_end_node(caller):
    text = """
    This is the end of the menu and since it has no options the menu
    will exit here, followed by a call of the "look" command.
    """
    return text, None

class CmdTestMenu(Command):
    """
    Test menu

    Usage:
      testmenu <menumodule>

    Starts a demo menu from a menu node definition module.

    """
    key = "testmenu"

    def func(self):

        if not self.args:
            self.caller.msg("Usage: testmenu menumodule")
            return
        # start menu
        EvMenu(self.caller, self.args.strip(), startnode="test_start_node", cmdset_mergetype="Replace")


text:
// Copyright 2012 Google Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//       http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package com.google.api.ads.adwords.axis.utility.extension.delegates;

import com.google.api.ads.adwords.axis.utility.extension.util.SelectorFields;
import com.google.api.ads.adwords.axis.v201409.cm.CampaignAdExtension;
import com.google.api.ads.adwords.axis.v201409.cm.CampaignAdExtensionOperation;
import com.google.api.ads.adwords.axis.v201409.cm.CampaignAdExtensionServiceInterface;
import com.google.api.ads.adwords.lib.client.AdWordsSession;
import com.google.common.annotations.VisibleForTesting;

import java.rmi.RemoteException;
import java.util.List;

/**
 * Specific AbstractGetMutateDelegate for {@link CampaignAdExtension}.
 *
 * @author Julian Toledo
 */
public final class CampaignAdExtensionDelegate extends AbstractGetMutateDelegate<
    CampaignAdExtension, CampaignAdExtensionOperation, CampaignAdExtensionServiceInterface> {

  /**
   * Default Constructor.
   *
   * @param adWordsSession the {@code adWordsSession} to use with the delegate/service
   */
  public CampaignAdExtensionDelegate(AdWordsSession adWordsSession, boolean includeBetaFields) {
    super(adWordsSession, SelectorFields.CampaignAdExtension.all(includeBetaFields),
        CampaignAdExtension.class, CampaignAdExtensionOperation.class,
        CampaignAdExtensionServiceInterface.class);
  }

  /**
   * Constructor with custom service.
   *
   * @param adWordsSession the {@code adWordsSession} to use with the delegate/service
   * @param service the service class for CampaignAdExtensionServiceInterface
   * @param includeBetaFields
   */
  @VisibleForTesting
  CampaignAdExtensionDelegate(AdWordsSession adWordsSession,
      CampaignAdExtensionServiceInterface service, boolean includeBetaFields) {
    super(adWordsSession, SelectorFields.CampaignAdExtension.all(includeBetaFields),
        CampaignAdExtension.class, CampaignAdExtensionOperation.class, service);
  }

  /**
   * Constructor with custom fields.
   *
   * @param adWordsSession the {@code adWordsSession} to use with the delegate/service
   * @param selectorFields for the Generic Selectors using the SelectorField class
   */
  public CampaignAdExtensionDelegate(AdWordsSession adWordsSession,
      List<SelectorFields.CampaignAdExtension> selectorFields) {
    super(adWordsSession, selectorFields, CampaignAdExtension.class,
        CampaignAdExtensionOperation.class, CampaignAdExtensionServiceInterface.class);
  }

  /**
   * Retrieves CampaignAdExtensions by adExtensionId.
   *
   * @param adExtensionId
   * @return a list of CampaignAdExtensions matching the adExtensionId
   * @throws RemoteException for communication-related exceptions
   */
  public CampaignAdExtension getByAdExtensionId(Long adExtensionId) throws RemoteException {
    return getOneByField(SelectorFields.CampaignAdExtension.AD_EXTENSION_ID, adExtensionId);
  }

  /**
   * Retrieves CampaignAdExtensions by campaignIds.
   *
   * @param campaignIds
   * @return a list of CampaignAdExtensions matching the campaignIds
   * @throws RemoteException for communication-related exceptions
   */
  public List<CampaignAdExtension> getByCampaignId(List<Long> campaignIds) throws RemoteException {
    return getByField(SelectorFields.CampaignAdExtension.CAMPAIGN_ID, campaignIds);
  }

  /**
   * Retrieves CampaignAdExtensions by campaignId.
   *
   * @param campaignId
   * @return a list of CampaignAdExtensions matching the campaignId
   * @throws RemoteException for communication-related exceptions
   */
  public List<CampaignAdExtension> getByCampaignId(Long campaignId) throws RemoteException {
    return getByField(SelectorFields.CampaignAdExtension.CAMPAIGN_ID, campaignId);
  }

  /**
   * Retrieves CampaignAdExtensions by campaignId in the range (startIndex, numberResults).
   *
   * @param campaignId
   * @param startIndex index of the first result
   * @param numberResults number of results
   * @return a list of CampaignAdExtensions matching the campaignId in the range
   *         (startIndex, numberResults)
   * @throws RemoteException for communication-related exceptions
   */
  public List<CampaignAdExtension> getByCampaignId(Long campaignId, int startIndex,
      int numberResults) throws RemoteException {
    return getByField(SelectorFields.CampaignAdExtension.CAMPAIGN_ID, campaignId, startIndex,
        numberResults);
  }
}

redpajama_set_name: RedPajamaGithub


text:
package es.tid.cosmos.admin.profile

import org.scalatest.FlatSpec
import org.scalatest.matchers.MustMatchers

import es.tid.cosmos.api.profile.dao.mock.MockCosmosDataStoreComponent
import es.tid.cosmos.api.profile.CosmosProfileTestHelpers._
import es.tid.cosmos.api.quota.{UnlimitedQuota, Quota}

class ProfileQuotaCommandsTest extends FlatSpec with MustMatchers {

  trait WithQuotaCommands extends MockCosmosDataStoreComponent {
    val handle = "jsmith"
    val cosmosId = registerUser(handle)(store).id
    val quotaCommands = new ProfileQuotaCommands(store)

    def currentQuota() = store.withTransaction { implicit c =>
      store.profile.lookupByHandle(handle)
    }.get.quota
  }

  "A quota profile command" must "unset quota" in new WithQuotaCommands {
    store.withTransaction { implicit c =>
      store.profile.setMachineQuota(cosmosId, Quota(10))
    }
    quotaCommands.remove(handle) must be ('success)
    currentQuota() must be (UnlimitedQuota)
  }

  it must "set a valid quota" in new WithQuotaCommands {
    quotaCommands.set(handle, 15) must be ('success)
    currentQuota() must be (Quota(15))
  }
}


text:
package mah.event;

import lombok.val;
import org.jetbrains.annotations.NotNull;

/**
 * Created by zgq on 2/13/17.
 */
public abstract class AbstractEventHandler<T> implements ComparableEventHandler<T> {
    private final int priority;

    public AbstractEventHandler(int priority) {
        this.priority = priority;
    }

    @Override
    public int compareTo(@NotNull ComparableEventHandler o) {
        int handlerPriority = o.getPriority();
        if (this.priority == handlerPriority) {
            return 0;
        }
        return (this.priority < handlerPriority) ? 1 : -1;
    }

    @Override
    public int getPriority() {
        return priority;
    }
}


text:
require('./setup');
require('./editor');

const initial_program = `
package main

import (
    "fmt"
)

func main() {
    fmt.Println("Hello, playground")
}
`.trim();

function resizeInput() {
    $(this).attr('size', $(this).val().length);
}

let share_url = $('#share-url');
share_url.keyup(resizeInput)
    // resize on page load
    .each(resizeInput);
$('#share').click(() => {
    share_url.addClass('active');
    share_url.focus();
});

import React from 'react';
import { render } from 'react-dom';
import { createStore, applyMiddleware, compose } from 'redux';
import thunk from 'redux-thunk';
import { Provider } from 'react-redux';
import reducer from './reducer';
import Playground from './components/playground';

const stateStore = createStore(reducer, {
    live: false,
    code: initial_program,
    forceEditorRender: false,
    output: '',
    system: '',
    sharing: false
}, compose(
    applyMiddleware(thunk),
    window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__()
));

render(
    <Provider store={stateStore}>
        <Playground />
    </Provider>,
    document.getElementById('root')
);


text:
// Copyright 1998-2015 Epic Games, Inc. All Rights Reserved.
#include "CoreUObjectPrivate.h"

/** Constructor */
FReloadObjectArc::FReloadObjectArc()
: FArchiveUObject(), Reader(Bytes), Writer(Bytes), RootObject(NULL), InstanceGraph(NULL)
, bAllowTransientObjects(true), bInstanceSubobjectsOnLoad(true)
{
}

/** Destructor */
FReloadObjectArc::~FReloadObjectArc()
{
	if ( InstanceGraph != NULL )
	{
		delete InstanceGraph;
		InstanceGraph = NULL;
	}
}

/**
 * Sets the root object for this memory archive.
 *
 * @param	NewRoot		the UObject that should be the new root
 */
void FReloadObjectArc::SetRootObject( UObject* NewRoot )
{
	if ( NewRoot != NULL && InstanceGraph == NULL )
	{
		// if we are setting the top-level root object and we don't yet have an instance graph, create one
		InstanceGraph = new FObjectInstancingGraph(NewRoot);
		if ( IsLoading() )
		{
			// if we're reloading data onto objects, pre-initialize the instance graph with the objects instances that were serialized
			for ( int32 ObjectIndex = 0; ObjectIndex < CompleteObjects.Num(); ObjectIndex++ )
			{
				UObject* InnerObject = CompleteObjects[ObjectIndex];

				// ignore previously saved objects that aren't contained within the current root object
				if ( InnerObject->IsIn(NewRoot) )
				{
					InstanceGraph->AddNewInstance(InnerObject);
				}
			}
		}
	}

	RootObject = NewRoot;
	if ( RootObject == NULL && InstanceGraph != NULL )
	{
		// if we have cleared the top-level root object and we have an instance graph, delete it
		delete InstanceGraph;
		InstanceGraph = NULL;
	}
}

/**
 * Begin serializing a UObject into the memory archive.  Note that this archive does not use
 * object marks (OBJECTMARK_TagExp|OBJECTMARK_TagImp) to prevent recursion, as do most other archives that perform
 * similar functionality.  This is because this archive is used in operations that modify those
 * object flags for other purposes.
 *
 * @param	Obj		the object to serialize
 */
void FReloadObjectArc::SerializeObject( UObject* Obj )
{
	if ( Obj != NULL )
	{
		TSet<UObject*>& ObjectList = IsLoading()
			? LoadedObjects
			: SavedObjects;

		// only process this top-level object once
		if ( !ObjectList.Contains(Obj) )
		{
			ObjectList.Add(Obj);

			// store the current value of RootObject, in case our caller set it before calling SerializeObject
			UObject* PreviousRoot = RootObject;

			// set the root object to this object so that we load complete object data
			// for any objects contained within the top-level object (such as components)
			SetRootObject(Obj);

			// set this to prevent recursion in serialization
			if ( IsLoading() )
			{
				if (InstanceGraph != NULL)
				{
					// InitProperties will call CopyCompleteValue for any instanced object properties, so disable object instancing
					// because we probably already have an object that will be copied over that value; for any instanced object properties which
					// did not have a value when we were saving object data, we'll call InstanceSubobjects to instance those.  Also disable component
					// instancing as this object may not have the correct values for its component properties until its serialized, which result in
					// possibly creating lots of unnecessary components that will be thrown away anyway
					InstanceGraph->EnableSubobjectInstancing(false);
				}
				if ( Obj->GetClass() != UPackage::StaticClass() )
				{
					Obj->ReinitializeProperties(NULL, InstanceGraph);
				}
			}

			if ( Obj->HasAnyFlags(RF_ClassDefaultObject) )
			{
				Obj->GetClass()->SerializeDefaultObject(Obj, *this);
			}
			else
			{
				// save / load the data for this object that is different from its class
				Obj->Serialize(*this);
			}

			if ( IsLoading() )
			{
				if ( InstanceGraph != NULL )
				{
					InstanceGraph->EnableSubobjectInstancing(true);

					if ( bInstanceSubobjectsOnLoad )
					{
						// components which were identical to their archetypes weren't stored into this archive's object data, so re-instance those components now
						Obj->InstanceSubobjectTemplates(InstanceGraph);
					}
				}

				if ( !Obj->HasAnyFlags(RF_ClassDefaultObject) )
				{
					// allow the object to perform any cleanup after re-initialization
					Obj->PostLoad();
				}
			}

			// restore the RootObject - we're done with it.
			SetRootObject(PreviousRoot);
		}
	}
}

/**
 * Resets the archive so that it can be loaded from again from scratch
 * as if it was never serialized as a Reader
 */
void FReloadObjectArc::Reset()
{
	// empty the list of objects that were loaded, so we can load again
	LoadedObjects.Empty();
	// reset our location in the buffer
	Seek(0);
}

/**
 * I/O function for FName
 */
FArchive& FReloadObjectArc::operator<<( class FName& Name )
{
	NAME_INDEX NameComparisonIndex;
	NAME_INDEX NameDisplayIndex;
	int32 NameInstance;
	if ( IsLoading() )
	{
		Reader << NameComparisonIndex << NameDisplayIndex << NameInstance;

		// recreate the FName using the serialized index and instance number
		Name = FName(NameComparisonIndex, NameDisplayIndex, NameInstance);
	}
	else if ( IsSaving() )
	{
		NameComparisonIndex = Name.GetComparisonIndex();
		NameDisplayIndex = Name.GetDisplayIndex();
		NameInstance = Name.GetNumber();

		Writer << NameComparisonIndex << NameDisplayIndex << NameInstance;
	}
	return *this;
}

/**
 * I/O function for UObject references
 */
FArchive& FReloadObjectArc::operator<<( class UObject*& Obj )
{
	if ( IsLoading() )
	{
		int32 Index = 0;
		Reader << Index;

		// An index of 0 indicates that the value of the object was NULL
		if ( Index == 0 )
		{
			Obj = NULL;
		}
		else if ( Index < 0 )
		{
			// An index less than zero indicates an object for which we only stored the object pointer
			Obj = ReferencedObjects[-Index-1];
		}
		else if ( Index > 0 )
		{
			// otherwise, the memory archive contains the entire UObject data for this UObject, so load
			// it from the archive
			Obj = CompleteObjects[Index-1];

			// Ensure we don't load it more than once.
			if ( !LoadedObjects.Contains(Obj) )
			{
				LoadedObjects.Add(Obj);

				// find the location for this UObject's data in the memory archive
				int32* ObjectOffset = ObjectMap.Find(Obj);
				checkf(ObjectOffset,TEXT("%s wasn't not found in ObjectMap for %s - double-check that %s (and objects it references) saves the same amount of data it loads if using custom serialization"),
					*Obj->GetFullName(), *GetArchiveName(), *RootObject->GetFullName());

				// move the reader to that position
				Reader.Seek(*ObjectOffset);

				// make sure object instancing is disabled before calling ReinitializeProperties; otherwise new copies of objects will be
				// created for any instanced object properties owned by this object and then immediately overwritten when its serialized
				InstanceGraph->EnableSubobjectInstancing(false);

				// Call ReinitializeProperties to propagate base change to 'within' objects (like Components).
				Obj->ReinitializeProperties( NULL, InstanceGraph );

				// read in the data for this UObject
				Obj->Serialize(*this);

				// we should never have RootObject serialized as an object contained by the root object
				checkSlow(Obj != RootObject);

				// serializing the stored data for this object should have replaced all of its original instanced object references
				// but there might have been new subobjects added to the object's archetype in the meantime (in the case of updating
				// an prefab from a prefab instance, for example), so enable subobject instancing and instance those now.
				InstanceGraph->EnableSubobjectInstancing(true);

				if ( bInstanceSubobjectsOnLoad )
				{
					// components which were identical to their archetypes weren't stored into this archive's object data, so re-instance those components now
					Obj->InstanceSubobjectTemplates(InstanceGraph);
				}

				// normally we'd never have CDOs in the list of CompleteObjects (CDOs can't be contained within other objects)
				// but in some cases this operator is invoked directly (prefabs)
				if ( !Obj->HasAnyFlags(RF_ClassDefaultObject) )
				{
					Obj->PostLoad();
				}

			}
		}
	}
	else if ( IsSaving() )
	{
		// Don't save references to transient or deleted objects.
		if ( Obj == NULL || (Obj->HasAnyFlags(RF_Transient) && !bAllowTransientObjects) || Obj->IsPendingKill() )
		{
			// null objects are stored as 0 indexes
			int32 Index = 0;
			Writer << Index;
			return *this;
		}

		// See if we have already written this object out.
		int32 CompleteIndex = CompleteObjects.Find(Obj);
		int32 ReferencedIndex = ReferencedObjects.Find(Obj);

		// The same object can't be in both arrays.
		check( !(CompleteIndex != INDEX_NONE && ReferencedIndex != INDEX_NONE) );

		if(CompleteIndex != INDEX_NONE)
		{
			int32 Index = CompleteIndex + 1;
			Writer << Index;
		}
		else if(ReferencedIndex != INDEX_NONE)
		{
			int32 Index = -ReferencedIndex - 1;
			Writer << Index;
		}
		// New object - was not already saved.
		// if the object is in the SavedObjects array, it means that the object was serialized into this memory archive as a root object
		// in this case, just serialize the object as a simple reference
		else if ( Obj->IsIn(RootObject) && !SavedObjects.Contains(Obj) )
		{
			SavedObjects.Add(Obj);

			// we need to store the UObject data for this object
			check(ObjectMap.Find(Obj) == NULL);

			// only the location of the UObject in the CompleteObjects
			// array is stored in the memory archive, using FPackageIndex-style
			// notation
			int32 Index = CompleteObjects.AddUnique(Obj) + 1;
			Writer << Index;

			// remember the location of the beginning of this UObject's data
			ObjectMap.Add(Obj,Writer.Tell());

			Obj->Serialize(*this);
		}
		else
		{
			// Referenced objects will be indicated by negative indexes
			int32 Index = -ReferencedObjects.AddUnique(Obj) - 1;
			Writer << Index;
		}
	}
	return *this;
}

/*----------------------------------------------------------------------------
	FArchiveReplaceArchetype.
----------------------------------------------------------------------------*/
FArchiveReplaceArchetype::FArchiveReplaceArchetype()
: FReloadObjectArc()
{
	// don't wipe out transient objects
	bAllowTransientObjects = true;

	// setting this flag indicates that component references should only be serialized into this archive if there the component has different values that its archetype,
	// and only when the component is being compared to its archetype (as opposed to another component instance, for example)
	SetPortFlags(PPF_DeepCompareInstances);
}


text:
#include "Player.h"
#include "../../exceptions.h"
#include "../../Application.h"

extern "C" {
  #include "../../audio/audio.h"
}

/* REMOVE ME */
namespace spotify {
  extern int framesReceived;
  extern int currentSecond;
}

extern Application* application;

Player::Player() : currentSecond(0), isPaused(false), isLoading(false),
  loadingTrack(nullptr) {};

void Player::stop() {
  sp_session_player_unload(application->session);
}

void Player::pause() {
  sp_session_player_play(application->session, 0);
  audio_fifo_flush(&application->audio_fifo);
  isPaused = true;
}

void Player::resume() {
 if(isPaused) {
    sp_session_player_play(application->session, 1);
    isPaused = false;
  }
}

void Player::play(std::shared_ptr<Track> track) {
  spotify::framesReceived = 0;
  spotify::currentSecond = 0;
  sp_error error = sp_session_player_load(application->session, track->track);
  if(error == SP_ERROR_IS_LOADING) {
    isLoading = true;
    loadingTrack = track->track;
  } else if (error == SP_ERROR_TRACK_NOT_PLAYABLE) {
    throw TrackNotPlayableException();
  } else {
    sp_session_player_play(application->session, 1);
  }
}

void Player::retryPlay() {
  sp_error error = sp_track_error(loadingTrack);
  if(error != SP_ERROR_IS_LOADING) {
    sp_session_player_load(application->session, loadingTrack);
    sp_session_player_play(application->session, 1);
    isLoading = false;
    loadingTrack = nullptr;
  }
}

void Player::seek(int second) {
  sp_session_player_seek(application->session, second*1000);
  spotify::currentSecond = second;
}

void Player::setCurrentSecond(int second) {
  currentSecond = second;
}

std::shared_ptr<Player> Player::instance = std::make_shared<Player>();


text:
package test.eidos.kingchanllenge.utils;

import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.equalTo;

import java.io.UnsupportedEncodingException;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;

import org.easymock.EasyMockRunner;
import org.eidos.kingchallenge.httpserver.handlers.HttpKingExchangeHelper;
import org.eidos.kingchallenge.utils.HttpExchangeUtils;
import org.junit.Test;
import org.junit.runner.RunWith;

import test.eidos.kingchanllenge.AbstractKingTest;

@RunWith(EasyMockRunner.class)
public class TestHttpExchangeutils   extends AbstractKingTest{

	@Test
	public void testTestHttpExchangeutils() throws UnsupportedEncodingException {
		Map<String,Object> map= new HashMap<String,Object>();
		String expectedparam="BabWcCKxRmnzPqyvZVKMfxWPuICmnBzEXIx";
		HttpExchangeUtils.parseQuery("score?sessionkey=BabWcCKxRmnzPqyvZVKMfxWPuICmnBzEXIx", map);
		for( Entry<String, Object> elem :map.entrySet()) {
			assertThat("",  (String)elem.getValue() , equalTo(expectedparam));
		}
	}
	@Test
	public void testHttpKingExchangeHelper() {
		Map<String,Object> requestParamMap= new HashMap<String,Object>();
		requestParamMap.put("3","3");
		requestParamMap.put("sessionkey", "BabWcCKxRmnzPqyvZVKMfxWPuICmnBzEXIx");
		assertThat("", HttpKingExchangeHelper.getKey(requestParamMap, "sessionkey"),  equalTo("BabWcCKxRmnzPqyvZVKMfxWPuICmnBzEXIx"));
		assertThat("", HttpKingExchangeHelper.getLongValue(requestParamMap, "3"),  equalTo(3L));
	}
}


text:
from django.test import TestCase
from django.contrib.auth.models import User
from mainstay.test_utils import MainstayTest

from .models import Page

class WikiTestCase(MainstayTest):
    fixtures = MainstayTest.fixtures + ['wiki_pages']

    def test_user_loaded(self):
        self.assertEqual(self.admin.username, 'admin')
        self.assertEqual(self.admin.is_superuser, True)

    def test_pages_loaded(self):
        pages = Page.objects.all()
        self.assertEqual(len(pages), 2)

    def test_page_view(self):
        self.login()
        r = self.client.get('/wiki/page/TestPage/')
        self.assertEqual(r.status_code, 200)

    def test_page_with_link(self):
        self.login()
        r = self.client.get('/wiki/page/PageWithLink/')
        self.assertEqual(r.status_code, 200)
        self.assertInHTML('TestPage', r.content.decode('utf-8'))

    def test_search(self):
        self.login()
        r = self.client.get('/wiki/search/page/')
        self.assertEqual(r.status_code, 200)
        results = r.context['results']
        self.assertEqual({r.title for r in results}, {'TestPage', 'PageWithLink'})

        r = self.client.get('/wiki/search/withlink/')
        results = r.context['results']
        self.assertEqual({r.title for r in results}, {'PageWithLink'})

    def test_add_page(self):
        self.login()
        self.assertEqual(Page.objects.count(), 2)
        post = {'title': 'NewTitle',
                'content': 'NewContent'}
        r = self.client.post('/wiki/add/', post, follow=True)
        self.assertRedirects(r, '/wiki')

    def test_edit_page(self):
        self.login()
        self.assertEqual(Page.objects.count(), 2)
        post = {'title': 'NewTitle',
                'content': 'NewContent'}
        r = self.client.post('/wiki/edit/TestPage/', post, follow=True)
        self.assertRedirects(r, '/wiki/page/NewTitle/')


text:
from setuptools import setup, find_packages
setup(
    name="html_purifier",
    version="1.0",
    packages=find_packages(),
)


text:
#include <cxxtest/TestSuite.h>
#include <sirikata/mesh/Meshdata.hpp>
#include <sirikata/mesh/ModelsSystemFactory.hpp>
#include <fstream>
#include <sirikata/core/util/Paths.hpp>
#include <boost/filesystem.hpp>
#include <sirikata/mesh/Filter.hpp>
#include <sirikata/mesh/CompositeFilter.hpp>
#include <sirikata/core/util/PluginManager.hpp>

using namespace Sirikata;
using namespace std;
using namespace Mesh;

class PlyLoaderTest : public CxxTest::TestSuite
{
protected:
	int _initialized;
	String _plugin;
	PluginManager _pmgr;
	ModelsSystem *msys;

public:

    void setUp( void )
    {
		//initialize plugin
		if (!_initialized) {
            _initialized = 1;
            _pmgr.loadList("mesh-ply,common-filters");
        }
		//create ModelsSystem
		msys = ModelsSystemFactory::getSingleton ().getConstructor ( "mesh-ply" ) ( "" );
		assert(msys);

    }
    void tearDown( void )
    {
		delete msys;
		_pmgr.gc();
		_initialized = 0;
    }

	//the PlyModelSystem needs to be made more efficient, as larger files take
	//a very long time to load (the second lowest resolution of the stanford bunny
	//takes around 45 seconds...

	void testPlyLoaderSimple( void ) {
		//ply file with almost nothing
		string simple = getString("simple");

		Transfer::DenseData *dd = new Transfer::DenseData(simple);
		Transfer::DenseDataPtr data(dd);
		TS_ASSERT_EQUALS(msys->canLoad(data), true);

		Mesh::VisualPtr parsed = msys->load(data);
		TS_ASSERT_EQUALS(parsed, Mesh::VisualPtr());
		MeshdataPtr mdp(std::tr1::dynamic_pointer_cast<Meshdata>(parsed));
		TS_ASSERT_EQUALS(mdp, MeshdataPtr());
    }

	void testPlyLoaderLine( void ) {
		//ply file with a line
		string line = getString("line");
		MeshdataPtr mdp = loadMDP(line);

		//asserts
		TS_ASSERT_DIFFERS(mdp, MeshdataPtr());
		TS_ASSERT_EQUALS(mdp->getInstancedGeometryCount(), 1);
		TS_ASSERT_EQUALS(mdp->getInstancedLightCount(), 0);
		TS_ASSERT_EQUALS(mdp->getJointCount(), 0);
		TS_ASSERT_EQUALS(mdp->geometry.size(), 1);
		TS_ASSERT_EQUALS(mdp->geometry[0].skinControllers.size(), 0);
		TS_ASSERT_EQUALS(mdp->geometry[0].primitives.size(), 1);
		TS_ASSERT_EQUALS(mdp->geometry[0].primitives[0].indices.size(), 2);
		TS_ASSERT_EQUALS(mdp->lights.size(), 0);
		TS_ASSERT_EQUALS(mdp->textures.size(), 0);
		TS_ASSERT_EQUALS(mdp->materials.size(), 1);
		TS_ASSERT_EQUALS(mdp->materials[0].textures.size(), 0);
		TS_ASSERT_EQUALS(mdp->nodes.size(), 1);
		TS_ASSERT_EQUALS(mdp->nodes[0].transform, Matrix4x4f::identity());
		TS_ASSERT_EQUALS(mdp->globalTransform, Matrix4x4f::identity());
	}

	void testPlyLoaderSquare( void ) {
		//ply file with a square (actually a rectangle)
		string square = getString("square");
		MeshdataPtr mdp = loadMDP(square);

		//asserts
		TS_ASSERT_DIFFERS(mdp, MeshdataPtr());
		TS_ASSERT_EQUALS(mdp->getInstancedGeometryCount(), 1);
		TS_ASSERT_EQUALS(mdp->getInstancedLightCount(), 0);
		TS_ASSERT_EQUALS(mdp->getJointCount(), 0);
		TS_ASSERT_EQUALS(mdp->geometry.size(), 1);
		TS_ASSERT_EQUALS(mdp->geometry[0].positions.size(), 4);
		TS_ASSERT_EQUALS(mdp->geometry[0].skinControllers.size(), 0);
		TS_ASSERT_EQUALS(mdp->geometry[0].primitives.size(), 1);
		TS_ASSERT_EQUALS(mdp->geometry[0].primitives[0].indices.size(), 6);
		TS_ASSERT_EQUALS(mdp->lights.size(), 0);
		TS_ASSERT_EQUALS(mdp->textures.size(), 0);
		TS_ASSERT_EQUALS(mdp->materials.size(), 1);
		TS_ASSERT_EQUALS(mdp->materials[0].textures.size(), 1);
		TS_ASSERT_EQUALS(mdp->nodes.size(), 1);
		TS_ASSERT_EQUALS(mdp->nodes[0].transform, Matrix4x4f::identity());
		TS_ASSERT_EQUALS(mdp->globalTransform, Matrix4x4f::identity());
	}

	void testPlyLoaderSquare2s( void ) {
		//ply file with square with two sides, one of which is specially texturized
		string square2s = getString("square2s");
		MeshdataPtr mdp = loadMDP(square2s);

		//asserts
		TS_ASSERT_DIFFERS(mdp, MeshdataPtr());
		TS_ASSERT_EQUALS(mdp->getInstancedGeometryCount(), 1);
		TS_ASSERT_EQUALS(mdp->getInstancedLightCount(), 0);
		TS_ASSERT_EQUALS(mdp->getJointCount(), 0);
		TS_ASSERT_EQUALS(mdp->geometry.size(), 1);
		TS_ASSERT_EQUALS(mdp->geometry[0].positions.size(), 8);
		TS_ASSERT_EQUALS(mdp->geometry[0].skinControllers.size(), 0);
		TS_ASSERT_EQUALS(mdp->geometry[0].primitives.size(), 2);
		TS_ASSERT_EQUALS(mdp->geometry[0].primitives[0].indices.size(), 6)
		TS_ASSERT_EQUALS(mdp->lights.size(), 0);
		TS_ASSERT_EQUALS(mdp->textures.size(), 1);
		TS_ASSERT_EQUALS(mdp->materials.size(), 2);
		for(uint32 i = 0; i < mdp->materials.size(); i++)
			TS_ASSERT_EQUALS(mdp->materials[i].textures.size(), 1);
		TS_ASSERT_EQUALS(mdp->nodes.size(), 1);
		TS_ASSERT_EQUALS(mdp->nodes[0].transform, Matrix4x4f::identity());
		TS_ASSERT_EQUALS(mdp->globalTransform, Matrix4x4f::identity());
	}

	void testPlyLoaderCubes( void ) {
		//ply file with three textured cubes of different rotations
		string cubes = getString("cubes");
		MeshdataPtr mdp = loadMDP(cubes);

		//asserts
		TS_ASSERT_DIFFERS(mdp, MeshdataPtr());
		TS_ASSERT_EQUALS(mdp->getInstancedGeometryCount(), 3);
		TS_ASSERT_EQUALS(mdp->getInstancedLightCount(), 0);
		TS_ASSERT_EQUALS(mdp->getJointCount(), 0);
		TS_ASSERT_EQUALS(mdp->geometry.size(), 3);
		for(uint32 i = 0; i < mdp->geometry.size(); i++) {
			TS_ASSERT_EQUALS(mdp->geometry[i].positions.size(), 24);
			TS_ASSERT_EQUALS(mdp->geometry[i].skinControllers.size(), 0);
			TS_ASSERT_EQUALS(mdp->geometry[i].primitives.size(), 1);
			TS_ASSERT_EQUALS(mdp->geometry[i].primitives[0].indices.size(), 36);
		}
		TS_ASSERT_EQUALS(mdp->lights.size(), 0);
		TS_ASSERT_EQUALS(mdp->textures.size(), 2);
		TS_ASSERT_EQUALS(mdp->materials.size(), 3);
		TS_ASSERT_EQUALS(mdp->nodes.size(), 1);
		TS_ASSERT_EQUALS(mdp->nodes[0].transform, Matrix4x4f::identity());
		TS_ASSERT_EQUALS(mdp->globalTransform, Matrix4x4f::identity());
	}

	void testPlyLoaderPrism( void ) {
		//ply file with partially textured hexagonal prism
		string prism = getString("prism");
		MeshdataPtr mdp = loadMDP(prism);

		//asserts
		TS_ASSERT_DIFFERS(mdp, MeshdataPtr());
		TS_ASSERT_EQUALS(mdp->getInstancedGeometryCount(), 3);
		TS_ASSERT_EQUALS(mdp->getInstancedLightCount(), 0);
		TS_ASSERT_EQUALS(mdp->getJointCount(), 0);
		TS_ASSERT_EQUALS(mdp->geometry.size(), 3);
		for(uint32 i = 0; i < mdp->geometry.size(); i++) {
			TS_ASSERT_EQUALS(mdp->geometry[i].skinControllers.size(), 0);
			TS_ASSERT_EQUALS(mdp->geometry[i].primitives.size(), 1);
		}
		TS_ASSERT_EQUALS(mdp->lights.size(), 0);
		TS_ASSERT_EQUALS(mdp->textures.size(), 2);
		TS_ASSERT_EQUALS(mdp->materials.size(), 3);
		TS_ASSERT_EQUALS(mdp->materials[0].textures.size(), 1);
		TS_ASSERT_EQUALS(mdp->nodes.size(), 1);
		TS_ASSERT_EQUALS(mdp->nodes[0].transform, Matrix4x4f::identity());
		TS_ASSERT_EQUALS(mdp->globalTransform, Matrix4x4f::identity());
	}

	void testPlyLoaderCircleT( void ) {
		//ply file with one texturized circle
		string circleT = getString("circleT");
		MeshdataPtr mdp = loadMDP(circleT);

		//asserts
		TS_ASSERT_DIFFERS(mdp, MeshdataPtr());
		TS_ASSERT_EQUALS(mdp->getInstancedGeometryCount(), 1);
		TS_ASSERT_EQUALS(mdp->getInstancedLightCount(), 0);
		TS_ASSERT_EQUALS(mdp->getJointCount(), 0);
		TS_ASSERT_EQUALS(mdp->geometry.size(), 1);
		TS_ASSERT_EQUALS(mdp->geometry[0].positions.size(), 48);
		TS_ASSERT_EQUALS(mdp->geometry[0].skinControllers.size(), 0);
		TS_ASSERT_EQUALS(mdp->geometry[0].primitives.size(), 1);
		TS_ASSERT_EQUALS(mdp->geometry[0].primitives[0].indices.size(), 132);
		TS_ASSERT_EQUALS(mdp->lights.size(), 0);
		TS_ASSERT_EQUALS(mdp->textures.size(), 1);
		TS_ASSERT_EQUALS(mdp->materials.size(), 1);
		TS_ASSERT_EQUALS(mdp->materials[0].textures.size(), 1);
		TS_ASSERT_EQUALS(mdp->nodes.size(), 1);
		TS_ASSERT_EQUALS(mdp->nodes[0].transform, Matrix4x4f::identity());
		TS_ASSERT_EQUALS(mdp->globalTransform, Matrix4x4f::identity());
	}

	void testPlyLoaderCircles( void ) {
		//ply file with two distinct circles
		string circles = getString("circles");
		MeshdataPtr mdp = loadMDP(circles);

		//asserts
		TS_ASSERT_DIFFERS(mdp, MeshdataPtr());
		TS_ASSERT_EQUALS(mdp->getInstancedGeometryCount(), 2);
		TS_ASSERT_EQUALS(mdp->getInstancedLightCount(), 0);
		TS_ASSERT_EQUALS(mdp->getJointCount(), 0);
		TS_ASSERT_EQUALS(mdp->geometry.size(), 2);
		for(uint32 i = 0; i < mdp->geometry.size(); i++) {
			TS_ASSERT_EQUALS(mdp->geometry[i].positions.size(), 24);
			TS_ASSERT_EQUALS(mdp->geometry[i].skinControllers.size(), 0);
			TS_ASSERT_EQUALS(mdp->geometry[i].primitives.size(), 1);
			TS_ASSERT_EQUALS(mdp->geometry[i].primitives[0].indices.size(), 66);
		}
		TS_ASSERT_EQUALS(mdp->lights.size(), 0);
		TS_ASSERT_EQUALS(mdp->textures.size(), 0);
		TS_ASSERT_EQUALS(mdp->materials.size(), 1);
		TS_ASSERT_EQUALS(mdp->materials[0].textures.size(), 1);
		TS_ASSERT_EQUALS(mdp->nodes.size(), 1);
		TS_ASSERT_EQUALS(mdp->nodes[0].transform, Matrix4x4f::identity());
		TS_ASSERT_EQUALS(mdp->globalTransform, Matrix4x4f::identity());
	}

	void testPlyLoaderCylinders( void ) {
		//ply file with two cylinders
		string cylinders = getString("cylinders");
		MeshdataPtr mdp = loadMDP(cylinders);

		//asserts
		TS_ASSERT_DIFFERS(mdp, MeshdataPtr());
		TS_ASSERT_EQUALS(mdp->getInstancedGeometryCount(), 2);
		TS_ASSERT_EQUALS(mdp->getInstancedLightCount(), 0);
		TS_ASSERT_EQUALS(mdp->getJointCount(), 0);
		TS_ASSERT_EQUALS(mdp->geometry.size(), 2);
		for(uint32 i = 0; i < mdp->geometry.size(); i++) {
			TS_ASSERT_EQUALS(mdp->geometry[i].positions.size(), 96);
			TS_ASSERT_EQUALS(mdp->geometry[i].skinControllers.size(), 0);
			TS_ASSERT_EQUALS(mdp->geometry[i].primitives.size(), 1);
			TS_ASSERT_EQUALS(mdp->geometry[i].primitives[0].indices.size(), 276);
		}
		TS_ASSERT_EQUALS(mdp->lights.size(), 0);
		TS_ASSERT_EQUALS(mdp->textures.size(), 0);
		TS_ASSERT_EQUALS(mdp->materials.size(), 1);
		TS_ASSERT_EQUALS(mdp->materials[0].textures.size(), 1);
		TS_ASSERT_EQUALS(mdp->nodes.size(), 1);
		TS_ASSERT_EQUALS(mdp->nodes[0].transform, Matrix4x4f::identity());
		TS_ASSERT_EQUALS(mdp->globalTransform, Matrix4x4f::identity());
	}

	void testPlyLoaderDrill( void ) {
		//ply file with drill
		//its results deviate significantly from those of the collada version...
		//but then again, the two formats are bettter for different things...
		//also, this loads *very* slowly, showing the inefficiency of the ply plugin
		string drill = getString("drill/reconstruction/drill_shaft_zip");
		MeshdataPtr mdp = loadMDP(drill);

		//asserts
		TS_ASSERT_DIFFERS(mdp, MeshdataPtr());
		TS_ASSERT_EQUALS(mdp->getInstancedGeometryCount(), 7);
		TS_ASSERT_EQUALS(mdp->getInstancedLightCount(), 0);
		TS_ASSERT_EQUALS(mdp->getJointCount(), 0);
		TS_ASSERT_EQUALS(mdp->geometry.size(), 7);
		TS_ASSERT_EQUALS(mdp->geometry[0].positions.size(), 845);
		TS_ASSERT_EQUALS(mdp->geometry[0].skinControllers.size(), 0);
		TS_ASSERT_EQUALS(mdp->geometry[0].primitives.size(), 1);
		TS_ASSERT_EQUALS(mdp->geometry[0].primitives[0].indices.size(), 3831);
		TS_ASSERT_EQUALS(mdp->lights.size(), 0);
		TS_ASSERT_EQUALS(mdp->textures.size(), 0);
		TS_ASSERT_EQUALS(mdp->materials.size(), 1);
		TS_ASSERT_EQUALS(mdp->nodes.size(), 1);
		TS_ASSERT_EQUALS(mdp->nodes[0].transform, Matrix4x4f::identity());
	}

	void testPlyLoaderBunny( void ) {
		//ply file with bunny
		string bunny = getString("bunny/reconstruction/bun_zipper_res4");
		MeshdataPtr mdp = loadMDP(bunny);

		//asserts
		TS_ASSERT_DIFFERS(mdp, MeshdataPtr());
		TS_ASSERT_EQUALS(mdp->getInstancedGeometryCount(), 1);
		TS_ASSERT_EQUALS(mdp->getInstancedLightCount(), 0);
		TS_ASSERT_EQUALS(mdp->getJointCount(), 0);
		TS_ASSERT_EQUALS(mdp->geometry.size(), 1);
		TS_ASSERT_EQUALS(mdp->geometry[0].positions.size(), 453);
		TS_ASSERT_EQUALS(mdp->geometry[0].skinControllers.size(), 0);
		TS_ASSERT_EQUALS(mdp->geometry[0].primitives.size(), 1);
		TS_ASSERT_EQUALS(mdp->geometry[0].primitives[0].indices.size(), 2844);
		TS_ASSERT_EQUALS(mdp->lights.size(), 0);
		TS_ASSERT_EQUALS(mdp->textures.size(), 0);
		TS_ASSERT_EQUALS(mdp->materials.size(), 1);
		TS_ASSERT_EQUALS(mdp->nodes.size(), 1);
		TS_ASSERT_EQUALS(mdp->nodes[0].transform, Matrix4x4f::identity());
	}

	void testPlyLoaderNull( void ) {
		//invalid ply file
		Transfer::DenseData *dd = new Transfer::DenseData("Hello world!");
		Transfer::DenseDataPtr data(dd);
		//the ply file shouldn't load
		TS_ASSERT_EQUALS(msys->canLoad(data), false);
		//so parsed should be null
		Mesh::VisualPtr parsed = msys->load(data);
		TS_ASSERT_EQUALS(parsed, Mesh::VisualPtr());
		//and so should mdp
		MeshdataPtr mdp(std::tr1::dynamic_pointer_cast<Meshdata>(parsed));
		TS_ASSERT_EQUALS(mdp, MeshdataPtr());
	}

	string getString(string name) {
		string result;
		//obtains string of information from the ply file rather than
		//copying and directly placing the text in the file

		// For now only support in-tree execution
        boost::filesystem::path ply_data_dir = boost::filesystem::path(Path::Get(Path::DIR_EXE));
        // Windows exes are one level deeper due to Debug or RelWithDebInfo
#if SIRIKATA_PLATFORM == SIRIKATA_PLATFORM_WINDOWS
        ply_data_dir = ply_data_dir / "..";
#endif
        ply_data_dir = ply_data_dir / "../../test/unit/libmesh/ply";

        ifstream fin ( (ply_data_dir / (name + ".ply")).string().c_str() );
        if (!fin) {
            TS_WARN("Unable to find ply data.");
            return "";
        }

		string temp;

		do {
			fin >> temp;
			result += temp + ' ';
		}while(fin);
		return result;
	}

	//MeshdataPtr loadMDP(string thing) {
	//	//loads the MeshdataPtr from the ply string
	//	Transfer::DenseData *dd = new Transfer::DenseData(thing);
	//	Transfer::DenseDataPtr data(dd);
	//	TS_ASSERT_EQUALS(msys->canLoad(data), true);

	//	Mesh::VisualPtr parsed = msys->load(data);
	//	TS_ASSERT_DIFFERS(parsed, Mesh::VisualPtr());
	//	MeshdataPtr mdp(std::tr1::dynamic_pointer_cast<Meshdata>(parsed));
	//	return mdp;
	//}

	MeshdataPtr loadMDP(string thing) {
		//loads the MeshdataPtr from the ply string and applies the deduplication filter
		std::vector<String> names_and_args;
		names_and_args.push_back("compute-normals"); names_and_args.push_back("");
		names_and_args.push_back("deduplication"); names_and_args.push_back("");
		Mesh::Filter* filter = new Mesh::CompositeFilter(names_and_args);

		Transfer::DenseData *dd = new Transfer::DenseData(thing);
		Transfer::DenseDataPtr data(dd);
		TS_ASSERT_EQUALS(msys->canLoad(data), true);

		Mesh::VisualPtr parsed = msys->load(data);
		Mesh::MutableFilterDataPtr input(new Mesh::FilterData);
		input->push_back(parsed);
		Mesh::FilterDataPtr output = filter->apply(input);
		parsed = output->get();
		MeshdataPtr mdp(std::tr1::dynamic_pointer_cast<Meshdata>(parsed));

		return mdp;
	}
};


text:
emo is an irssi theme heavily based on benny's (benny@IRCnet) gothic theme (but
less aggressive in my opinion :).

## Thanks
Benny (benny@IRCnet, benny@graniitti.net) for his gothic theme.


text:
set -e

usage() {
   echo "usage: make_tarball.sh <SUPERSET_VERSION> <SUPERSET_RC> <PGP_KEY_FULLBANE>"
}

if [ -z "$1" ] || [ -z "$2" ] || [ -z "$3" ]; then
  if [ -z "${SUPERSET_VERSION}" ] || [ -z "${SUPERSET_RC}" ] || [ -z "${SUPERSET_PGP_FULLNAME}" ] || [ -z "${SUPERSET_RELEASE_RC_TARBALL}" ]; then
    echo "No parameters found and no required environment variables set"
    echo "usage: make_tarball.sh <SUPERSET_VERSION> <SUPERSET_RC> <PGP_KEY_FULLBANE>"
    usage;
    exit 1
  fi
else
  SUPERSET_VERSION="${1}"
  SUPERSET_RC="${2}"
  SUPERSET_PGP_FULLNAME="${3}"
  SUPERSET_RELEASE_RC_TARBALL="apache-superset-${SUPERSET_VERSION_RC}-source.tar.gz"
fi

SUPERSET_VERSION_RC="${SUPERSET_VERSION}rc${SUPERSET_RC}"

if [ -z "${SUPERSET_SVN_DEV_PATH}" ]; then
  SUPERSET_SVN_DEV_PATH="$HOME/svn/superset_dev"
fi

if [[ ! -d "${SUPERSET_SVN_DEV_PATH}" ]]; then
  echo "${SUPERSET_SVN_DEV_PATH} does not exist, you need to: svn checkout"
  exit 1
fi

if [ -d "${SUPERSET_SVN_DEV_PATH}/${SUPERSET_VERSION_RC}" ]; then
  echo "${SUPERSET_VERSION_RC} Already exists on svn, refusing to overwrite"
  exit 1
fi

SUPERSET_RELEASE_RC_TARBALL_PATH="${SUPERSET_SVN_DEV_PATH}"/"${SUPERSET_VERSION_RC}"/"${SUPERSET_RELEASE_RC_TARBALL}"
DOCKER_SVN_PATH="/docker_svn"

# Building docker that will produce a tarball
docker build -t apache-builder -f Dockerfile.make_tarball .

# Running docker to produce a tarball
docker run \
      -e SUPERSET_SVN_DEV_PATH="${DOCKER_SVN_PATH}" \
      -e SUPERSET_VERSION="${SUPERSET_VERSION}" \
      -e SUPERSET_VERSION_RC="${SUPERSET_VERSION_RC}" \
      -e HOST_UID=${UID} \
      -v "${SUPERSET_SVN_DEV_PATH}":"${DOCKER_SVN_PATH}":rw \
      -ti apache-builder

gpg --armor --local-user "${SUPERSET_PGP_FULLNAME}" --output "${SUPERSET_RELEASE_RC_TARBALL_PATH}".asc --detach-sig "${SUPERSET_RELEASE_RC_TARBALL_PATH}"
gpg --print-md --local-user "${SUPERSET_PGP_FULLNAME}" SHA512 "${SUPERSET_RELEASE_RC_TARBALL_PATH}" > "${SUPERSET_RELEASE_RC_TARBALL_PATH}".sha512

echo ---------------------------------------
echo Release candidate tarball is ready
echo ---------------------------------------


text:
import { waitForAsync, ComponentFixture, TestBed } from '@angular/core/testing';
import { RouterTestingModule } from '@angular/router/testing';
import { HttpClientTestingModule } from '@angular/common/http/testing';

import { PostComponent } from './post.component';
import { FormsModule } from '@angular/forms';
import { DatePipe } from '@angular/common';

describe('PostComponent', () => {
  let component: PostComponent;
  let fixture: ComponentFixture<PostComponent>;

  beforeEach(waitForAsync(() => {
    TestBed.configureTestingModule({
      imports: [
        RouterTestingModule,
        HttpClientTestingModule,
        FormsModule
      ],
      declarations: [ PostComponent ],
      providers: [
        DatePipe
      ]
    })
    .compileComponents();
  }));

  beforeEach(() => {
    fixture = TestBed.createComponent(PostComponent);
    component = fixture.componentInstance;
    fixture.detectChanges();
  });

  it('should create', () => {
    expect(component).toBeTruthy();
  });
});