Page MenuHomestyx hydra

No OneTemporary

diff --git a/src/applications/project/remarkup/ProjectRemarkupRule.php b/src/applications/project/remarkup/ProjectRemarkupRule.php
index 41ea2e026f..5eeddeabfe 100644
--- a/src/applications/project/remarkup/ProjectRemarkupRule.php
+++ b/src/applications/project/remarkup/ProjectRemarkupRule.php
@@ -1,81 +1,74 @@
<?php
final class ProjectRemarkupRule extends PhabricatorObjectRemarkupRule {
protected function getObjectNamePrefix() {
return '#';
}
protected function renderObjectRef(
$object,
PhabricatorObjectHandle $handle,
$anchor,
$id) {
if ($this->getEngine()->isTextMode()) {
return '#'.$id;
}
return $handle->renderTag();
}
protected function getObjectIDPattern() {
- // NOTE: This explicitly does not match strings which contain only
- // digits, because digit strings like "#123" are used to reference tasks at
- // Facebook and are somewhat conventional in general.
-
- // The latter half of this rule matches monograms with internal periods,
- // like `#domain.com`, but does not match monograms with terminal periods,
- // because they're probably just puncutation.
+ // NOTE: The latter half of this rule matches monograms with internal
+ // periods, like `#domain.com`, but does not match monograms with terminal
+ // periods, because they're probably just puncutation.
// Broadly, this will not match every possible project monogram, and we
- // accept some false negatives -- like `#1` or `#dot.` -- in order to avoid
- // a bunch of false positives on general use of the `#` character.
+ // accept some false negatives -- like `#dot.` -- in order to avoid a bunch
+ // of false positives on general use of the `#` character.
// In other contexts, the PhabricatorProjectProjectPHIDType pattern is
// controlling and these names should parse correctly.
// These characters may never appear anywhere in a hashtag.
$never = '\s?!,:;{}#\\(\\)"\'';
- // These characters may not appear at the beginning.
- $never_first = '.\d';
-
- // These characters may not appear at the end.
- $never_last = '.';
+ // These characters may not appear at the edge of the string.
+ $never_edge = '.';
return
- '[^'.$never_first.$never.']+'.
+ '[^'.$never_edge.$never.']+'.
'(?:'.
'[^'.$never.']*'.
- '[^'.$never_last.$never.']+'.
+ '[^'.$never_edge.$never.']+'.
')*';
}
protected function loadObjects(array $ids) {
$viewer = $this->getEngine()->getConfig('viewer');
// Put the "#" back on the front of these IDs.
$names = array();
foreach ($ids as $id) {
$names[] = '#'.$id;
}
// Issue a query by object name.
$query = id(new PhabricatorObjectQuery())
->setViewer($viewer)
->withNames($names);
$query->execute();
$projects = $query->getNamedResults();
// Slice the "#" off again.
$result = array();
foreach ($projects as $name => $project) {
$result[substr($name, 1)] = $project;
}
return $result;
}
}
diff --git a/src/applications/project/remarkup/__tests__/ProjectRemarkupRuleTestCase.php b/src/applications/project/remarkup/__tests__/ProjectRemarkupRuleTestCase.php
index 80e809aba9..3789a424dd 100644
--- a/src/applications/project/remarkup/__tests__/ProjectRemarkupRuleTestCase.php
+++ b/src/applications/project/remarkup/__tests__/ProjectRemarkupRuleTestCase.php
@@ -1,123 +1,137 @@
<?php
final class ProjectRemarkupRuleTestCase extends PhabricatorTestCase {
public function testProjectObjectRemarkup() {
$cases = array(
'I like #ducks.' => array(
'embed' => array(),
'ref' => array(
array(
'offset' => 8,
'id' => 'ducks',
),
),
),
'We should make a post on #blog.example.com tomorrow.' => array(
'embed' => array(),
'ref' => array(
array(
'offset' => 26,
'id' => 'blog.example.com',
),
),
),
'We should make a post on #blog.example.com.' => array(
'embed' => array(),
'ref' => array(
array(
'offset' => 26,
'id' => 'blog.example.com',
),
),
),
'#123' => array(
'embed' => array(),
- 'ref' => array(),
+ 'ref' => array(
+ array(
+ 'offset' => 1,
+ 'id' => '123',
+ ),
+ ),
+ ),
+ '#2x4' => array(
+ 'embed' => array(),
+ 'ref' => array(
+ array(
+ 'offset' => 1,
+ 'id' => '2x4',
+ ),
+ ),
),
'#security#123' => array(
'embed' => array(),
'ref' => array(
array(
'offset' => 1,
'id' => 'security',
'tail' => '123',
),
),
),
// Don't match a terminal parenthesis. This fixes these constructs in
// natural language.
'There is some documentation (see #guides).' => array(
'embed' => array(),
'ref' => array(
array(
'offset' => 34,
'id' => 'guides',
),
),
),
// Don't match internal parentheses either. This makes the terminal
// parenthesis behavior less arbitrary (otherwise, we match open
// parentheses but not closing parentheses, which is surprising).
'#a(b)c' => array(
'embed' => array(),
'ref' => array(
array(
'offset' => 1,
'id' => 'a',
),
),
),
'#s3' => array(
'embed' => array(),
'ref' => array(
array(
'offset' => 1,
'id' => 's3',
),
),
),
'Is this #urgent?' => array(
'embed' => array(),
'ref' => array(
array(
'offset' => 9,
'id' => 'urgent',
),
),
),
'This is "#urgent".' => array(
'embed' => array(),
'ref' => array(
array(
'offset' => 10,
'id' => 'urgent',
),
),
),
"This is '#urgent'." => array(
'embed' => array(),
'ref' => array(
array(
'offset' => 10,
'id' => 'urgent',
),
),
),
);
foreach ($cases as $input => $expect) {
$rule = new ProjectRemarkupRule();
$matches = $rule->extractReferences($input);
$this->assertEqual($expect, $matches, $input);
}
}
}

File Metadata

Mime Type
text/x-diff
Expires
Thu, May 1, 4:02 AM (1 d, 12 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
108853
Default Alt Text
(6 KB)

Event Timeline