Commit cf8c6d00 authored by Sruthi Chandran's avatar Sruthi Chandran

New upstream version 2.8.0+gh

parent 3c88daf5
# This file was generated by Appraisal
source "https://rubygems.org"
gem "rack", "< 2"
gem "rails", "3.2.22.2"
group :development do
gem "bundler"
gem "rake"
gem "appraisal"
end
group :test do
gem "minitest"
gem "rinku", "~> 1.7", :require => false
gem "gemoji", "~> 2.0", :require => false
gem "RedCloth", "~> 4.2.9", :require => false
gem "commonmarker", "~> 0.14", :require => false
gem "email_reply_parser", "~> 0.5", :require => false
gem "sanitize", "~> 2.0", :require => false
gem "escape_utils", "~> 1.0", :require => false
gem "rouge", "~> 3.1", :require => false
end
gemspec :path => "../"
# This file was generated by Appraisal
source "https://rubygems.org"
gem "rack", "< 2"
gem "rails", "~> 4.2.6"
group :development do
gem "bundler"
gem "rake"
gem "appraisal"
end
group :test do
gem "minitest"
gem "rinku", "~> 1.7", :require => false
gem "gemoji", "~> 2.0", :require => false
gem "RedCloth", "~> 4.2.9", :require => false
gem "commonmarker", "~> 0.14", :require => false
gem "email_reply_parser", "~> 0.5", :require => false
gem "sanitize", "~> 2.0", :require => false
gem "escape_utils", "~> 1.0", :require => false
gem "rouge", "~> 3.1", :require => false
end
gemspec :path => "../"
# This file was generated by Appraisal
source "https://rubygems.org"
gem "rails", "~> 5.0.0"
group :development do
gem "bundler"
gem "rake"
gem "appraisal"
end
group :test do
gem "minitest"
gem "rinku", "~> 1.7", :require => false
gem "gemoji", "~> 2.0", :require => false
gem "RedCloth", "~> 4.2.9", :require => false
gem "commonmarker", "~> 0.14", :require => false
gem "email_reply_parser", "~> 0.5", :require => false
gem "sanitize", "~> 2.0", :require => false
gem "escape_utils", "~> 1.0", :require => false
gem "rouge", "~> 3.1", :require => false
end
gemspec :path => "../"
#!/bin/bash
# Usage: script/changelog [-r <repo>] [-b <base>] [-h <head>]
#
# repo: base string of GitHub repository url. e.g. "user_or_org/repository". Defaults to git remote url.
# base: git ref to compare from. e.g. "v1.3.1". Defaults to latest git tag.
# head: git ref to compare to. Defaults to "HEAD".
#
# Generate a changelog preview from pull requests merged between `base` and
# `head`.
#
# https://github.com/jch/release-scripts/blob/master/changelog
set -e
[ $# -eq 0 ] && set -- --help
while [[ $# > 1 ]]
do
key="$1"
case $key in
-r|--repo)
repo="$2"
shift
;;
-b|--base)
base="$2"
shift
;;
-h|--head)
head="$2"
shift
;;
*)
;;
esac
shift
done
repo="${repo:-$(git remote -v | grep push | awk '{print $2}' | cut -d'/' -f4- | sed 's/\.git//')}"
base="${base:-$(git tag -l | sort -t. -k 1,1n -k 2,2n -k 3,3n | tail -n 1)}"
head="${head:-HEAD}"
api_url="https://api.github.com"
# get merged PR's. Better way is to query the API for these, but this is easier
for pr in $(git log --oneline $base..$head | grep "Merge pull request" | awk '{gsub("#",""); print $5}')
do
# frustrated with trying to pull out the right values, fell back to ruby
curl -s "$api_url/repos/$repo/pulls/$pr" | ruby -rjson -e 'pr=JSON.parse(STDIN.read); puts "* #{pr[%q(title)]} [##{pr[%q(number)]}](#{pr[%q(html_url)]})"'
done
#!/usr/bin/env bash
# Usage: script/gem
# Updates the gemspec and builds a new gem in the pkg directory.
mkdir -p pkg
gem build *.gemspec
mv *.gem pkg
#!/usr/bin/env bash
# Usage: script/release
# Build the package, tag a commit, push it to origin, and then release the
# package publicly.
set -e
version="$(script/package | grep Version: | awk '{print $2}')"
[ -n "$version" ] || exit 1
echo $version
git commit --allow-empty -a -m "Release $version"
git tag "v$version"
git push origin
git push origin "v$version"
gem push pkg/*-${version}.gem
class MockedInstrumentationService
attr_reader :events
def initialize(event = nil, events = [])
@events = events
subscribe event
end
def instrument(event, payload = nil)
payload ||= {}
res = yield payload
events << [event, payload, res] if @subscribe == event
res
end
def subscribe(event)
@subscribe = event
@events
end
end
require 'test_helper'
class HTML::Pipeline::AbsoluteSourceFilterTest < Minitest::Test
AbsoluteSourceFilter = HTML::Pipeline::AbsoluteSourceFilter
def setup
@image_base_url = 'http://assets.example.com'
@image_subpage_url = 'http://blog.example.com/a/post'
@options = {
image_base_url: @image_base_url,
image_subpage_url: @image_subpage_url
}
end
def test_rewrites_root_urls
orig = %(<p><img src="/img.png"></p>)
assert_equal "<p><img src=\"#{@image_base_url}/img.png\"></p>",
AbsoluteSourceFilter.call(orig, @options).to_s
end
def test_rewrites_relative_urls
orig = %(<p><img src="post/img.png"></p>)
assert_equal "<p><img src=\"#{@image_subpage_url}/img.png\"></p>",
AbsoluteSourceFilter.call(orig, @options).to_s
end
def test_does_not_rewrite_absolute_urls
orig = %(<p><img src="http://other.example.com/img.png"></p>)
result = AbsoluteSourceFilter.call(orig, @options).to_s
refute_match /@image_base_url/, result
refute_match /@image_subpage_url/, result
end
def test_fails_when_context_is_missing
assert_raises RuntimeError do
AbsoluteSourceFilter.call('<img src="img.png">', {})
end
assert_raises RuntimeError do
AbsoluteSourceFilter.call('<img src="/img.png">', {})
end
end
def test_tells_you_where_context_is_required
exception = assert_raises(RuntimeError) do
AbsoluteSourceFilter.call('<img src="img.png">', {})
end
assert_match 'HTML::Pipeline::AbsoluteSourceFilter', exception.message
exception = assert_raises(RuntimeError) do
AbsoluteSourceFilter.call('<img src="/img.png">', {})
end
assert_match 'HTML::Pipeline::AbsoluteSourceFilter', exception.message
end
end
require 'test_helper'
AutolinkFilter = HTML::Pipeline::AutolinkFilter
class HTML::Pipeline::AutolinkFilterTest < Minitest::Test
def test_uses_rinku_for_autolinking
# just try to parse a complicated piece of HTML
# that Rails auto_link cannot handle
assert_equal '<p>"<a href="http://www.github.com">http://www.github.com</a>"</p>',
AutolinkFilter.to_html('<p>"http://www.github.com"</p>')
end
def test_autolink_option
assert_equal '<p>"http://www.github.com"</p>',
AutolinkFilter.to_html('<p>"http://www.github.com"</p>', autolink: false)
end
def test_autolink_link_attr
assert_equal '<p>"<a href="http://www.github.com" target="_blank">http://www.github.com</a>"</p>',
AutolinkFilter.to_html('<p>"http://www.github.com"</p>', link_attr: 'target="_blank"')
end
def test_autolink_flags
assert_equal '<p>"<a href="http://github">http://github</a>"</p>',
AutolinkFilter.to_html('<p>"http://github"</p>', flags: Rinku::AUTOLINK_SHORT_DOMAINS)
end
def test_autolink_skip_tags
assert_equal '<code>"http://github.com"</code>',
AutolinkFilter.to_html('<code>"http://github.com"</code>')
assert_equal '<code>"<a href="http://github.com">http://github.com</a>"</code>',
AutolinkFilter.to_html('<code>"http://github.com"</code>', skip_tags: %w[kbd script])
end
end
require 'test_helper'
class HTML::Pipeline::CamoFilterTest < Minitest::Test
CamoFilter = HTML::Pipeline::CamoFilter
def setup
@asset_proxy_url = 'https//assets.example.org'
@asset_proxy_secret_key = 'ssssh-secret'
@options = {
asset_proxy: @asset_proxy_url,
asset_proxy_secret_key: @asset_proxy_secret_key,
asset_proxy_whitelist: [/(^|\.)github\.com$/]
}
end
def test_asset_proxy_disabled
orig = %(<p><img src="http://twitter.com/img.png"></p>)
assert_equal orig,
CamoFilter.call(orig, @options.merge(disable_asset_proxy: true)).to_s
end
def test_camouflaging_http_image_urls
orig = %(<p><img src="http://twitter.com/img.png"></p>)
assert_equal %(<p><img src="https//assets.example.org/a5ad43494e343b20d745586282be61ff530e6fa0/687474703a2f2f747769747465722e636f6d2f696d672e706e67" data-canonical-src="http://twitter.com/img.png"></p>),
CamoFilter.call(orig, @options).to_s
end
def test_doesnt_rewrite_dotcom_image_urls
orig = %(<p><img src="https://github.com/img.png"></p>)
assert_equal orig, CamoFilter.call(orig, @options).to_s
end
def test_doesnt_rewrite_dotcom_subdomain_image_urls
orig = %(<p><img src="https://raw.github.com/img.png"></p>)
assert_equal orig, CamoFilter.call(orig, @options).to_s
end
def test_doesnt_rewrite_dotcom_subsubdomain_image_urls
orig = %(<p><img src="https://f.assets.github.com/img.png"></p>)
assert_equal orig, CamoFilter.call(orig, @options).to_s
end
def test_camouflaging_github_prefixed_image_urls
orig = %(<p><img src="https://notgithub.com/img.png"></p>)
assert_equal %(<p><img src="https//assets.example.org/5d4a96c69713f850520538e04cb9661035cfb534/68747470733a2f2f6e6f746769746875622e636f6d2f696d672e706e67" data-canonical-src="https://notgithub.com/img.png"></p>),
CamoFilter.call(orig, @options).to_s
end
def test_doesnt_rewrite_absolute_image_urls
orig = %(<p><img src="/img.png"></p>)
assert_equal orig, CamoFilter.call(orig, @options).to_s
end
def test_doesnt_rewrite_relative_image_urls
orig = %(<p><img src="img.png"></p>)
assert_equal orig, CamoFilter.call(orig, @options).to_s
end
def test_camouflaging_https_image_urls
orig = %(<p><img src="https://foo.com/img.png"></p>)
assert_equal %(<p><img src="https//assets.example.org/3c5c6dc74fd6592d2596209dfcb8b7e5461383c8/68747470733a2f2f666f6f2e636f6d2f696d672e706e67" data-canonical-src="https://foo.com/img.png"></p>),
CamoFilter.call(orig, @options).to_s
end
def test_handling_images_with_no_src_attribute
orig = %(<p><img></p>)
assert_equal orig, CamoFilter.call(orig, @options).to_s
end
def test_required_context_validation
exception = assert_raises(ArgumentError) do
CamoFilter.call('', {})
end
assert_match /:asset_proxy[^_]/, exception.message
assert_match /:asset_proxy_secret_key/, exception.message
end
end
require 'test_helper'
EmailReplyFilter = HTML::Pipeline::EmailReplyFilter
class HTML::Pipeline::EmailReplyFilterTest < Minitest::Test
def setup
@body = <<-EMAIL
Hey, don't send email addresses in comments. They aren't filtered.
> On Mar 5, 2016, at 08:05, Boaty McBoatface <boatymcboatface@example.com> wrote:
>
> Sup. alreadyleaked@example.com
>
> —
> Reply to this email directly or view it on GitHub.
EMAIL
end
def test_doesnt_hide_by_default
filter = EmailReplyFilter.new(@body)
doc = filter.call.to_s
assert_match /alreadyleaked@example.com/, doc
assert_match /boatymcboatface@example.com/, doc
end
def test_hides_email_addresses_when_configured
filter = EmailReplyFilter.new(@body, hide_quoted_email_addresses: true)
doc = filter.call.to_s
refute_match /boatymcboatface@example.com/, doc
refute_match /alreadyleaked@example.com/, doc
end
def test_preserves_non_email_content_while_filtering
str = <<-EMAIL
> Thank you! I have some thoughts on this pull request.
>
> * acme provides cmake and a wrapper for it. Please use '$(TARGET)-cmake' instead of cmake -DCMAKE_TOOLCHAIN_FILE='$(CMAKE_TOOLCHAIN_FILE)' -DCMAKE_BUILD_TYPE=Release.
Okay -- I'm afraid I just blindly copied the eigen3.mk file, since that's a library I'm familiar with :-)
> * Do you need -DCMAKE_SYSTEM_PROCESSOR=x86?
Yes, this is a bit dumb, but vc checks for that (or amd) to determine that it's not being built on ARM.
--
Boaty McBoatface | http://example.org
EMAIL
filter = EmailReplyFilter.new(str, hide_quoted_email_addresses: true)
doc = filter.call.to_s
expected = <<-EXPECTED
<div class="email-quoted-reply"> Thank you! I have some thoughts on this pull request.
* acme provides cmake and a wrapper for it. Please use &#39;$(TARGET)-cmake&#39; instead of cmake -DCMAKE_TOOLCHAIN_FILE=&#39;$(CMAKE_TOOLCHAIN_FILE)&#39; -DCMAKE_BUILD_TYPE=Release.</div>
<div class="email-fragment">Okay -- I&#39;m afraid I just blindly copied the eigen3.mk file, since that&#39;s a library I&#39;m familiar with :-)</div>
<div class="email-quoted-reply"> * Do you need -DCMAKE_SYSTEM_PROCESSOR=x86?</div>
<div class="email-fragment">Yes, this is a bit dumb, but vc checks for that (or amd) to determine that it&#39;s not being built on ARM.</div>
<span class="email-hidden-toggle"><a href="#">&hellip;</a></span><div class="email-hidden-reply" style="display:none"><div class="email-signature-reply">--
Boaty McBoatface | http:&#47;&#47;example.org</div>
</div>
EXPECTED
assert_equal(expected.chomp, doc)
end
end
require 'test_helper'
class HTML::Pipeline::EmojiFilterTest < Minitest::Test
EmojiFilter = HTML::Pipeline::EmojiFilter
def test_emojify
filter = EmojiFilter.new('<p>:shipit:</p>', asset_root: 'https://foo.com')
doc = filter.call
assert_match 'https://foo.com/emoji/shipit.png', doc.search('img').attr('src').value
end
def test_uri_encoding
filter = EmojiFilter.new('<p>:+1:</p>', asset_root: 'https://foo.com')
doc = filter.call
assert_match 'https://foo.com/emoji/unicode/1f44d.png', doc.search('img').attr('src').value
end
def test_required_context_validation
exception = assert_raises(ArgumentError) do
EmojiFilter.call('', {})
end
assert_match /:asset_root/, exception.message
end
def test_custom_asset_path
filter = EmojiFilter.new('<p>:+1:</p>', asset_path: ':file_name', asset_root: 'https://foo.com')
doc = filter.call
assert_match 'https://foo.com/unicode/1f44d.png', doc.search('img').attr('src').value
end
def test_not_emojify_in_code_tags
body = '<code>:shipit:</code>'
filter = EmojiFilter.new(body, asset_root: 'https://foo.com')
doc = filter.call
assert_equal body, doc.to_html
end
def test_not_emojify_in_tt_tags
body = '<tt>:shipit:</tt>'
filter = EmojiFilter.new(body, asset_root: 'https://foo.com')
doc = filter.call
assert_equal body, doc.to_html
end
def test_not_emojify_in_pre_tags
body = '<pre>:shipit:</pre>'
filter = EmojiFilter.new(body, asset_root: 'https://foo.com')
doc = filter.call
assert_equal body, doc.to_html
end
def test_not_emojify_in_custom_single_tag_foo
body = '<foo>:shipit:</foo>'
filter = EmojiFilter.new(body, asset_root: 'https://foo.com', ignored_ancestor_tags: %w[foo])
doc = filter.call
assert_equal body, doc.to_html
end
def test_not_emojify_in_custom_multiple_tags_foo_and_bar
body = '<bar>:shipit:</bar>'
filter = EmojiFilter.new(body, asset_root: 'https://foo.com', ignored_ancestor_tags: %w[foo bar])
doc = filter.call
assert_equal body, doc.to_html
end
def test_img_tag_attributes
body = ':shipit:'
filter = EmojiFilter.new(body, asset_root: 'https://foo.com')
doc = filter.call
assert_equal %(<img class="emoji" title=":shipit:" alt=":shipit:" src="https://foo.com/emoji/shipit.png" height="20" width="20" align="absmiddle">), doc.to_html
end
def test_img_tag_attributes_can_be_customized
body = ':shipit:'
filter = EmojiFilter.new(body, asset_root: 'https://foo.com', img_attrs: Hash('draggable' => 'false', 'height' => nil, 'width' => nil, 'align' => nil))
doc = filter.call
assert_equal %(<img class="emoji" title=":shipit:" alt=":shipit:" src="https://foo.com/emoji/shipit.png" draggable="false">), doc.to_html
end
def test_img_attrs_value_can_accept_proclike_object
remove_colons = ->(name) { name.delete(':') }
body = ':shipit:'
filter = EmojiFilter.new(body, asset_root: 'https://foo.com', img_attrs: Hash('title' => remove_colons))
doc = filter.call
assert_equal %(<img class="emoji" title="shipit" alt=":shipit:" src="https://foo.com/emoji/shipit.png" height="20" width="20" align="absmiddle">), doc.to_html
end
def test_img_attrs_can_accept_symbolized_keys
body = ':shipit:'
filter = EmojiFilter.new(body, asset_root: 'https://foo.com', img_attrs: Hash(draggable: false, height: nil, width: nil, align: nil))
doc = filter.call
assert_equal %(<img class="emoji" title=":shipit:" alt=":shipit:" src="https://foo.com/emoji/shipit.png" draggable="false">), doc.to_html
end
end
require 'test_helper'
HttpsFilter = HTML::Pipeline::HttpsFilter
class HTML::Pipeline::AutolinkFilterTest < Minitest::Test
def filter(html)
HttpsFilter.to_html(html, @options)
end
def setup
@options = { base_url: 'http://github.com' }
end
def test_http
assert_equal %(<a href="https://github.com">github.com</a>),
filter(%(<a href="http://github.com">github.com</a>))
end
def test_https
assert_equal %(<a href="https://github.com">github.com</a>),
filter(%(<a href="https://github.com">github.com</a>))
end
def test_subdomain
assert_equal %(<a href="http://help.github.com">github.com</a>),
filter(%(<a href="http://help.github.com">github.com</a>))
end
def test_other
assert_equal %(<a href="http://github.io">github.io</a>),
filter(%(<a href="http://github.io">github.io</a>))
end
def test_uses_http_url_over_base_url
@options = { http_url: 'http://github.com', base_url: 'https://github.com' }
assert_equal %(<a href="https://github.com">github.com</a>),
filter(%(<a href="http://github.com">github.com</a>))
end
def test_only_http_url
@options = { http_url: 'http://github.com' }
assert_equal %(<a href="https://github.com">github.com</a>),
filter(%(<a href="http://github.com">github.com</a>))
end
def test_validates_http_url
@options.clear
exception = assert_raises(ArgumentError) { filter('') }
assert_match 'HTML::Pipeline::HttpsFilter: :http_url', exception.message
end
end
require 'test_helper'
ImageFilter = HTML::Pipeline::ImageFilter
class HTML::Pipeline::ImageFilterTest < Minitest::Test
def filter(html)
ImageFilter.to_html(html)
end
def test_jpg
assert_equal %(<img src="http://example.com/test.jpg" alt=""/>),
filter(%(http://example.com/test.jpg))
end
def test_jpeg
assert_equal %(<img src="http://example.com/test.jpeg" alt=""/>),
filter(%(http://example.com/test.jpeg))
end
def test_bmp
assert_equal %(<img src="http://example.com/test.bmp" alt=""/>),
filter(%(http://example.com/test.bmp))
end
def test_gif
assert_equal %(<img src="http://example.com/test.gif" alt=""/>),
filter(%(http://example.com/test.gif))
end
def test_png
assert_equal %(<img src="http://example.com/test.png" alt=""/>),
filter(%(http://example.com/test.png))
end
def test_https_url
assert_equal %(<img src="https://example.com/test.png" alt=""/>),
filter(%(https://example.com/test.png))
end
end
require 'test_helper'
class HTML::Pipeline::ImageMaxWidthFilterTest < Minitest::Test
def filter(html)
HTML::Pipeline::ImageMaxWidthFilter.call(html)
end
def test_rewrites_image_style_tags
body = "<p>Screenshot: <img src='screenshot.png'></p>"
doc = Nokogiri::HTML::DocumentFragment.parse(body)
res = filter(doc)
assert_equal_html '<p>Screenshot: <a target="_blank" href="screenshot.png"><img src="screenshot.png" style="max-width:100%;"></a></p>',
res.to_html
end
def test_leaves_existing_image_style_tags_alone
body = "<p><img src='screenshot.png' style='width:100px;'></p>"
doc = Nokogiri::HTML::DocumentFragment.parse(body)
res = filter(doc)
assert_equal_html '<p><img src="screenshot.png" style="width:100px;"></p>',
res.to_html
end
def test_links_to_image
body = "<p>Screenshot: <img src='screenshot.png'></p>"
doc = Nokogiri::HTML::DocumentFragment.parse(body)
res = filter(doc)
assert_equal_html '<p>Screenshot: <a target="_blank" href="screenshot.png"><img src="screenshot.png" style="max-width:100%;"></a></p>',
res.to_html
end
def test_doesnt_link_to_image_when_already_linked
body = "<p>Screenshot: <a href='blah.png'><img src='screenshot.png'></a></p>"
doc = Nokogiri::HTML::DocumentFragment.parse(body)
res = filter(doc)
assert_equal_html '<p>Screenshot: <a href="blah.png"><img src="screenshot.png" style="max-width:100%;"></a></p>',
res.to_html
end
def test_doesnt_screw_up_inlined_images
body = "<p>Screenshot <img src='screenshot.png'>, yes, this is a <b>screenshot</b> indeed.</p>"
doc = Nokogiri::HTML::DocumentFragment.parse(body)
assert_equal_html '<p>Screenshot <a target="_blank" href="screenshot.png"><img src="screenshot.png" style="max-width:100%;"></a>, yes, this is a <b>screenshot</b> indeed.</p>', filter(doc).to_html
end
end
require 'test_helper'
MarkdownFilter = HTML::Pipeline::MarkdownFilter
class HTML::Pipeline::MarkdownFilterTest < Minitest::Test
def setup
@haiku =
"Pointing at the moon\n" \
"Reminded of simple things\n" \
'Moments matter most'
@links =
'See http://example.org/ for more info'
@code =
"```\n" \
'def hello()' \
" 'world'" \
'end' \
'```'
end
def test_fails_when_given_a_documentfragment
body = '<p>heyo</p>'
doc = HTML::Pipeline.parse(body)
assert_raises(TypeError) { MarkdownFilter.call(doc, {}) }
end
def test_gfm_enabled_by_default
doc = MarkdownFilter.to_document(@haiku, {})
assert doc.is_a?(HTML::Pipeline::DocumentFragment)
assert_equal 2, doc.search('br').size
end
def test_disabling_gfm
doc = MarkdownFilter.to_document(@haiku, gfm: false)
assert doc.is_a?(HTML::Pipeline::DocumentFragment)
assert_equal 0, doc.search('br').size
end
def test_fenced_code_blocks
doc = MarkdownFilter.to_document(@code)
assert doc.is_a?(HTML::Pipeline::DocumentFragment)
assert_equal 1, doc.search('pre').size
end
def test_fenced_code_blocks_with_language
doc = MarkdownFilter.to_document(@code.sub('```', '``` ruby'))
assert doc.is_a?(HTML::Pipeline::DocumentFragment)
assert_equal 1, doc.search('pre').size
assert_equal 'ruby', doc.search('pre').first['lang']
end
def test_standard_extensions
iframe = "<iframe src='http://www.google.com'></iframe>"
iframe_escaped = "&lt;iframe src='http://www.google.com'>&lt;/iframe>"
doc = MarkdownFilter.new(iframe).call
assert_equal(doc, iframe_escaped)
end
def test_changing_extensions
iframe = "<iframe src='http://www.google.com'></iframe>"
doc = MarkdownFilter.new(iframe, commonmarker_extensions: []).call
assert_equal(doc, iframe)
end
end
class GFMTest < Minitest::Test
def gfm(text)
MarkdownFilter.call(text, gfm: true)
end
def test_not_touch_single_underscores_inside_words
assert_equal '<p>foo_bar</p>',