discourse/spec/lib/version_spec.rb
David Taylor 00903f6b11
DEV: Support version operators in .discourse-compatibility (#22714)
This adds support for the `<=` and `<` version operators in `.discourse-compatibility` files. This allows for more flexibility (e.g. targeting the entire 3.1.x stable release via `< 3.2.0.beta1`), and should also make compatibility files to be more readable.

If an operator is not specified we default to `<=`, which matches the old behavior.
2023-07-25 14:04:39 +01:00

182 lines
6.6 KiB
Ruby

# frozen_string_literal: true
require "version"
RSpec.describe Discourse::VERSION do
describe ".has_needed_version?" do
it "works for major comparisons" do
expect(Discourse.has_needed_version?("1.0.0", "1.0.0")).to eq(true)
expect(Discourse.has_needed_version?("2.0.0", "1.0.0")).to eq(true)
expect(Discourse.has_needed_version?("0.0.1", "1.0.0")).to eq(false)
end
it "works for minor comparisons" do
expect(Discourse.has_needed_version?("1.1.0", "1.1.0")).to eq(true)
expect(Discourse.has_needed_version?("1.2.0", "1.1.0")).to eq(true)
expect(Discourse.has_needed_version?("2.0.0", "1.1.0")).to eq(true)
expect(Discourse.has_needed_version?("0.1.0", "0.1.0")).to eq(true)
expect(Discourse.has_needed_version?("1.0.0", "1.1.0")).to eq(false)
expect(Discourse.has_needed_version?("0.0.1", "0.1.0")).to eq(false)
end
it "works for tiny comparisons" do
expect(Discourse.has_needed_version?("2.0.0", "2.0.0")).to eq(true)
expect(Discourse.has_needed_version?("2.0.1", "2.0.0")).to eq(true)
expect(Discourse.has_needed_version?("1.12.0", "2.0.0")).to eq(false)
expect(Discourse.has_needed_version?("1.12.0", "2.12.5")).to eq(false)
end
it "works for beta comparisons when current_version is beta" do
expect(Discourse.has_needed_version?("1.3.0.beta3", "1.2.9")).to eq(true)
expect(Discourse.has_needed_version?("1.3.0.beta3", "1.3.0.beta1")).to eq(true)
expect(Discourse.has_needed_version?("1.3.0.beta3", "1.3.0.beta4")).to eq(false)
expect(Discourse.has_needed_version?("1.3.0.beta3", "1.3.0")).to eq(false)
end
it "works for beta comparisons when needed_version is beta" do
expect(Discourse.has_needed_version?("1.2.0", "1.3.0.beta3")).to eq(false)
expect(Discourse.has_needed_version?("1.2.9", "1.3.0.beta3")).to eq(false)
expect(Discourse.has_needed_version?("1.3.0.beta1", "1.3.0.beta3")).to eq(false)
expect(Discourse.has_needed_version?("1.3.0.beta4", "1.3.0.beta3")).to eq(true)
expect(Discourse.has_needed_version?("1.3.0", "1.3.0.beta3")).to eq(true)
end
end
describe ".find_compatible_resource" do
shared_examples "test compatible resource" do
it "returns nil when the current version is above all pinned versions" do
expect(Discourse.find_compatible_resource(version_list, "2.6.0")).to be_nil
end
it "returns the correct version if matches exactly" do
expect(Discourse.find_compatible_resource(version_list, "2.5.0.beta4")).to eq(
"twofivebetafour",
)
end
it "returns the closest matching version" do
expect(Discourse.find_compatible_resource(version_list, "2.4.6.beta12")).to eq(
"twofivebetatwo",
)
end
it "returns the lowest version possible when using an older version" do
expect(Discourse.find_compatible_resource(version_list, "1.4.6.beta12")).to eq(
"twofourtwobetaone",
)
end
end
it "returns nil when nil" do
expect(Discourse.find_compatible_resource(nil)).to be_nil
end
it "returns nil when empty" do
expect(Discourse.find_compatible_resource("")).to be_nil
end
it "raises an error on invalid input" do
expect { Discourse.find_compatible_resource("1.0.0.beta1 12f82d5") }.to raise_error(
Discourse::InvalidVersionListError,
)
end
context "with a regular compatible list" do
let(:version_list) { <<~YML }
2.5.0.beta6: twofivebetasix
2.5.0.beta4: twofivebetafour
2.5.0.beta2: twofivebetatwo
2.4.4.beta6: twofourfourbetasix
2.4.2.beta1: twofourtwobetaone
YML
include_examples "test compatible resource"
end
context "when handling a compatible resource out of order" do
let(:version_list) { <<~YML }
2.4.2.beta1: twofourtwobetaone
2.5.0.beta4: twofivebetafour
2.5.0.beta6: twofivebetasix
2.5.0.beta2: twofivebetatwo
2.4.4.beta6: twofourfourbetasix
YML
include_examples "test compatible resource"
end
context "with different version operators" do
let(:version_list) { <<~YML }
<= 3.2.0.beta1: lteBeta1
3.2.0.beta2: lteBeta2
< 3.2.0.beta4: ltBeta4
<= 3.2.0.beta4: lteBeta4
YML
it "supports <= operator" do
expect(Discourse.find_compatible_resource(version_list, "3.2.0.beta1")).to eq("lteBeta1")
expect(Discourse.find_compatible_resource(version_list, "3.2.0.beta0")).to eq("lteBeta1")
end
it "defaults to <= operator" do
expect(Discourse.find_compatible_resource(version_list, "3.2.0.beta2")).to eq("lteBeta2")
end
it "supports < operator" do
expect(Discourse.find_compatible_resource(version_list, "3.2.0.beta3")).to eq("ltBeta4")
expect(Discourse.find_compatible_resource(version_list, "3.2.0.beta4")).not_to eq("ltBeta4")
end
it "prioritises <= over <, regardless of file order" do
expect(Discourse.find_compatible_resource(version_list, "3.2.0.beta3")).to eq("ltBeta4")
expect(
Discourse.find_compatible_resource(version_list.lines.reverse.join("\n"), "3.2.0.beta3"),
).to eq("ltBeta4")
end
it "raises error for >= operator" do
expect { Discourse.find_compatible_resource(">= 3.1.0: test", "3.1.0") }.to raise_error(
Discourse::InvalidVersionListError,
)
end
it "raises error for ~> operator" do
expect { Discourse.find_compatible_resource("~> 3.1.0: test", "3.1.0") }.to raise_error(
Discourse::InvalidVersionListError,
)
end
it "raises error for invalid version" do
expect { Discourse.find_compatible_resource("1.1.: test", "3.1.0") }.to raise_error(
Discourse::InvalidVersionListError,
)
end
end
end
describe ".find_compatible_git_resource" do
let!(:git_directory) do
path = nil
capture_stdout do
# Note the lack of colon between version and hash
path = setup_git_repo(".discourse-compatibility" => "1.0.0.beta1 12f82d5")
# Simulate a remote upstream
`cd #{path} && git remote add origin #{path}/.git && git fetch -q`
`cd #{path} && git branch -u origin/$(git rev-parse --abbrev-ref HEAD)`
end
path
end
after { FileUtils.remove_entry(git_directory) }
it "gracefully handles invalid input" do
output =
capture_stderr { expect(Discourse.find_compatible_git_resource(git_directory)).to be_nil }
expect(output).to include("Invalid version list")
end
end
end