Link Detection
==============

Some fields of PoiIssues and responses can have text like #42 to
point to an issue and r1000 to point to a revision or changeset.  This
is governed by settings in the PoiTracker.

The linkDetection method was split up into several methods.  These
will be tested here.  See the testTracker.TestLinkDetection class for
more tests.


getNumberFromString
~~~~~~~~~~~~~~~~~~~

This gets a number from a string.  It always returns a string as well::

    >>> from Products.Poi.utils import getNumberFromString
    >>> getNumberFromString('#1')
    '1'
    >>> getNumberFromString('r12')
    '12'
    >>> getNumberFromString('rev42')
    '42'
    >>> getNumberFromString('[42]')
    '42'
    >>> getNumberFromString('ticket:399')
    '399'
    >>> getNumberFromString('changeset:12345.')
    '12345'

Look for problems::

    >>> getNumberFromString('') is None
    True
    >>> getNumberFromString('foobar') is None
    True
    >>> getNumberFromString('2')
    '2'
    >>> getNumberFromString(u'3')
    u'3'
    >>> getNumberFromString('-7')
    '7'
    >>> getNumberFromString('0') is None
    True
    >>> getNumberFromString('#007')
    '7'
    >>> getNumberFromString('my.html#7')
    '7'

With more numbers, the first one is taken::

    >>> getNumberFromString('its13past12')
    '13'


linkBugs
~~~~~~~~

This links to bugs.  First we give some ids of existing bugs and some
text with possibly links::

    >>> from Products.Poi.utils import linkBugs
    >>> ids = [str(i) for i in range(12)]
    >>> text = "issue:1 #2 r3 [4] ticket:5."

Now we test this with patterns::

    >>> from Products.Poi.config import ISSUE_RECOGNITION_PATTERNS
    >>> patterns = ['test']
    >>> linkBugs(text, ids, patterns)
    'issue:1 #2 r3 [4] ticket:5.'
    >>> patterns = ['#2']
    >>> linkBugs(text, ids, patterns)
    'issue:1 <a href="../2">#2</a> r3 [4] ticket:5.'
    >>> patterns = ['#[1-9][0-9]*']
    >>> linkBugs(text, ids, patterns)
    'issue:1 <a href="../2">#2</a> r3 [4] ticket:5.'
    >>> patterns = ['[[1-9][0-9]*]']
    >>> linkBugs(text, ids, patterns)
    'issue:1 #2 r3 <a href="../4">[4]</a> ticket:5.'
    >>> patterns = ISSUE_RECOGNITION_PATTERNS
    >>> linkBugs(text, ids, patterns)
    '<a href="../1">issue:1</a> <a href="../2">#2</a> r3 [4] <a href="../5">ticket:5</a>.'
    >>> linkBugs(text, [], patterns)
    'issue:1 #2 r3 [4] ticket:5.'
    >>> linkBugs("#9#9#9", ['9'], ["#9"])
    '<a href="../9">#9</a><a href="../9">#9</a><a href="../9">#9</a>'
    >>> linkBugs("foo#9 #9a #99 #9", ['9'], patterns)
    'foo#9 #9a #99 <a href="../9">#9</a>'
    >>> linkBugs("noticket:5 ticket:5", ['5'], patterns)
    'noticket:5 <a href="../5">ticket:5</a>'

You can pass a base_url to linkBugs.  The default is '..'.  This works
fine when you view an issue.  But in 'tracker/@@log' such a url will
point outside of the tracker.  So now we pass the url of the tracker
when we call the relevant code.

    >>> linkBugs("#1", ['1'], patterns, base_url='http://example.org/issues')
    '<a href="http://example.org/issues/1">#1</a>'


linkSvn
~~~~~~~~

Replace patterns with links to changesets in a repository.  It does
not need to be subversion of course.  Specify something to test with::

    >>> from Products.Poi.utils import linkSvn
    >>> from Products.Poi.config import REVISION_RECOGNITION_PATTERNS
    >>> text = "r1 #22 changeset:333 [4444]"
    >>> svnUrl = "someurl?rev=%(rev)s"

And test it::

    >>> patterns = []
    >>> linkSvn(text, svnUrl, patterns)
    'r1 #22 changeset:333 [4444]'
    >>> patterns = ["r1"]
    >>> linkSvn(text, svnUrl, patterns)
    '<a href="someurl?rev=1">r1</a> #22 changeset:333 [4444]'
    >>> patterns = REVISION_RECOGNITION_PATTERNS
    >>> linkSvn(text, svnUrl, patterns)
    '<a href="someurl?rev=1">r1</a> #22 <a href="someurl?rev=333">changeset:333</a> <a href="someurl?rev=4444">[4444]</a>'

Of course if you want to be silly, you can::

    >>> linkSvn(text, "here", patterns)
    '<a href="here">r1</a> #22 <a href="here">changeset:333</a> <a href="here">[4444]</a>'

Test with multiple similar revisions.  This is more a text of our
regular expression skills::

    >>> text = "r1 r2 norevisionr3 r4nope (r5) r6."
    >>> linkSvn(text, svnUrl, patterns)
    '<a href="someurl?rev=1">r1</a> <a href="someurl?rev=2">r2</a> norevisionr3 r4nope (<a href="someurl?rev=5">r5</a>) <a href="someurl?rev=6">r6</a>.'
    >>> text = "[1] link[2] [3]."
    >>> linkSvn(text, svnUrl, patterns)
    '<a href="someurl?rev=1">[1]</a> link[2] <a href="someurl?rev=3">[3]</a>.'

