public function testInclusionOfOldFileInNewCommentFromStartWithContext()
 {
     $parser = new DifferentialHunkParser();
     $hunks = $this->createSingleChange(2, 2, "-o1\n" . " e2/1\n" . "-o3\n" . "+n2\n");
     $context = $parser->makeContextDiff($hunks, 1, 1, 1, 1);
     $this->assertEqual("@@ -1,3 +1,2 @@\n" . "-o1\n" . " e2/1\n" . "-o3\n" . "+n2", $context);
 }
 private function renderInlineCommentsForMail(PhabricatorLiskDAO $object, array $inlines)
 {
     $context_key = 'metamta.differential.unified-comment-context';
     $show_context = PhabricatorEnv::getEnvConfig($context_key);
     $changeset_ids = array();
     $line_numbers_by_changeset = array();
     foreach ($inlines as $inline) {
         $id = $inline->getComment()->getChangesetID();
         $changeset_ids[$id] = $id;
         $line_numbers_by_changeset[$id][] = $inline->getComment()->getLineNumber();
     }
     $changesets = id(new DifferentialChangesetQuery())->setViewer($this->getActor())->withIDs($changeset_ids)->needHunks(true)->execute();
     $inline_groups = DifferentialTransactionComment::sortAndGroupInlines($inlines, $changesets);
     if ($show_context) {
         $hunk_parser = new DifferentialHunkParser();
         $table = new DifferentialTransactionComment();
         $conn_r = $table->establishConnection('r');
         $queries = array();
         foreach ($line_numbers_by_changeset as $id => $line_numbers) {
             $queries[] = qsprintf($conn_r, '(changesetID = %d AND lineNumber IN (%Ld))', $id, $line_numbers);
         }
         $all_comments = id(new DifferentialTransactionComment())->loadAllWhere('transactionPHID IS NOT NULL AND (%Q)', implode(' OR ', $queries));
         $comments_by_line_number = array();
         foreach ($all_comments as $comment) {
             $comments_by_line_number[$comment->getChangesetID()][$comment->getLineNumber()][$comment->getID()] = $comment;
         }
         $author_phids = mpull($all_comments, 'getAuthorPHID');
         $authors = id(new PhabricatorPeopleQuery())->setViewer($this->getActor())->withPHIDs($author_phids)->execute();
         $authors_by_phid = mpull($authors, null, 'getPHID');
     }
     $section = new PhabricatorMetaMTAMailSection();
     foreach ($inline_groups as $changeset_id => $group) {
         $changeset = idx($changesets, $changeset_id);
         if (!$changeset) {
             continue;
         }
         foreach ($group as $inline) {
             $comment = $inline->getComment();
             $file = $changeset->getFilename();
             $start = $comment->getLineNumber();
             $len = $comment->getLineLength();
             if ($len) {
                 $range = $start . '-' . ($start + $len);
             } else {
                 $range = $start;
             }
             $inline_content = $comment->getContent();
             if (!$show_context) {
                 $section->addFragment("{$file}:{$range} {$inline_content}");
             } else {
                 $patch = $hunk_parser->makeContextDiff($changeset->getHunks(), $comment->getIsNewFile(), $comment->getLineNumber(), $comment->getLineLength(), 1);
                 $nested_comments = $this->nestCommentHistory($inline->getComment(), $comments_by_line_number, $authors_by_phid);
                 $section->addFragment('================')->addFragment(pht('Comment at: %s:%s', $file, $range))->addPlaintextFragment($patch)->addHTMLFragment($this->renderPatchHTMLForMail($patch))->addFragment('----------------')->addFragment($nested_comments)->addFragment(null);
             }
         }
     }
     return $section;
 }
 private function getPatch(DifferentialHunkParser $parser, DifferentialTransactionComment $comment, $is_html)
 {
     $changeset = $this->getChangeset($comment->getChangesetID());
     $is_new = $comment->getIsNewFile();
     $start = $comment->getLineNumber();
     $length = $comment->getLineLength();
     // By default, show one line of context around the target inline.
     $context = 1;
     // If the inline is at least 3 lines long, don't show any extra context.
     if ($length >= 2) {
         $context = 0;
     }
     // If the inline is more than 7 lines long, only show the first 7 lines.
     if ($length >= 6) {
         $length = 6;
     }
     if (!$is_html) {
         $hunks = $changeset->getHunks();
         $patch = $parser->makeContextDiff($hunks, $is_new, $start, $length, $context);
         $patch = phutil_split_lines($patch);
         // Remove the "@@ -x,y +u,v @@" line.
         array_shift($patch);
         return implode('', $patch);
     }
     $viewer = $this->getViewer();
     $engine = new PhabricatorMarkupEngine();
     if ($is_new) {
         $offset_mode = 'new';
     } else {
         $offset_mode = 'old';
     }
     $parser = id(new DifferentialChangesetParser())->setUser($viewer)->setChangeset($changeset)->setOffsetMode($offset_mode)->setMarkupEngine($engine);
     $parser->setRenderer(new DifferentialChangesetOneUpMailRenderer());
     return $parser->render($start - $context, $length + 1 + 2 * $context, array());
 }