2020-08-08 07:16:06 +05:30
|
|
|
# frozen_string_literal: true
|
|
|
|
|
2021-07-28 13:20:12 -04:00
|
|
|
require "livecheck/strategy"
|
2020-08-08 07:16:06 +05:30
|
|
|
|
2024-02-18 15:11:11 -08:00
|
|
|
RSpec.describe Homebrew::Livecheck::Strategy::Pypi do
|
2020-08-08 07:16:06 +05:30
|
|
|
subject(:pypi) { described_class }
|
|
|
|
|
2024-05-03 10:21:03 -04:00
|
|
|
let(:pypi_url) { "https://files.pythonhosted.org/packages/ab/cd/efg/example-package-1.2.3.tar.gz" }
|
2020-08-08 07:16:06 +05:30
|
|
|
let(:non_pypi_url) { "https://brew.sh/test" }
|
|
|
|
|
2024-12-08 12:47:50 -05:00
|
|
|
let(:regex) { /^v?(\d+(?:\.\d+)+)/i }
|
2024-12-07 20:42:46 -05:00
|
|
|
|
2023-03-08 23:14:46 +00:00
|
|
|
let(:generated) do
|
2021-07-28 13:20:12 -04:00
|
|
|
{
|
2024-12-07 10:56:46 -05:00
|
|
|
url: "https://pypi.org/pypi/example-package/json",
|
2021-07-28 13:20:12 -04:00
|
|
|
}
|
2023-03-08 23:14:46 +00:00
|
|
|
end
|
2021-07-28 13:20:12 -04:00
|
|
|
|
2024-12-07 20:42:46 -05:00
|
|
|
# This is a limited subset of a PyPI JSON API response object, for the sake
|
2024-12-08 12:47:50 -05:00
|
|
|
# of testing. Typical versions use a `1.2.3` format but this adds a suffix,
|
|
|
|
# so we can test regex matching.
|
2024-12-07 20:42:46 -05:00
|
|
|
let(:content) do
|
|
|
|
<<~JSON
|
|
|
|
{
|
|
|
|
"info": {
|
2024-12-08 12:47:50 -05:00
|
|
|
"version": "1.2.3-456"
|
2024-12-07 20:42:46 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
JSON
|
|
|
|
end
|
|
|
|
|
2024-12-08 12:47:50 -05:00
|
|
|
let(:matches) { ["1.2.3-456"] }
|
2024-12-07 20:42:46 -05:00
|
|
|
|
|
|
|
let(:find_versions_return_hash) do
|
|
|
|
{
|
|
|
|
matches: {
|
2024-12-08 12:47:50 -05:00
|
|
|
"1.2.3-456" => Version.new("1.2.3-456"),
|
2024-12-07 20:42:46 -05:00
|
|
|
},
|
2024-12-08 12:47:50 -05:00
|
|
|
regex:,
|
2024-12-07 20:42:46 -05:00
|
|
|
url: generated[:url],
|
|
|
|
}
|
|
|
|
end
|
|
|
|
|
|
|
|
let(:find_versions_cached_return_hash) do
|
|
|
|
find_versions_return_hash.merge({ cached: true })
|
|
|
|
end
|
|
|
|
|
2020-08-08 07:16:06 +05:30
|
|
|
describe "::match?" do
|
2021-08-10 17:39:11 -04:00
|
|
|
it "returns true for a PyPI URL" do
|
2020-08-08 07:16:06 +05:30
|
|
|
expect(pypi.match?(pypi_url)).to be true
|
|
|
|
end
|
|
|
|
|
2021-08-10 17:39:11 -04:00
|
|
|
it "returns false for a non-PyPI URL" do
|
2020-08-08 07:16:06 +05:30
|
|
|
expect(pypi.match?(non_pypi_url)).to be false
|
|
|
|
end
|
|
|
|
end
|
2021-07-28 13:20:12 -04:00
|
|
|
|
|
|
|
describe "::generate_input_values" do
|
|
|
|
it "returns a hash containing url and regex for an PyPI URL" do
|
|
|
|
expect(pypi.generate_input_values(pypi_url)).to eq(generated)
|
|
|
|
end
|
|
|
|
|
|
|
|
it "returns an empty hash for a non-PyPI URL" do
|
|
|
|
expect(pypi.generate_input_values(non_pypi_url)).to eq({})
|
|
|
|
end
|
|
|
|
end
|
2024-12-07 20:42:46 -05:00
|
|
|
|
|
|
|
describe "::find_versions" do
|
|
|
|
let(:match_data) do
|
|
|
|
cached = {
|
|
|
|
matches: matches.to_h { |v| [v, Version.new(v)] },
|
|
|
|
regex: nil,
|
|
|
|
url: generated[:url],
|
|
|
|
cached: true,
|
|
|
|
}
|
|
|
|
|
|
|
|
{
|
|
|
|
cached:,
|
|
|
|
cached_default: cached.merge({ matches: {} }),
|
2024-12-08 12:47:50 -05:00
|
|
|
cached_regex: cached.merge({
|
|
|
|
matches: { "1.2.3" => Version.new("1.2.3") },
|
|
|
|
regex:,
|
|
|
|
}),
|
2024-12-07 20:42:46 -05:00
|
|
|
}
|
|
|
|
end
|
|
|
|
|
|
|
|
it "finds versions in provided content" do
|
2024-12-08 12:47:50 -05:00
|
|
|
expect(pypi.find_versions(url: pypi_url, regex:, provided_content: content))
|
|
|
|
.to eq(match_data[:cached_regex])
|
|
|
|
|
2024-12-07 20:42:46 -05:00
|
|
|
expect(pypi.find_versions(url: pypi_url, provided_content: content))
|
|
|
|
.to eq(match_data[:cached])
|
|
|
|
end
|
|
|
|
|
|
|
|
it "finds versions in provided content using a block" do
|
|
|
|
# NOTE: We only use a regex here to make sure it can be passed into the
|
|
|
|
# block, if necessary.
|
|
|
|
expect(pypi.find_versions(url: pypi_url, regex:, provided_content: content) do |json, regex|
|
|
|
|
match = json.dig("info", "version")&.match(regex)
|
|
|
|
next if match.blank?
|
|
|
|
|
|
|
|
match[1]
|
2024-12-08 12:47:50 -05:00
|
|
|
end).to eq(match_data[:cached_regex])
|
2024-12-07 20:42:46 -05:00
|
|
|
|
|
|
|
expect(pypi.find_versions(url: pypi_url, provided_content: content) do |json|
|
|
|
|
json.dig("info", "version").presence
|
|
|
|
end).to eq(match_data[:cached])
|
|
|
|
end
|
|
|
|
|
|
|
|
it "returns default match_data when block doesn't return version information" do
|
2024-12-08 12:47:50 -05:00
|
|
|
no_match_regex = /will_not_match/i
|
|
|
|
|
2024-12-07 20:42:46 -05:00
|
|
|
expect(pypi.find_versions(url: pypi_url, provided_content: '{"info":{"version":""}}'))
|
|
|
|
.to eq(match_data[:cached_default])
|
|
|
|
expect(pypi.find_versions(url: pypi_url, provided_content: '{"other":true}'))
|
|
|
|
.to eq(match_data[:cached_default])
|
2024-12-08 12:47:50 -05:00
|
|
|
expect(pypi.find_versions(url: pypi_url, regex: no_match_regex, provided_content: content))
|
|
|
|
.to eq(match_data[:cached_default].merge({ regex: no_match_regex }))
|
2024-12-07 20:42:46 -05:00
|
|
|
end
|
|
|
|
|
|
|
|
it "returns default match_data when url is blank" do
|
|
|
|
expect(pypi.find_versions(url: "") { "1.2.3" })
|
|
|
|
.to eq({ matches: {}, regex: nil, url: "" })
|
|
|
|
end
|
|
|
|
|
|
|
|
it "returns default match_data when content is blank" do
|
|
|
|
expect(pypi.find_versions(url: pypi_url, provided_content: "{}") { "1.2.3" })
|
|
|
|
.to eq(match_data[:cached_default])
|
|
|
|
expect(pypi.find_versions(url: pypi_url, provided_content: "") { "1.2.3" })
|
|
|
|
.to eq(match_data[:cached_default])
|
|
|
|
end
|
|
|
|
end
|
2020-08-08 07:16:06 +05:30
|
|
|
end
|