diff --git a/lib/semantic_range.rb b/lib/semantic_range.rb index fbac4da..0202798 100644 --- a/lib/semantic_range.rb +++ b/lib/semantic_range.rb @@ -4,44 +4,46 @@ require "semantic_range/comparator" module SemanticRange - BUILDIDENTIFIER = /[0-9A-Za-z-]+/ - BUILD = /(?:\+(#{BUILDIDENTIFIER.source}(?:\.#{BUILDIDENTIFIER.source})*))/ - NUMERICIDENTIFIER = /0|[1-9]\d*/ - NUMERICIDENTIFIERLOOSE = /[0-9]+/ - NONNUMERICIDENTIFIER = /\d*[a-zA-Z-][a-zA-Z0-9-]*/ - XRANGEIDENTIFIERLOOSE = /#{NUMERICIDENTIFIERLOOSE.source}|x|X|\*/ - PRERELEASEIDENTIFIERLOOSE = /(?:#{NUMERICIDENTIFIERLOOSE.source}|#{NONNUMERICIDENTIFIER.source})/ - PRERELEASELOOSE = /(?:-?(#{PRERELEASEIDENTIFIERLOOSE.source}(?:\.#{PRERELEASEIDENTIFIERLOOSE.source})*))/ - XRANGEPLAINLOOSE = /[v=\s]*(#{XRANGEIDENTIFIERLOOSE.source})(?:\.(#{XRANGEIDENTIFIERLOOSE.source})(?:\.(#{XRANGEIDENTIFIERLOOSE.source})(?:#{PRERELEASELOOSE.source})?#{BUILD.source}?)?)?/ - HYPHENRANGELOOSE = /^\s*(#{XRANGEPLAINLOOSE.source})\s+-\s+(#{XRANGEPLAINLOOSE.source})\s*$/ - PRERELEASEIDENTIFIER = /(?:#{NUMERICIDENTIFIER.source}|#{NONNUMERICIDENTIFIER.source})/ - PRERELEASE = /(?:-(#{PRERELEASEIDENTIFIER.source}(?:\.#{PRERELEASEIDENTIFIER.source})*))/ - XRANGEIDENTIFIER = /#{NUMERICIDENTIFIER.source}|x|X|\*/ - XRANGEPLAIN = /[v=\s]*(#{XRANGEIDENTIFIER.source})(?:\.(#{XRANGEIDENTIFIER.source})(?:\.(#{XRANGEIDENTIFIER.source})(?:#{PRERELEASE.source})?#{BUILD.source}?)?)?/ - HYPHENRANGE = /^\s*(#{XRANGEPLAIN.source})\s+-\s+(#{XRANGEPLAIN.source})\s*$/ - MAINVERSIONLOOSE = /(#{NUMERICIDENTIFIERLOOSE.source})\.(#{NUMERICIDENTIFIERLOOSE.source})\.(#{NUMERICIDENTIFIERLOOSE.source})/ - LOOSEPLAIN = /[v=\s]*#{MAINVERSIONLOOSE.source}#{PRERELEASELOOSE.source}?#{BUILD.source}?/ - GTLT = /((?:<|>)?=?)/ - COMPARATORTRIM = /(\s*)#{GTLT.source}\s*(#{LOOSEPLAIN.source}|#{XRANGEPLAIN.source})/ - LONETILDE = /(?:~>?)/ - TILDETRIM = /(\s*)#{LONETILDE.source}\s+/ - LONECARET = /(?:\^)/ - CARETTRIM = /(\s*)#{LONECARET.source}\s+/ - STAR = /(<|>)?=?\s*\*/ - CARET = /^#{LONECARET.source}#{XRANGEPLAIN.source}$/ - CARETLOOSE = /^#{LONECARET.source}#{XRANGEPLAINLOOSE.source}$/ - MAINVERSION = /(#{NUMERICIDENTIFIER.source})\.(#{NUMERICIDENTIFIER.source})\.(#{NUMERICIDENTIFIER.source})/ - FULLPLAIN = /v?#{MAINVERSION.source}#{PRERELEASE.source}?#{BUILD.source}?/ - FULL = /^#{FULLPLAIN.source}$/ - LOOSE = /^#{LOOSEPLAIN.source}$/ - TILDE = /^#{LONETILDE.source}#{XRANGEPLAIN.source}$/ - TILDELOOSE = /^#{LONETILDE.source}#{XRANGEPLAINLOOSE.source}$/ - XRANGE = /^#{GTLT.source}\s*#{XRANGEPLAIN.source}$/ - XRANGELOOSE = /^#{GTLT.source}\s*#{XRANGEPLAINLOOSE.source}$/ - COMPARATOR = /^#{GTLT.source}\s*(#{FULLPLAIN.source})$|^$/ - COMPARATORLOOSE = /^#{GTLT.source}\s*(#{LOOSEPLAIN.source})$|^$/ - - ANY = {} + BUILDIDENTIFIER = /[0-9A-Za-z-]+/.freeze + BUILD = /(?:\+(#{BUILDIDENTIFIER.source}(?:\.#{BUILDIDENTIFIER.source})*))/.freeze + NUMERICIDENTIFIER = /0|[1-9]\d*/.freeze + NUMERICIDENTIFIERLOOSE = /[0-9]+/.freeze + NONNUMERICIDENTIFIER = /\d*[a-zA-Z-][a-zA-Z0-9-]*/.freeze + XRANGEIDENTIFIERLOOSE = /#{NUMERICIDENTIFIERLOOSE.source}|x|X|\*/.freeze + PRERELEASEIDENTIFIERLOOSE = /(?:#{NUMERICIDENTIFIERLOOSE.source}|#{NONNUMERICIDENTIFIER.source})/.freeze + PRERELEASELOOSE = /(?:-?(#{PRERELEASEIDENTIFIERLOOSE.source}(?:\.#{PRERELEASEIDENTIFIERLOOSE.source})*))/.freeze + XRANGEPLAINLOOSE = /[v=\s]*(#{XRANGEIDENTIFIERLOOSE.source})(?:\.(#{XRANGEIDENTIFIERLOOSE.source})(?:\.(#{XRANGEIDENTIFIERLOOSE.source})(?:#{PRERELEASELOOSE.source})?#{BUILD.source}?)?)?/.freeze + HYPHENRANGELOOSE = /^\s*(#{XRANGEPLAINLOOSE.source})\s+-\s+(#{XRANGEPLAINLOOSE.source})\s*$/.freeze + PRERELEASEIDENTIFIER = /(?:#{NUMERICIDENTIFIER.source}|#{NONNUMERICIDENTIFIER.source})/.freeze + PRERELEASE = /(?:-(#{PRERELEASEIDENTIFIER.source}(?:\.#{PRERELEASEIDENTIFIER.source})*))/.freeze + XRANGEIDENTIFIER = /#{NUMERICIDENTIFIER.source}|x|X|\*/.freeze + XRANGEPLAIN = /[v=\s]*(#{XRANGEIDENTIFIER.source})(?:\.(#{XRANGEIDENTIFIER.source})(?:\.(#{XRANGEIDENTIFIER.source})(?:#{PRERELEASE.source})?#{BUILD.source}?)?)?/.freeze + HYPHENRANGE = /^\s*(#{XRANGEPLAIN.source})\s+-\s+(#{XRANGEPLAIN.source})\s*$/.freeze + MAINVERSIONLOOSE = /(#{NUMERICIDENTIFIERLOOSE.source})\.(#{NUMERICIDENTIFIERLOOSE.source})\.(#{NUMERICIDENTIFIERLOOSE.source})/.freeze + LOOSEPLAIN = /[v=\s]*#{MAINVERSIONLOOSE.source}#{PRERELEASELOOSE.source}?#{BUILD.source}?/.freeze + GTLT = /((?:<|>)?=?)/.freeze + COMPARATORTRIM = /(\s*)#{GTLT.source}\s*(#{LOOSEPLAIN.source}|#{XRANGEPLAIN.source})/.freeze + LONETILDE = /(?:~>?)/.freeze + TILDETRIM = /(\s*)#{LONETILDE.source}\s+/.freeze + LONECARET = /(?:\^)/.freeze + CARETTRIM = /(\s*)#{LONECARET.source}\s+/.freeze + STAR = /(<|>)?=?\s*\*/.freeze + CARET = /^#{LONECARET.source}#{XRANGEPLAIN.source}$/.freeze + CARETLOOSE = /^#{LONECARET.source}#{XRANGEPLAINLOOSE.source}$/.freeze + MAINVERSION = /(#{NUMERICIDENTIFIER.source})\.(#{NUMERICIDENTIFIER.source})\.(#{NUMERICIDENTIFIER.source})/.freeze + FULLPLAIN = /v?#{MAINVERSION.source}#{PRERELEASE.source}?#{BUILD.source}?/.freeze + FULL = /^#{FULLPLAIN.source}$/.freeze + LOOSE = /^#{LOOSEPLAIN.source}$/.freeze + TILDE = /^#{LONETILDE.source}#{XRANGEPLAIN.source}$/.freeze + TILDELOOSE = /^#{LONETILDE.source}#{XRANGEPLAINLOOSE.source}$/.freeze + XRANGE = /^#{GTLT.source}\s*#{XRANGEPLAIN.source}$/.freeze + XRANGELOOSE = /^#{GTLT.source}\s*#{XRANGEPLAINLOOSE.source}$/.freeze + COMPARATOR = /^#{GTLT.source}\s*(#{FULLPLAIN.source})$|^$/.freeze + COMPARATORLOOSE = /^#{GTLT.source}\s*(#{LOOSEPLAIN.source})$|^$/.freeze + GTE0 = /^\s*>=\s*0\.0\.0\s*$/.freeze + GTE0PRE = /^\s*>=\s*0\.0\.0-0\s*$/.freeze + + ANY = {}.freeze MAX_LENGTH = 256 @@ -50,12 +52,12 @@ class InvalidVersion < StandardError; end class InvalidComparator < StandardError; end class InvalidRange < StandardError; end - def self.ltr?(version, range, loose: false, platform: nil) - outside?(version, range, '<', loose: loose, platform: platform) + def self.ltr?(version, range, loose: false, platform: nil, include_prerelease: false) + outside?(version, range, '<', loose: loose, platform: platform, include_prerelease: include_prerelease) end - def self.gtr?(version, range, loose: false, platform: nil) - outside?(version, range, '>', loose: loose, platform: platform) + def self.gtr?(version, range, loose: false, platform: nil, include_prerelease: false) + outside?(version, range, '>', loose: loose, platform: platform, include_prerelease: include_prerelease) end def self.cmp(a, op, b, loose: false) @@ -85,11 +87,11 @@ def self.cmp(a, op, b, loose: false) end end - def self.outside?(version, range, hilo, loose: false, platform: nil) + def self.outside?(version, range, hilo, loose: false, platform: nil, include_prerelease: false) version = Version.new(version, loose: loose) - range = Range.new(range, loose: loose, platform: platform) + range = Range.new(range, loose: loose, platform: platform, include_prerelease: include_prerelease) - return false if satisfies?(version, range, loose: loose, platform: platform) + return false if satisfies?(version, range, loose: loose, platform: platform, include_prerelease: include_prerelease) case hilo when '>' @@ -148,28 +150,28 @@ def self.outside?(version, range, hilo, loose: false, platform: nil) true end - def self.satisfies?(version, range, loose: false, platform: nil) + def self.satisfies?(version, range, loose: false, platform: nil, include_prerelease: false) return false if !valid_range(range, loose: loose, platform: platform) - Range.new(range, loose: loose, platform: platform).test(version) + Range.new(range, loose: loose, platform: platform, include_prerelease: include_prerelease).test(version) end - def self.filter(versions, range, loose: false, platform: nil) - return [] if !valid_range(range, loose: loose, platform: platform) + def self.filter(versions, range, loose: false, platform: nil, include_prerelease: false) + return [] if !valid_range(range, loose: loose, platform: platform, include_prerelease: include_prerelease) - versions.filter { |v| SemanticRange.satisfies?(v, range, loose: loose, platform: platform) } + versions.filter { |v| SemanticRange.satisfies?(v, range, loose: loose, platform: platform, include_prerelease: include_prerelease) } end - def self.max_satisfying(versions, range, loose: false, platform: nil) + def self.max_satisfying(versions, range, loose: false, platform: nil, include_prerelease: false) versions.select { |version| - satisfies?(version, range, loose: loose, platform: platform) + satisfies?(version, range, loose: loose, platform: platform, include_prerelease: include_prerelease) }.sort { |a, b| rcompare(a, b, loose: loose) }[0] || nil end - def self.valid_range(range, loose: false, platform: nil) + def self.valid_range(range, loose: false, platform: nil, include_prerelease: false) begin - r = Range.new(range, loose: loose, platform: platform).range + r = Range.new(range, loose: loose, platform: platform, include_prerelease: include_prerelease).range r = '*' if r.nil? || r.empty? r rescue @@ -263,8 +265,8 @@ def self.diff(a, b) return "prerelease" if pre_diff end - def self.to_comparators(range, loose: false, platform: nil) - Range.new(range, loose: loose, platform: platform).set.map do |comp| + def self.to_comparators(range, loose: false, platform: nil, include_prerelease: false) + Range.new(range, loose: loose, platform: platform, include_prerelease: include_prerelease).set.map do |comp| comp.map(&:to_s) end end diff --git a/lib/semantic_range/range.rb b/lib/semantic_range/range.rb index b5c5ac4..c343801 100644 --- a/lib/semantic_range/range.rb +++ b/lib/semantic_range/range.rb @@ -2,11 +2,12 @@ module SemanticRange class Range attr_reader :loose, :raw, :range, :set, :platform - def initialize(range, loose: false, platform: nil) + def initialize(range, loose: false, platform: nil, include_prerelease: false) range = range.raw if range.is_a?(Range) @platform = platform @raw = range @loose = loose + @include_prerelease = include_prerelease split = range.split(/\s*\|\|\s*/) split = ['', ''] if range == '||' split = [''] if split == [] @@ -19,6 +20,21 @@ def initialize(range, loose: false, platform: nil) raise InvalidRange.new(range) if @set.empty? || @set == [[]] + if @set.any? + first = set.first + @set = @set.reject { |c| is_null_set(c[0]) } + if @set.empty? + @set = [first] + elsif @set.any? + @set.each do |c| + if c.length == 1 && is_any(c[0]) + @set = [c] + break + end + end + end + end + format end @@ -29,15 +45,25 @@ def format @range end + def is_null_set(comparator) + comparator.value == '<0.0.0-0' + end + + def is_any(comparator) + comparator.value == '' + end + def test(version) return false if !version version = Version.new(version, loose: @loose) if version.is_a?(String) @set.any?{|s| test_set(s, version) } + rescue SemanticRange::InvalidVersion + false end def test_set(set, version) return false if set.any? {|comp| !comp.test(version) } - if version.prerelease.length > 0 + if version.prerelease.length > 0 && !@include_prerelease set.each do |comp| next if comp.semver == ANY @@ -53,7 +79,8 @@ def test_set(set, version) def parse_range(range) # expand hyphens - range = range.gsub(@loose ? HYPHENRANGELOOSE : HYPHENRANGE){ hyphen_replace(Regexp.last_match) } + hyphen_range_regex = @loose ? HYPHENRANGELOOSE : HYPHENRANGE + range = range.gsub(hyphen_range_regex){ hyphen_replace(Regexp.last_match) } # comparator trim range = range.gsub(COMPARATORTRIM, '\1\2\3') @@ -71,34 +98,53 @@ def parse_range(range) range = range.split(/\s+/).join(' ') set = range.split(' ').map do |comp| - parse_comparator(comp, @loose) + parse_comparator(comp) end.join(' ').split(/\s+/) + set.map! { |comp| replaceGTE0(comp) } set = [''] if set == [] - set = set.select{|comp| !!comp.match(COMPARATORLOOSE) } if @loose + set = set.select{|comp| comp.match(COMPARATORLOOSE) } if @loose - set.map{|comp| Comparator.new(comp, @loose) } + set.map! {|comp| Comparator.new(comp, @loose) } + + rangeMap = {} + set.each do |comp| + if is_null_set(comp) + return [comp] + end + rangeMap[comp.value] = comp + end + if rangeMap.size > 1 && rangeMap.has_key?('') + rangeMap.delete('') + end + rangeMap.values end def isX(id) !id || id.downcase == 'x' || id == '*' end - def parse_comparator(comp, loose) - comp = replace_carets(comp, loose) - comp = replace_tildes(comp, loose) - comp = replace_x_ranges(comp, loose) - replace_stars(comp, loose) + def replaceGTE0(comp) + comp.strip.gsub(@include_prerelease ? GTE0PRE : GTE0, '') + end + + def parse_comparator(comp) + comp = replace_carets(comp) + comp = replace_tildes(comp) + comp = replace_x_ranges(comp) + replace_stars(comp) end - def replace_carets(comp, loose) + def replace_carets(comp) comp.strip.split(/\s+/).map do |comp| - replace_caret(comp, loose) + replace_caret(comp) end.join(' ') end - def replace_caret(comp, loose) - comp.gsub(loose ? CARETLOOSE : CARET) do + def replace_caret(comp) + z = @include_prerelease ? '-0' : '' + comp.gsub(@loose ? CARETLOOSE : CARET) do + match = Regexp.last_match mj = match[1] m = match[2] @@ -108,48 +154,45 @@ def replace_caret(comp, loose) if isX(mj) '' elsif isX(m) - ">=#{mj}.0.0 <#{(mj.to_i + 1)}.0.0" + ">=#{mj}.0.0#{z} <#{(mj.to_i + 1)}.0.0-0" elsif isX(p) if mj == '0' - ">=#{mj}.#{m}.0 <#{mj}.#{(m.to_i + 1)}.0" + ">=#{mj}.#{m}.0#{z} <#{mj}.#{(m.to_i + 1)}.0-0" else - ">=#{mj}.#{m}.0 <#{(mj.to_i + 1)}.0.0" + ">=#{mj}.#{m}.0#{z} <#{(mj.to_i + 1)}.0.0-0" end elsif pr - if pr[0] != '-' - pr = "-#{pr}" - end if mj == '0' if m == '0' - ">=#{mj}.#{m}.#{p}#{pr} <#{mj}.#{m}.#{(p.to_i + 1)}" + ">=#{mj}.#{m}.#{p}-#{pr} <#{mj}.#{m}.#{(p.to_i + 1)}-0" else - ">=#{mj}.#{m}.#{p}#{pr} <#{mj}.#{(m.to_i + 1)}.0" + ">=#{mj}.#{m}.#{p}-#{pr} <#{mj}.#{(m.to_i + 1)}.0-0" end else - ">=#{mj}.#{m}.#{p}#{pr} <#{(mj.to_i + 1)}.0.0" + ">=#{mj}.#{m}.#{p}-#{pr} <#{(mj.to_i + 1)}.0.0-0" end else if mj == '0' if m == '0' - ">=#{mj}.#{m}.#{p} <#{mj}.#{m}.#{(p.to_i + 1)}" + ">=#{mj}.#{m}.#{p}#{z} <#{mj}.#{m}.#{(p.to_i + 1)}-0" else - ">=#{mj}.#{m}.#{p} <#{mj}.#{(m.to_i + 1)}.0" + ">=#{mj}.#{m}.#{p}#{z} <#{mj}.#{(m.to_i + 1)}.0-0" end else - ">=#{mj}.#{m}.#{p} <#{(mj.to_i + 1)}.0.0" + ">=#{mj}.#{m}.#{p} <#{(mj.to_i + 1)}.0.0-0" end end end end - def replace_tildes(comp, loose) + def replace_tildes(comp) comp.strip.split(/\s+/).map do |comp| - replace_tilde(comp, loose) + replace_tilde(comp) end.join(' ') end - def replace_tilde(comp, loose) - comp.gsub(loose ? TILDELOOSE : TILDE) do + def replace_tilde(comp) + comp.gsub(@loose ? TILDELOOSE : TILDE) do match = Regexp.last_match mj = match[1] m = match[2] @@ -159,39 +202,37 @@ def replace_tilde(comp, loose) if isX(mj) '' elsif isX(m) - ">=#{mj}.0.0 <#{(mj.to_i + 1)}.0.0" + ">=#{mj}.0.0 <#{(mj.to_i + 1)}.0.0-0" elsif isX(p) if ['Rubygems', 'Packagist'].include?(platform) ">=#{mj}.#{m}.0 <#{mj.to_i+1}.0.0" else - ">=#{mj}.#{m}.0 <#{mj}.#{(m.to_i + 1)}.0" + ">=#{mj}.#{m}.0 <#{mj}.#{(m.to_i + 1)}.0-0" end - elsif pr - pr = '-' + pr if (pr[0] != '-') - ">=#{mj}.#{m}.#{p}#{pr} <#{mj}.#{(m.to_i + 1)}.0" + pr = '-' + pr if pr[0] != '-' + ">=#{mj}.#{m}.#{p}#{pr} <#{mj}.#{(m.to_i + 1)}.0-0" else - ">=#{mj}.#{m}.#{p} <#{mj}.#{(m.to_i + 1)}.0" + ">=#{mj}.#{m}.#{p} <#{mj}.#{(m.to_i + 1)}.0-0" end end end - def replace_x_ranges(comp, loose) + def replace_x_ranges(comp) comp.strip.split(/\s+/).map do |comp| - replace_x_range(comp, loose) + replace_x_range(comp) end.join(' ') end - def replace_x_range(comp, loose) + def replace_x_range(comp) comp = comp.strip - comp.gsub(loose ? XRANGELOOSE : XRANGE) do + comp.gsub(@loose ? XRANGELOOSE : XRANGE) do match = Regexp.last_match ret = match[0] gtlt = match[1] mj = match[2] m = match[3] p = match[4] - pr = match[5] xM = isX(mj) xm = xM || isX(m) @@ -200,9 +241,11 @@ def replace_x_range(comp, loose) gtlt = '' if gtlt == '=' && anyX + pr = @include_prerelease ? '-0' : '' + if xM if gtlt == '>' || gtlt == '<' - '<0.0.0' + '<0.0.0-0' else '*' end @@ -229,18 +272,20 @@ def replace_x_range(comp, loose) end end - "#{gtlt}#{mj}.#{m}.#{p}" + pr = '-0' if gtlt == '<' + + "#{gtlt}#{mj}.#{m}.#{p}#{pr}" elsif xm - ">=#{mj}.0.0 <#{(mj.to_i + 1)}.0.0" + ">=#{mj}.0.0#{pr} <#{(mj.to_i + 1)}.0.0-0" elsif xp - ">=#{mj}.#{m}.0 <#{mj}.#{(m.to_i + 1)}.0" + ">=#{mj}.#{m}.0#{pr} <#{mj}.#{(m.to_i + 1)}.0-0" else ret end end end - def replace_stars(comp, loose) + def replace_stars(comp) comp.strip.gsub(STAR, '') end @@ -261,21 +306,25 @@ def hyphen_replace(match) if isX(fM) from = '' elsif isX(fm) - from = ">=#{fM}.0.0" + from = ">=#{fM}.0.0#{@include_prerelease ? '-0' : ''}" elsif isX(fp) - from = ">=#{fM}.#{fm}.0" - else + from = ">=#{fM}.#{fm}.0#{@include_prerelease ? '-0' : ''}" + elsif fpr from = ">=#{from}" + else + from = ">=#{from}#{@include_prerelease ? '-0' : ''}" end if isX(tM) to = '' elsif isX(tm) - to = "<#{(tM.to_i + 1)}.0.0" + to = "<#{(tM.to_i + 1)}.0.0-0" elsif isX(tp) - to = "<#{tM}.#{(tm.to_i + 1)}.0" + to = "<#{tM}.#{(tm.to_i + 1)}.0-0" elsif tpr to = "<=#{tM}.#{tm}.#{tp}-#{tpr}" + elsif @include_prerelease + to = "<#{tM}.#{tm}.#{tp.to_i + 1}-0" else to = "<=#{to}" end diff --git a/spec/rubygems_ranges_spec.rb b/spec/rubygems_ranges_spec.rb index fa0f268..07684e3 100644 --- a/spec/rubygems_ranges_spec.rb +++ b/spec/rubygems_ranges_spec.rb @@ -109,6 +109,17 @@ end end + it 'range with prerelease' do + [ + ['>=1 <3', '1.23.0-20210103.1434'] + ].each do |tuple| + range = tuple[0] + version = tuple[1] + loose = tuple[2] + expect(SemanticRange.satisfies?(version, range, loose: loose, include_prerelease: true)).to eq(true), "#{tuple}" + end + end + it 'negative range for rubygems/packagist' do [ ['1.0.0 - 2.0.0', '2.2.3'], @@ -195,14 +206,10 @@ ['>=*', '*'], ['', '*'], ['*', '*'], - ['*', '*'], ['>=1.0.0', '>=1.0.0'], ['>1.0.0', '>1.0.0'], ['<=2.0.0', '<=2.0.0'], - ['1', '>=1.0.0 <2.0.0'], - ['<=2.0.0', '<=2.0.0'], - ['<=2.0.0', '<=2.0.0'], - ['<2.0.0', '<2.0.0'], + ['1', '>=1.0.0 <2.0.0-0'], ['<2.0.0', '<2.0.0'], ['>= 1.0.0', '>=1.0.0'], ['>= 1.0.0', '>=1.0.0'], @@ -213,54 +220,48 @@ ['<= 2.0.0', '<=2.0.0'], ['<= 2.0.0', '<=2.0.0'], ['< 2.0.0', '<2.0.0'], - ['< 2.0.0', '<2.0.0'], - ['>=0.1.97', '>=0.1.97'], + ["<\t2.0.0", '<2.0.0'], ['>=0.1.97', '>=0.1.97'], ['0.1.20 || 1.2.4', '0.1.20||1.2.4'], ['>=0.2.3 || <0.0.1', '>=0.2.3||<0.0.1'], - ['>=0.2.3 || <0.0.1', '>=0.2.3||<0.0.1'], - ['>=0.2.3 || <0.0.1', '>=0.2.3||<0.0.1'], - ['||', '||'], - ['2.x.x', '>=2.0.0 <3.0.0'], - ['1.2.x', '>=1.2.0 <1.3.0'], - ['1.2.x || 2.x', '>=1.2.0 <1.3.0||>=2.0.0 <3.0.0'], - ['1.2.x || 2.x', '>=1.2.0 <1.3.0||>=2.0.0 <3.0.0'], + ['||', '*'], + ['2.x.x', '>=2.0.0 <3.0.0-0'], + ['1.2.x', '>=1.2.0 <1.3.0-0'], + ['1.2.x || 2.x', '>=1.2.0 <1.3.0-0||>=2.0.0 <3.0.0-0'], ['x', '*'], - ['2.*.*', '>=2.0.0 <3.0.0'], - ['1.2.*', '>=1.2.0 <1.3.0'], - ['1.2.* || 2.*', '>=1.2.0 <1.3.0||>=2.0.0 <3.0.0'], - ['*', '*'], - ['2', '>=2.0.0 <3.0.0'], - ['2.3', '>=2.3.0 <2.4.0'], + ['2.*.*', '>=2.0.0 <3.0.0-0'], + ['1.2.*', '>=1.2.0 <1.3.0-0'], + ['1.2.* || 2.*', '>=1.2.0 <1.3.0-0||>=2.0.0 <3.0.0-0'], + ['2', '>=2.0.0 <3.0.0-0'], + ['2.3', '>=2.3.0 <2.4.0-0'], ['~2.4', '>=2.4.0 <3.0.0'], - ['~>3.2.1', '>=3.2.1 <3.3.0'], - ['~1', '>=1.0.0 <2.0.0'], - ['~>1', '>=1.0.0 <2.0.0'], - ['~> 1', '>=1.0.0 <2.0.0'], + ['~>3.2.1', '>=3.2.1 <3.3.0-0'], + ['~1', '>=1.0.0 <2.0.0-0'], + ['~>1', '>=1.0.0 <2.0.0-0'], + ['~> 1', '>=1.0.0 <2.0.0-0'], ['~1.0', '>=1.0.0 <2.0.0'], ['~ 1.0', '>=1.0.0 <2.0.0'], - ['^0', '>=0.0.0 <1.0.0'], - ['^ 1', '>=1.0.0 <2.0.0'], - ['^0.1', '>=0.1.0 <0.2.0'], - ['^1.0', '>=1.0.0 <2.0.0'], - ['^1.2', '>=1.2.0 <2.0.0'], - ['^0.0.1', '>=0.0.1 <0.0.2'], - ['^0.0.1-beta', '>=0.0.1-beta <0.0.2'], - ['^0.1.2', '>=0.1.2 <0.2.0'], - ['^1.2.3', '>=1.2.3 <2.0.0'], - ['^1.2.3-beta.4', '>=1.2.3-beta.4 <2.0.0'], - ['<1', '<1.0.0'], - ['< 1', '<1.0.0'], + ['^0', '<1.0.0-0'], + ['^ 1', '>=1.0.0 <2.0.0-0'], + ['^0.1', '>=0.1.0 <0.2.0-0'], + ['^1.0', '>=1.0.0 <2.0.0-0'], + ['^1.2', '>=1.2.0 <2.0.0-0'], + ['^0.0.1', '>=0.0.1 <0.0.2-0'], + ['^0.0.1-beta', '>=0.0.1-beta <0.0.2-0'], + ['^0.1.2', '>=0.1.2 <0.2.0-0'], + ['^1.2.3', '>=1.2.3 <2.0.0-0'], + ['^1.2.3-beta.4', '>=1.2.3-beta.4 <2.0.0-0'], + ['<1', '<1.0.0-0'], + ['< 1', '<1.0.0-0'], ['>=1', '>=1.0.0'], ['>= 1', '>=1.0.0'], - ['<1.2', '<1.2.0'], - ['< 1.2', '<1.2.0'], - ['1', '>=1.0.0 <2.0.0'], + ['<1.2', '<1.2.0-0'], + ['< 1.2', '<1.2.0-0'], ['>01.02.03', '>1.2.3', true], ['>01.02.03', nil], - ['~1.2.3beta', '>=1.2.3-beta <1.3.0', true], + ['~1.2.3beta', '>=1.2.3-beta <1.3.0-0', true], ['~1.2.3beta', nil], - ['^ 1.2 ^ 1', '>=1.2.0 <2.0.0 >=1.0.0 <2.0.0'] + ['^ 1.2 ^ 1', '>=1.2.0 <2.0.0-0 >=1.0.0'] ].each do |tuple| pre = tuple[0] wanted = tuple[1] @@ -291,17 +292,10 @@ ['>=*', [['']]], ['', [['']]], ['*', [['']]], - ['*', [['']]], - ['>=1.0.0', [['>=1.0.0']]], ['>=1.0.0', [['>=1.0.0']]], - ['>=1.0.0', [['>=1.0.0']]], - ['>1.0.0', [['>1.0.0']]], ['>1.0.0', [['>1.0.0']]], ['<=2.0.0', [['<=2.0.0']]], - ['1', [['>=1.0.0', '<2.0.0']]], - ['<=2.0.0', [['<=2.0.0']]], - ['<=2.0.0', [['<=2.0.0']]], - ['<2.0.0', [['<2.0.0']]], + ['1', [['>=1.0.0', '<2.0.0-0']]], ['<2.0.0', [['<2.0.0']]], ['>= 1.0.0', [['>=1.0.0']]], ['>= 1.0.0', [['>=1.0.0']]], @@ -314,46 +308,40 @@ ['< 2.0.0', [['<2.0.0']]], ["<\t2.0.0", [['<2.0.0']]], ['>=0.1.97', [['>=0.1.97']]], - ['>=0.1.97', [['>=0.1.97']]], ['0.1.20 || 1.2.4', [['0.1.20'], ['1.2.4']]], ['>=0.2.3 || <0.0.1', [['>=0.2.3'], ['<0.0.1']]], - ['>=0.2.3 || <0.0.1', [['>=0.2.3'], ['<0.0.1']]], - ['>=0.2.3 || <0.0.1', [['>=0.2.3'], ['<0.0.1']]], - ['||', [[''], ['']]], - ['2.x.x', [['>=2.0.0', '<3.0.0']]], - ['1.2.x', [['>=1.2.0', '<1.3.0']]], - ['1.2.x || 2.x', [['>=1.2.0', '<1.3.0'], ['>=2.0.0', '<3.0.0']]], - ['1.2.x || 2.x', [['>=1.2.0', '<1.3.0'], ['>=2.0.0', '<3.0.0']]], + ['||', [['']]], + ['2.x.x', [['>=2.0.0', '<3.0.0-0']]], + ['1.2.x', [['>=1.2.0', '<1.3.0-0']]], + ['1.2.x || 2.x', [['>=1.2.0', '<1.3.0-0'], ['>=2.0.0', '<3.0.0-0']]], ['x', [['']]], - ['2.*.*', [['>=2.0.0', '<3.0.0']]], - ['1.2.*', [['>=1.2.0', '<1.3.0']]], - ['1.2.* || 2.*', [['>=1.2.0', '<1.3.0'], ['>=2.0.0', '<3.0.0']]], - ['1.2.* || 2.*', [['>=1.2.0', '<1.3.0'], ['>=2.0.0', '<3.0.0']]], - ['*', [['']]], - ['2', [['>=2.0.0', '<3.0.0']]], - ['2.3', [['>=2.3.0', '<2.4.0']]], + ['2.*.*', [['>=2.0.0', '<3.0.0-0']]], + ['1.2.*', [['>=1.2.0', '<1.3.0-0']]], + ['1.2.* || 2.*', [['>=1.2.0', '<1.3.0-0'], ['>=2.0.0', '<3.0.0-0']]], + ['2', [['>=2.0.0', '<3.0.0-0']]], + ['2.3', [['>=2.3.0', '<2.4.0-0']]], ['~2.4', [['>=2.4.0', '<3.0.0']]], - ['~>3.2.1', [['>=3.2.1', '<3.3.0']]], - ['~1', [['>=1.0.0', '<2.0.0']]], - ['~>1', [['>=1.0.0', '<2.0.0']]], - ['~> 1', [['>=1.0.0', '<2.0.0']]], + ['~>3.2.1', [['>=3.2.1', '<3.3.0-0']]], + ['~1', [['>=1.0.0', '<2.0.0-0']]], + ['~>1', [['>=1.0.0', '<2.0.0-0']]], + ['~> 1', [['>=1.0.0', '<2.0.0-0']]], ['~1.0', [['>=1.0.0', '<2.0.0']]], ['~ 1.0', [['>=1.0.0', '<2.0.0']]], - ['~ 1.0.3', [['>=1.0.3', '<1.1.0']]], - ['~> 1.0.3', [['>=1.0.3', '<1.1.0']]], - ['<1', [['<1.0.0']]], - ['< 1', [['<1.0.0']]], + ['~ 1.0.3', [['>=1.0.3', '<1.1.0-0']]], + ['~> 1.0.3', [['>=1.0.3', '<1.1.0-0']]], + ['<1', [['<1.0.0-0']]], + ['< 1', [['<1.0.0-0']]], ['>=1', [['>=1.0.0']]], ['>= 1', [['>=1.0.0']]], - ['<1.2', [['<1.2.0']]], - ['< 1.2', [['<1.2.0']]], - ['1', [['>=1.0.0', '<2.0.0']]], - ['1 2', [['>=1.0.0', '<2.0.0', '>=2.0.0', '<3.0.0']]], + ['<1.2', [['<1.2.0-0']]], + ['< 1.2', [['<1.2.0-0']]], + ['1', [['>=1.0.0', '<2.0.0-0']]], + ['1 2', [['>=1.0.0', '<2.0.0-0', '>=2.0.0', '<3.0.0-0']]], ['1.2 - 3.4.5', [['>=1.2.0', '<=3.4.5']]], - ['1.2.3 - 3.4', [['>=1.2.3', '<3.5.0']]], - ['1.2.3 - 3', [['>=1.2.3', '<4.0.0']]], - ['>*', [['<0.0.0']]], - ['<*', [['<0.0.0']]] + ['1.2.3 - 3.4', [['>=1.2.3', '<3.5.0-0']]], + ['1.2.3 - 3', [['>=1.2.3', '<4.0.0-0']]], + ['>*', [['<0.0.0-0']]], + ['<*', [['<0.0.0-0']]] ].each do |v| pre, wanted = v found = SemanticRange.to_comparators(pre, loose: false, platform: 'Rubygems') diff --git a/spec/semantic_range_gtr_spec.rb b/spec/semantic_range_gtr_spec.rb index d96ba4f..a08d1bb 100644 --- a/spec/semantic_range_gtr_spec.rb +++ b/spec/semantic_range_gtr_spec.rb @@ -2,7 +2,7 @@ describe SemanticRange do it 'gtr' do - # [version, range, loose] + # [version, range, options] # Version should be greater than range expect(SemanticRange.gtr?('1.3.0', '~1.2.2')).to eq(true) expect(SemanticRange.gtr?('0.7.1-1', '~0.6.1-1')).to eq(true) @@ -70,10 +70,11 @@ expect(SemanticRange.gtr?('1.0.0beta', '< 1', loose: true)).to eq(true) expect(SemanticRange.gtr?('0.8.2', '=0.7.x')).to eq(true) expect(SemanticRange.gtr?('0.7.2', '<0.7.x')).to eq(true) + expect(SemanticRange.gtr?('0.7.2-beta', '<0.7.x')).to eq(true) end it 'negative gtr' do - # [version, range, loose] + # [version, range, options] # Version should NOT be greater than range expect(SemanticRange.gtr?('0.6.1-1', '~0.6.1-1')).to eq(false) expect(SemanticRange.gtr?('1.2.3', '1.0.0 - 2.0.0')).to eq(false) @@ -156,5 +157,6 @@ expect(SemanticRange.gtr?('1.0.0beta', '^0.1.0 || ~3.0.1 || 5.0.0', loose: true)).to eq(false) expect(SemanticRange.gtr?('5.0.0-0', '^0.1.0 || ~3.0.1 || 5.0.0', loose: true)).to eq(false) expect(SemanticRange.gtr?('3.5.0', '^0.1.0 || ~3.0.1 || >4 <=5.0.0')).to eq(false) + expect(SemanticRange.gtr?('0.7.2-beta', '0.7.x', include_prerelease: true)).to eq(false) end end diff --git a/spec/semantic_range_ltr_spec.rb b/spec/semantic_range_ltr_spec.rb index 0b17c8e..8a30eaa 100644 --- a/spec/semantic_range_ltr_spec.rb +++ b/spec/semantic_range_ltr_spec.rb @@ -74,92 +74,98 @@ end it 'negative ltr' do - # [version, range, loose] + # [version, range, options] # Version should NOT be less than range - expect(SemanticRange.ltr?('1.2.4', '1.2.4')).to eq(false) - expect(SemanticRange.ltr?('1.1.0', '~ 1.0')).to eq(false) - expect(SemanticRange.ltr?('0.6.1-1', '~0.6.1-1')).to eq(false) - expect(SemanticRange.ltr?('1.2.3', '1.0.0 - 2.0.0')).to eq(false) - expect(SemanticRange.ltr?('2.9.9', '1.0.0 - 2.0.0')).to eq(false) - expect(SemanticRange.ltr?('1.0.0', '1.0.0')).to eq(false) - expect(SemanticRange.ltr?('0.2.4', '>=*')).to eq(false) - expect(SemanticRange.ltr?('1.0.0', '', loose: true)).to eq(false) - expect(SemanticRange.ltr?('1.2.3', '*')).to eq(false) - expect(SemanticRange.ltr?('1.0.0', '>=1.0.0')).to eq(false) - expect(SemanticRange.ltr?('1.0.1', '>=1.0.0')).to eq(false) - expect(SemanticRange.ltr?('1.1.0', '>=1.0.0')).to eq(false) - expect(SemanticRange.ltr?('1.0.1', '>1.0.0')).to eq(false) - expect(SemanticRange.ltr?('1.1.0', '>1.0.0')).to eq(false) - expect(SemanticRange.ltr?('2.0.0', '<=2.0.0')).to eq(false) - expect(SemanticRange.ltr?('1.9999.9999', '<=2.0.0')).to eq(false) - expect(SemanticRange.ltr?('0.2.9', '<=2.0.0')).to eq(false) - expect(SemanticRange.ltr?('1.9999.9999', '<2.0.0')).to eq(false) - expect(SemanticRange.ltr?('0.2.9', '<2.0.0')).to eq(false) - expect(SemanticRange.ltr?('1.0.0', '>= 1.0.0')).to eq(false) - expect(SemanticRange.ltr?('1.0.1', '>= 1.0.0')).to eq(false) - expect(SemanticRange.ltr?('1.1.0', '>= 1.0.0')).to eq(false) - expect(SemanticRange.ltr?('1.0.1', '> 1.0.0')).to eq(false) - expect(SemanticRange.ltr?('1.1.0', '> 1.0.0')).to eq(false) - expect(SemanticRange.ltr?('2.0.0', '<= 2.0.0')).to eq(false) - expect(SemanticRange.ltr?('1.9999.9999', '<= 2.0.0')).to eq(false) - expect(SemanticRange.ltr?('0.2.9', '<= 2.0.0')).to eq(false) - expect(SemanticRange.ltr?('1.9999.9999', '< 2.0.0')).to eq(false) - expect(SemanticRange.ltr?('0.2.9', "<\t2.0.0")).to eq(false) - expect(SemanticRange.ltr?('v0.1.97', '>=0.1.97')).to eq(false) - expect(SemanticRange.ltr?('0.1.97', '>=0.1.97')).to eq(false) - expect(SemanticRange.ltr?('1.2.4', '0.1.20 || 1.2.4')).to eq(false) - expect(SemanticRange.ltr?('1.2.4', '0.1.20 || >1.2.4')).to eq(false) - expect(SemanticRange.ltr?('1.2.3', '0.1.20 || 1.2.4')).to eq(false) - expect(SemanticRange.ltr?('0.1.20', '0.1.20 || 1.2.4')).to eq(false) - expect(SemanticRange.ltr?('0.0.0', '>=0.2.3 || <0.0.1')).to eq(false) - expect(SemanticRange.ltr?('0.2.3', '>=0.2.3 || <0.0.1')).to eq(false) - expect(SemanticRange.ltr?('0.2.4', '>=0.2.3 || <0.0.1')).to eq(false) - expect(SemanticRange.ltr?('1.3.4', '||')).to eq(false) - expect(SemanticRange.ltr?('2.1.3', '2.x.x')).to eq(false) - expect(SemanticRange.ltr?('1.2.3', '1.2.x')).to eq(false) - expect(SemanticRange.ltr?('2.1.3', '1.2.x || 2.x')).to eq(false) - expect(SemanticRange.ltr?('1.2.3', '1.2.x || 2.x')).to eq(false) - expect(SemanticRange.ltr?('1.2.3', 'x')).to eq(false) - expect(SemanticRange.ltr?('2.1.3', '2.*.*')).to eq(false) - expect(SemanticRange.ltr?('1.2.3', '1.2.*')).to eq(false) - expect(SemanticRange.ltr?('2.1.3', '1.2.* || 2.*')).to eq(false) - expect(SemanticRange.ltr?('1.2.3', '1.2.* || 2.*')).to eq(false) - expect(SemanticRange.ltr?('1.2.3', '1.2.* || 2.*')).to eq(false) - expect(SemanticRange.ltr?('1.2.3', '*')).to eq(false) - expect(SemanticRange.ltr?('2.1.2', '2')).to eq(false) - expect(SemanticRange.ltr?('2.3.1', '2.3')).to eq(false) - expect(SemanticRange.ltr?('2.4.0', '~2.4')).to eq(false) # >=2.4.0 <2.5.)) - expect(SemanticRange.ltr?('2.4.5', '~2.4')).to eq(false) - expect(SemanticRange.ltr?('3.2.2', '~>3.2.1')).to eq(false) # >=3.2.1 <3.3.)) - expect(SemanticRange.ltr?('1.2.3', '~1')).to eq(false) # >=1.0.0 <2.0.)) - expect(SemanticRange.ltr?('1.2.3', '~>1')).to eq(false) - expect(SemanticRange.ltr?('1.2.3', '~> 1')).to eq(false) - expect(SemanticRange.ltr?('1.0.2', '~1.0')).to eq(false) # >=1.0.0 <1.1.)) - expect(SemanticRange.ltr?('1.0.2', '~ 1.0')).to eq(false) - expect(SemanticRange.ltr?('1.0.0', '>=1')).to eq(false) - expect(SemanticRange.ltr?('1.0.0', '>= 1')).to eq(false) - expect(SemanticRange.ltr?('1.1.1', '<1.2')).to eq(false) - expect(SemanticRange.ltr?('1.1.1', '< 1.2')).to eq(false) - expect(SemanticRange.ltr?('0.5.5', '~v0.5.4-pre')).to eq(false) - expect(SemanticRange.ltr?('0.5.4', '~v0.5.4-pre')).to eq(false) - expect(SemanticRange.ltr?('0.7.2', '=0.7.x')).to eq(false) - expect(SemanticRange.ltr?('0.7.2', '>=0.7.x')).to eq(false) - expect(SemanticRange.ltr?('0.6.2', '<=0.7.x')).to eq(false) - expect(SemanticRange.ltr?('0.2.5', '>0.2.3 >0.2.4 <=0.2.5')).to eq(false) - expect(SemanticRange.ltr?('0.2.4', '>=0.2.3 <=0.2.4')).to eq(false) - expect(SemanticRange.ltr?('2.0.0', '1.0.0 - 2.0.0')).to eq(false) - expect(SemanticRange.ltr?('4.0.0', '^3.0.0')).to eq(false) - expect(SemanticRange.ltr?('2.0.0', '^1.0.0 || ~2.0.1')).to eq(false) - expect(SemanticRange.ltr?('3.2.0', '^0.1.0 || ~3.0.1 || 5.0.0')).to eq(false) - expect(SemanticRange.ltr?('1.0.0beta', '^0.1.0 || ~3.0.1 || 5.0.0', loose: true)).to eq(false) - expect(SemanticRange.ltr?('5.0.0-0', '^0.1.0 || ~3.0.1 || 5.0.0', loose: true)).to eq(false) - expect(SemanticRange.ltr?('3.5.0', '^0.1.0 || ~3.0.1 || >4 <=5.0.0')).to eq(false) - expect(SemanticRange.ltr?('1.0.0beta', '^1.0.0alpha', loose: true)).to eq(false) - expect(SemanticRange.ltr?('1.0.0beta', '~1.0.0alpha', loose: true)).to eq(false) - expect(SemanticRange.ltr?('1.0.0beta', '^1.0.0-alpha', loose: true)).to eq(false) - expect(SemanticRange.ltr?('1.0.0beta', '~1.0.0-alpha', loose: true)).to eq(false) - expect(SemanticRange.ltr?('1.0.0-beta', '^1.0.0-alpha')).to eq(false) - expect(SemanticRange.ltr?('1.0.0-beta', '~1.0.0-alpha')).to eq(false) - expect(SemanticRange.ltr?('1.0.0', '=0.1.0')).to eq(false) + [['~ 1.0', '1.1.0'], + ['~0.6.1-1', '0.6.1-1'], + ['1.0.0 - 2.0.0', '1.2.3'], + ['1.0.0 - 2.0.0', '2.9.9'], + ['1.0.0', '1.0.0'], + ['>=*', '0.2.4'], + ['', '1.0.0', loose: true], + ['*', '1.2.3'], + ['>=1.0.0', '1.0.0'], + ['>=1.0.0', '1.0.1'], + ['>=1.0.0', '1.1.0'], + ['>1.0.0', '1.0.1'], + ['>1.0.0', '1.1.0'], + ['<=2.0.0', '2.0.0'], + ['<=2.0.0', '1.9999.9999'], + ['<=2.0.0', '0.2.9'], + ['<2.0.0', '1.9999.9999'], + ['<2.0.0', '0.2.9'], + ['>= 1.0.0', '1.0.0'], + ['>= 1.0.0', '1.0.1'], + ['>= 1.0.0', '1.1.0'], + ['> 1.0.0', '1.0.1'], + ['> 1.0.0', '1.1.0'], + ['<= 2.0.0', '2.0.0'], + ['<= 2.0.0', '1.9999.9999'], + ['<= 2.0.0', '0.2.9'], + ['< 2.0.0', '1.9999.9999'], + ["<\t2.0.0", '0.2.9'], + ['>=0.1.97', 'v0.1.97'], + ['>=0.1.97', '0.1.97'], + ['0.1.20 || 1.2.4', '1.2.4'], + ['0.1.20 || >1.2.4', '1.2.4'], + ['0.1.20 || 1.2.4', '1.2.3'], + ['0.1.20 || 1.2.4', '0.1.20'], + ['>=0.2.3 || <0.0.1', '0.0.0'], + ['>=0.2.3 || <0.0.1', '0.2.3'], + ['>=0.2.3 || <0.0.1', '0.2.4'], + ['||', '1.3.4'], + ['2.x.x', '2.1.3'], + ['1.2.x', '1.2.3'], + ['1.2.x || 2.x', '2.1.3'], + ['1.2.x || 2.x', '1.2.3'], + ['x', '1.2.3'], + ['2.*.*', '2.1.3'], + ['1.2.*', '1.2.3'], + ['1.2.* || 2.*', '2.1.3'], + ['1.2.* || 2.*', '1.2.3'], + ['1.2.* || 2.*', '1.2.3'], + ['*', '1.2.3'], + ['2', '2.1.2'], + ['2.3', '2.3.1'], + ['~2.4', '2.4.0'], # >=2.4.0 <2.5.0 + ['~2.4', '2.4.5'], + ['~>3.2.1', '3.2.2'], # >=3.2.1 <3.3.0 + ['~1', '1.2.3'], # >=1.0.0 <2.0.0 + ['~>1', '1.2.3'], + ['~> 1', '1.2.3'], + ['~1.0', '1.0.2'], # >=1.0.0 <1.1.0 + ['~ 1.0', '1.0.2'], + ['>=1', '1.0.0'], + ['>= 1', '1.0.0'], + ['<1.2', '1.1.1'], + ['< 1.2', '1.1.1'], + ['~v0.5.4-pre', '0.5.5'], + ['~v0.5.4-pre', '0.5.4'], + ['=0.7.x', '0.7.2'], + ['>=0.7.x', '0.7.2'], + ['<=0.7.x', '0.6.2'], + ['>0.2.3 >0.2.4 <=0.2.5', '0.2.5'], + ['>=0.2.3 <=0.2.4', '0.2.4'], + ['1.0.0 - 2.0.0', '2.0.0'], + ['^3.0.0', '4.0.0'], + ['^1.0.0 || ~2.0.1', '2.0.0'], + ['^0.1.0 || ~3.0.1 || 5.0.0', '3.2.0'], + ['^0.1.0 || ~3.0.1 || 5.0.0', '1.0.0beta', loose: true], + ['^0.1.0 || ~3.0.1 || 5.0.0', '5.0.0-0', loose: true], + ['^0.1.0 || ~3.0.1 || >4 <=5.0.0', '3.5.0'], + ['^1.0.0alpha', '1.0.0beta', loose: true], + ['~1.0.0alpha', '1.0.0beta', loose: true], + ['^1.0.0-alpha', '1.0.0beta', loose: true], + ['~1.0.0-alpha', '1.0.0beta', loose: true], + ['^1.0.0-alpha', '1.0.0-beta'], + ['~1.0.0-alpha', '1.0.0-beta'], + ['=0.1.0', '1.0.0'], + ['>1.2.3', '1.3.0-alpha', include_prerelease: true] + ].each do |tuple| + range = tuple[0] + version = tuple[1] + options = tuple[2] || {} + expect(SemanticRange.ltr?(version, range, **options)).to eq(false) + end end end diff --git a/spec/semantic_range_spec.rb b/spec/semantic_range_spec.rb index 122c3c0..3eb9cfd 100644 --- a/spec/semantic_range_spec.rb +++ b/spec/semantic_range_spec.rb @@ -73,15 +73,6 @@ expect(SemanticRange.cmp(v0, '>=', v1, loose: loose)).to eq(true) expect(SemanticRange.cmp(v1, '<=', v0, loose: loose)).to eq(true) expect(SemanticRange.cmp(v0, '!=', v1, loose: loose)).to eq(true) - - # Backwards-compatibility - expect(SemanticRange.gt(v0, v1, loose: loose)).to eq(true) - expect(SemanticRange.lt(v1, v0, loose: loose)).to eq(true) - expect(SemanticRange.lt(v0, v1, loose: loose)).to eq(false) - expect(SemanticRange.gt(v1, v0, loose: loose)).to eq(false) - expect(SemanticRange.eq(v0, v0, loose: loose)).to eq(true) - expect(SemanticRange.eq(v1, v1, loose: loose)).to eq(true) - expect(SemanticRange.neq(v0, v1, loose: loose)).to eq(true) end end @@ -138,14 +129,6 @@ expect(SemanticRange.gte?(v0, v1, loose: loose)).to eq(true) expect(SemanticRange.lt?(v0, v1, loose: loose)).to eq(false) expect(SemanticRange.lte?(v0, v1, loose: loose)).to eq(true) - - # Backwards-compatibility - expect(SemanticRange.eq(v0, v1, loose: loose)).to eq(true) - expect(SemanticRange.neq(v0, v1, loose: loose)).to eq(false) - expect(SemanticRange.gt(v0, v1, loose: loose)).to eq(false) - expect(SemanticRange.gte(v0, v1, loose: loose)).to eq(true) - expect(SemanticRange.lt(v0, v1, loose: loose)).to eq(false) - expect(SemanticRange.lte(v0, v1, loose: loose)).to eq(true) end end @@ -155,9 +138,9 @@ ['^1.2.3+build', '1.2.3'], ['^1.2.3+build', '1.3.0'], ['1.2.3-pre+asdf - 2.4.3-pre+asdf', '1.2.3'], - ['1.2.3pre+asdf - 2.4.3-pre+asdf', '1.2.3', true], - ['1.2.3-pre+asdf - 2.4.3pre+asdf', '1.2.3', true], - ['1.2.3pre+asdf - 2.4.3pre+asdf', '1.2.3', true], + ['1.2.3pre+asdf - 2.4.3-pre+asdf', '1.2.3', loose: true], + ['1.2.3-pre+asdf - 2.4.3pre+asdf', '1.2.3', loose: true], + ['1.2.3pre+asdf - 2.4.3pre+asdf', '1.2.3', loose: true], ['1.2.3-pre+asdf - 2.4.3-pre+asdf', '1.2.3-pre.2'], ['1.2.3-pre+asdf - 2.4.3-pre+asdf', '2.4.3-alpha'], ['1.2.3+asdf - 2.4.3+asdf', '1.2.3'], @@ -165,10 +148,10 @@ ['>=*', '0.2.4'], ['', '1.0.0'], ['*', '1.2.3'], - ['*', 'v1.2.3', true], - ['>=1.0.0', '1.0.0'], - ['>=1.0.0', '1.0.1'], - ['>=1.0.0', '1.1.0'], + ['*', 'v1.2.3', loose: 123], + ['>=1.0.0', '1.0.0', loose: /asdf/], + ['>=1.0.0', '1.0.1', loose: nil], + ['>=1.0.0', '1.1.0', loose: 0], ['>1.0.0', '1.0.1'], ['>1.0.0', '1.1.0'], ['<=2.0.0', '2.0.0'], @@ -186,7 +169,7 @@ ['<= 2.0.0', '0.2.9'], ['< 2.0.0', '1.9999.9999'], ["<\t2.0.0", '0.2.9'], - ['>=0.1.97', 'v0.1.97', true], + ['>=0.1.97', 'v0.1.97', loose: true], ['>=0.1.97', '0.1.97'], ['0.1.20 || 1.2.4', '1.2.4'], ['>=0.2.3 || <0.0.1', '0.0.0'], @@ -205,6 +188,10 @@ ['*', '1.2.3'], ['2', '2.1.2'], ['2.3', '2.3.1'], + ['~0.0.1', '0.0.1'], + ['~0.0.1', '0.0.2'], + ['~x', '0.0.9'], # >=2.4.0 <2.5.0 + ['~2', '2.0.9'], # >=2.4.0 <2.5.0 ['~2.4', '2.4.0'], # >=2.4.0 <2.5.0 ['~2.4', '2.4.5'], ['~>3.2.1', '3.2.2'], # >=3.2.1 <3.3.0, @@ -214,6 +201,7 @@ ['~1.0', '1.0.2'], # >=1.0.0 <1.1.0, ['~ 1.0', '1.0.2'], ['~ 1.0.3', '1.0.12'], + ['~ 1.0.3alpha', '1.0.12', loose: true], ['>=1', '1.0.0'], ['>= 1', '1.0.0'], ['<1.2', '1.1.1'], @@ -238,19 +226,43 @@ ['^1.2.3', '1.8.1'], ['^0.1.2', '0.1.2'], ['^0.1', '0.1.2'], + ['^0.0.1', '0.0.1'], ['^1.2', '1.4.2'], ['^1.2 ^1', '1.4.2'], ['^1.2.3-alpha', '1.2.3-pre'], ['^1.2.0-alpha', '1.2.0-pre'], - ['^0.0.1-alpha', '0.0.1-beta'] + ['^0.0.1-alpha', '0.0.1-beta'], + ['^0.0.1-alpha', '0.0.1'], + ['^0.1.1-alpha', '0.1.1-beta'], + ['^x', '1.2.3'], + ['x - 1.0.0', '0.9.7'], + ['x - 1.x', '0.9.7'], + ['1.0.0 - x', '1.9.7'], + ['1.x - x', '1.9.7'], + ['<=7.x', '7.9.9'], + ['2.x', '2.0.0-pre.0', include_prerelease: true], + ['2.x', '2.1.0-pre.0', include_prerelease: true], + ['1.1.x', '1.1.0-a', include_prerelease: true], + ['1.1.x', '1.1.1-a', include_prerelease: true], + ['*', '1.0.0-rc1', include_prerelease: true], + ['^1.0.0-0', '1.0.1-rc1', include_prerelease: true], + ['^1.0.0-rc2', '1.0.1-rc1', include_prerelease: true], + ['^1.0.0', '1.0.1-rc1', include_prerelease: true], + ['^1.0.0', '1.1.0-rc1', include_prerelease: true], + ['1 - 2', '2.0.0-pre', include_prerelease: true], + ['1 - 2', '1.0.0-pre', include_prerelease: true], + ['1.0 - 2', '1.0.0-pre', include_prerelease: true], + + ['=0.7.x', '0.7.0-asdf', include_prerelease: true], + ['>=0.7.x', '0.7.0-asdf', include_prerelease: true], + ['<=0.7.x', '0.7.0-asdf', include_prerelease: true], + + ['>=1.0.0 <=1.1.0', '1.1.0-pre', include_prerelease: true], ].each do |tuple| range = tuple[0] version = tuple[1] - loose = tuple[2] - expect(SemanticRange.satisfies?(version, range, loose: loose)).to eq(true), "#{tuple}" - - # Backwards-compatibility - expect(SemanticRange.satisfies(version, range, loose: loose)).to eq(true), "#{tuple}" + options = tuple[2] || {} + expect(SemanticRange.satisfies?(version, range, **options)).to eq(true), "#{tuple}" end end @@ -268,9 +280,10 @@ ['^1.2.3', '1.2.3-beta'], ['=0.7.x', '0.7.0-asdf'], ['>=0.7.x', '0.7.0-asdf'], - ['1', '1.0.0beta', true], - ['<1', '1.0.0beta', true], - ['< 1', '1.0.0beta', true], + ['<=0.7.x', '0.7.0-asdf'], + ['1', '1.0.0beta', loose: 420], + ['<1', '1.0.0beta', loose: true], + ['< 1', '1.0.0beta', loose: true], ['1.0.0', '1.0.1'], ['>=1.0.0', '0.0.0'], ['>=1.0.0', '0.0.1'], @@ -282,7 +295,7 @@ ['<=2.0.0', '2.2.9'], ['<2.0.0', '2.9999.9999'], ['<2.0.0', '2.2.9'], - ['>=0.1.97', 'v0.1.93', true], + ['>=0.1.97', 'v0.1.93', loose: true], ['>=0.1.97', '0.1.93'], ['0.1.20 || 1.2.4', '1.2.3'], ['>=0.2.3 || <0.0.1', '0.0.3'], @@ -299,6 +312,8 @@ ['1.2.* || 2.*', '1.1.3'], ['2', '1.1.2'], ['2.3', '2.4.1'], + ['~0.0.1', '0.1.0-alpha'], + ['~0.0.1', '0.1.0'], ['~2.4', '2.5.0'], # >=2.4.0 <2.5.0 ['~2.4', '2.3.9'], ['~>3.2.1', '3.3.2'], # >=3.2.1 <3.3.0 @@ -308,7 +323,7 @@ ['~1.0', '1.1.0'], # >=1.0.0 <1.1.0 ['<1', '1.0.0'], ['>=1.2', '1.1.1'], - ['1', '2.0.0beta', true], + ['1', '2.0.0beta', loose: true], ['~v0.5.4-beta', '0.5.4-alpha'], ['=0.7.x', '0.8.2'], ['>=0.7.x', '0.6.2'], @@ -316,29 +331,61 @@ ['<1.2.3', '1.2.3-beta'], ['=1.2.3', '1.2.3-beta'], ['>1.2', '1.2.8'], + ['^0.0.1', '0.0.2-alpha'], + ['^0.0.1', '0.0.2'], ['^1.2.3', '2.0.0-alpha'], ['^1.2.3', '1.2.2'], ['^1.2', '1.1.9'], - ['*', 'v1.2.3-foo', true], - # invalid ranges never satisfied! - ['blerg', '1.2.3'], - ['git+https:#user:password0123@github.com/foo', '123.0.0', true], - ['^1.2.3', '2.0.0-pre'] + ['*', 'v1.2.3-foo', loose: true], + + ['*', 'not a version'], + ['>=2', 'glorp'], + ['>=2', loose: false], + + ['2.x', '3.0.0-pre.0', include_prerelease: true], + ['^1.0.0', '1.0.0-rc1', include_prerelease: true], + ['^1.0.0', '2.0.0-rc1', include_prerelease: true], + ['^1.2.3-rc2', '2.0.0', include_prerelease: true], + ['^1.0.0', '2.0.0-rc1', include_prerelease: true], + ['^1.0.0', '2.0.0-rc1'], + + ['1 - 2', '3.0.0-pre', include_prerelease: true], + ['1 - 2', '2.0.0-pre'], + ['1 - 2', '1.0.0-pre'], + ['1.0 - 2', '1.0.0-pre'], + + ['1.1.x', '1.0.0-a'], + ['1.1.x', '1.1.0-a'], + ['1.1.x', '1.2.0-a'], + ['1.1.x', '1.2.0-a', include_prerelease: true], + ['1.1.x', '1.0.0-a', include_prerelease: true], + ['1.x', '1.0.0-a'], + ['1.x', '1.1.0-a'], + ['1.x', '1.2.0-a'], + ['1.x', '0.0.0-a', include_prerelease: true], + ['1.x', '2.0.0-a', include_prerelease: true], + + ['>=1.0.0 <1.1.0', '1.1.0'], + ['>=1.0.0 <1.1.0', '1.1.0', include_prerelease: true], + ['>=1.0.0 <1.1.0', '1.1.0-pre'], + ['>=1.0.0 <1.1.0-pre', '1.1.0-pre'], ].each do |tuple| range = tuple[0] version = tuple[1] - loose = tuple[2] - expect(SemanticRange.satisfies?(version, range, loose: loose)).to eq(false), "#{tuple}" - - # Backwards-compatibility - expect(SemanticRange.satisfies(version, range, loose: loose)).to eq(false), "#{tuple}" + options = tuple[2] || {} + expect(SemanticRange.satisfies?(version, range, **options)).to eq(false), "#{tuple}" end end it 'valid range' do [ ['1.0.0 - 2.0.0', '>=1.0.0 <=2.0.0'], - ['1.0.0', '1.0.0'], + ['1.0.0 - 2.0.0', '>=1.0.0-0 <2.0.1-0', include_prerelease: true], + ['1 - 2', '>=1.0.0 <3.0.0-0'], + ['1 - 2', '>=1.0.0-0 <3.0.0-0', include_prerelease: true], + ['1.0 - 2.0', '>=1.0.0 <2.1.0-0'], + ['1.0 - 2.0', '>=1.0.0-0 <2.1.0-0', include_prerelease: true], + ['1.0.0', '1.0.0', loose: false], ['>=*', '*'], ['', '*'], ['*', '*'], @@ -346,7 +393,7 @@ ['>=1.0.0', '>=1.0.0'], ['>1.0.0', '>1.0.0'], ['<=2.0.0', '<=2.0.0'], - ['1', '>=1.0.0 <2.0.0'], + ['1', '>=1.0.0 <2.0.0-0'], ['<=2.0.0', '<=2.0.0'], ['<=2.0.0', '<=2.0.0'], ['<2.0.0', '<2.0.0'], @@ -360,60 +407,69 @@ ['<= 2.0.0', '<=2.0.0'], ['<= 2.0.0', '<=2.0.0'], ['< 2.0.0', '<2.0.0'], - ['< 2.0.0', '<2.0.0'], + ["<\t2.0.0", '<2.0.0'], ['>=0.1.97', '>=0.1.97'], ['>=0.1.97', '>=0.1.97'], ['0.1.20 || 1.2.4', '0.1.20||1.2.4'], ['>=0.2.3 || <0.0.1', '>=0.2.3||<0.0.1'], ['>=0.2.3 || <0.0.1', '>=0.2.3||<0.0.1'], ['>=0.2.3 || <0.0.1', '>=0.2.3||<0.0.1'], - ['||', '||'], - ['2.x.x', '>=2.0.0 <3.0.0'], - ['1.2.x', '>=1.2.0 <1.3.0'], - ['1.2.x || 2.x', '>=1.2.0 <1.3.0||>=2.0.0 <3.0.0'], - ['1.2.x || 2.x', '>=1.2.0 <1.3.0||>=2.0.0 <3.0.0'], + ['||', '*'], + ['2.x.x', '>=2.0.0 <3.0.0-0'], + ['1.2.x', '>=1.2.0 <1.3.0-0'], + ['1.2.x || 2.x', '>=1.2.0 <1.3.0-0||>=2.0.0 <3.0.0-0'], + ['1.2.x || 2.x', '>=1.2.0 <1.3.0-0||>=2.0.0 <3.0.0-0'], ['x', '*'], - ['2.*.*', '>=2.0.0 <3.0.0'], - ['1.2.*', '>=1.2.0 <1.3.0'], - ['1.2.* || 2.*', '>=1.2.0 <1.3.0||>=2.0.0 <3.0.0'], + ['2.*.*', '>=2.0.0 <3.0.0-0'], + ['1.2.*', '>=1.2.0 <1.3.0-0'], + ['1.2.* || 2.*', '>=1.2.0 <1.3.0-0||>=2.0.0 <3.0.0-0'], ['*', '*'], - ['2', '>=2.0.0 <3.0.0'], - ['2.3', '>=2.3.0 <2.4.0'], - ['~2.4', '>=2.4.0 <2.5.0'], - ['~2.4', '>=2.4.0 <2.5.0'], - ['~>3.2.1', '>=3.2.1 <3.3.0'], - ['~1', '>=1.0.0 <2.0.0'], - ['~>1', '>=1.0.0 <2.0.0'], - ['~> 1', '>=1.0.0 <2.0.0'], - ['~1.0', '>=1.0.0 <1.1.0'], - ['~ 1.0', '>=1.0.0 <1.1.0'], - ['^0', '>=0.0.0 <1.0.0'], - ['^ 1', '>=1.0.0 <2.0.0'], - ['^0.1', '>=0.1.0 <0.2.0'], - ['^1.0', '>=1.0.0 <2.0.0'], - ['^1.2', '>=1.2.0 <2.0.0'], - ['^0.0.1', '>=0.0.1 <0.0.2'], - ['^0.0.1-beta', '>=0.0.1-beta <0.0.2'], - ['^0.1.2', '>=0.1.2 <0.2.0'], - ['^1.2.3', '>=1.2.3 <2.0.0'], - ['^1.2.3-beta.4', '>=1.2.3-beta.4 <2.0.0'], - ['<1', '<1.0.0'], - ['< 1', '<1.0.0'], + ['2', '>=2.0.0 <3.0.0-0'], + ['2.3', '>=2.3.0 <2.4.0-0'], + ['~2.4', '>=2.4.0 <2.5.0-0'], + ['~2.4', '>=2.4.0 <2.5.0-0'], + ['~>3.2.1', '>=3.2.1 <3.3.0-0'], + ['~1', '>=1.0.0 <2.0.0-0'], + ['~>1', '>=1.0.0 <2.0.0-0'], + ['~> 1', '>=1.0.0 <2.0.0-0'], + ['~1.0', '>=1.0.0 <1.1.0-0'], + ['~ 1.0', '>=1.0.0 <1.1.0-0'], + ['^0', '<1.0.0-0'], + ['^ 1', '>=1.0.0 <2.0.0-0'], + ['^0.1', '>=0.1.0 <0.2.0-0'], + ['^1.0', '>=1.0.0 <2.0.0-0'], + ['^1.2', '>=1.2.0 <2.0.0-0'], + ['^0.0.1', '>=0.0.1 <0.0.2-0'], + ['^0.0.1-beta', '>=0.0.1-beta <0.0.2-0'], + ['^0.1.2', '>=0.1.2 <0.2.0-0'], + ['^1.2.3', '>=1.2.3 <2.0.0-0'], + ['^1.2.3-beta.4', '>=1.2.3-beta.4 <2.0.0-0'], + ['<1', '<1.0.0-0'], + ['< 1', '<1.0.0-0'], ['>=1', '>=1.0.0'], ['>= 1', '>=1.0.0'], - ['<1.2', '<1.2.0'], - ['< 1.2', '<1.2.0'], - ['1', '>=1.0.0 <2.0.0'], - ['>01.02.03', '>1.2.3', true], + ['<1.2', '<1.2.0-0'], + ['< 1.2', '<1.2.0-0'], + ['1', '>=1.0.0 <2.0.0-0'], + ['>01.02.03', '>1.2.3', loose: true], ['>01.02.03', nil], - ['~1.2.3beta', '>=1.2.3-beta <1.3.0', true], + ['~1.2.3beta', '>=1.2.3-beta <1.3.0-0', loose: true], ['~1.2.3beta', nil], - ['^ 1.2 ^ 1', '>=1.2.0 <2.0.0 >=1.0.0 <2.0.0'] + ['^ 1.2 ^ 1', '>=1.2.0 <2.0.0-0 >=1.0.0'], + ['1.2 - 3.4.5', '>=1.2.0 <=3.4.5'], + ['1.2.3 - 3.4', '>=1.2.3 <3.5.0-0'], + ['1.2 - 3.4', '>=1.2.0 <3.5.0-0'], + ['>1', '>=2.0.0'], + ['>1.2', '>=1.3.0'], + ['>X', '<0.0.0-0'], + ['* 2.x', '<0.0.0-0'], + ['>x 2.x || * || =01.02.03', '>=1.2.3'], - ['~1.02.03beta', '>=1.2.3-beta <1.3.0'] + ['~1.02.03beta', '>=1.2.3-beta <1.3.0-0'] ].each do |v| loose, comps = v expect { SemanticRange::Range.new(loose) }.to raise_error(SemanticRange::InvalidRange) @@ -614,17 +613,10 @@ ['>=*', [['']]], ['', [['']]], ['*', [['']]], - ['*', [['']]], - ['>=1.0.0', [['>=1.0.0']]], ['>=1.0.0', [['>=1.0.0']]], - ['>=1.0.0', [['>=1.0.0']]], - ['>1.0.0', [['>1.0.0']]], ['>1.0.0', [['>1.0.0']]], ['<=2.0.0', [['<=2.0.0']]], - ['1', [['>=1.0.0', '<2.0.0']]], - ['<=2.0.0', [['<=2.0.0']]], - ['<=2.0.0', [['<=2.0.0']]], - ['<2.0.0', [['<2.0.0']]], + ['1', [['>=1.0.0', '<2.0.0-0']]], ['<2.0.0', [['<2.0.0']]], ['>= 1.0.0', [['>=1.0.0']]], ['>= 1.0.0', [['>=1.0.0']]], @@ -637,47 +629,43 @@ ['< 2.0.0', [['<2.0.0']]], ["<\t2.0.0", [['<2.0.0']]], ['>=0.1.97', [['>=0.1.97']]], - ['>=0.1.97', [['>=0.1.97']]], ['0.1.20 || 1.2.4', [['0.1.20'], ['1.2.4']]], ['>=0.2.3 || <0.0.1', [['>=0.2.3'], ['<0.0.1']]], - ['>=0.2.3 || <0.0.1', [['>=0.2.3'], ['<0.0.1']]], - ['>=0.2.3 || <0.0.1', [['>=0.2.3'], ['<0.0.1']]], - ['||', [[''], ['']]], - ['2.x.x', [['>=2.0.0', '<3.0.0']]], - ['1.2.x', [['>=1.2.0', '<1.3.0']]], - ['1.2.x || 2.x', [['>=1.2.0', '<1.3.0'], ['>=2.0.0', '<3.0.0']]], - ['1.2.x || 2.x', [['>=1.2.0', '<1.3.0'], ['>=2.0.0', '<3.0.0']]], + ['||', [['']]], + ['2.x.x', [['>=2.0.0', '<3.0.0-0']]], + ['1.2.x', [['>=1.2.0', '<1.3.0-0']]], + ['1.2.x || 2.x', [['>=1.2.0', '<1.3.0-0'], ['>=2.0.0', '<3.0.0-0']]], ['x', [['']]], - ['2.*.*', [['>=2.0.0', '<3.0.0']]], - ['1.2.*', [['>=1.2.0', '<1.3.0']]], - ['1.2.* || 2.*', [['>=1.2.0', '<1.3.0'], ['>=2.0.0', '<3.0.0']]], - ['1.2.* || 2.*', [['>=1.2.0', '<1.3.0'], ['>=2.0.0', '<3.0.0']]], - ['*', [['']]], - ['2', [['>=2.0.0', '<3.0.0']]], - ['2.3', [['>=2.3.0', '<2.4.0']]], - ['~2.4', [['>=2.4.0', '<2.5.0']]], - ['~2.4', [['>=2.4.0', '<2.5.0']]], - ['~>3.2.1', [['>=3.2.1', '<3.3.0']]], - ['~1', [['>=1.0.0', '<2.0.0']]], - ['~>1', [['>=1.0.0', '<2.0.0']]], - ['~> 1', [['>=1.0.0', '<2.0.0']]], - ['~1.0', [['>=1.0.0', '<1.1.0']]], - ['~ 1.0', [['>=1.0.0', '<1.1.0']]], - ['~ 1.0.3', [['>=1.0.3', '<1.1.0']]], - ['~> 1.0.3', [['>=1.0.3', '<1.1.0']]], - ['<1', [['<1.0.0']]], - ['< 1', [['<1.0.0']]], + ['2.*.*', [['>=2.0.0', '<3.0.0-0']]], + ['1.2.*', [['>=1.2.0', '<1.3.0-0']]], + ['1.2.* || 2.*', [['>=1.2.0', '<1.3.0-0'], ['>=2.0.0', '<3.0.0-0']]], + ['2', [['>=2.0.0', '<3.0.0-0']]], + ['2.3', [['>=2.3.0', '<2.4.0-0']]], + ['~2.4', [['>=2.4.0', '<2.5.0-0']]], + ['~>3.2.1', [['>=3.2.1', '<3.3.0-0']]], + ['~1', [['>=1.0.0', '<2.0.0-0']]], + ['~>1', [['>=1.0.0', '<2.0.0-0']]], + ['~> 1', [['>=1.0.0', '<2.0.0-0']]], + ['~1.0', [['>=1.0.0', '<1.1.0-0']]], + ['~ 1.0', [['>=1.0.0', '<1.1.0-0']]], + ['~ 1.0.3', [['>=1.0.3', '<1.1.0-0']]], + ['~> 1.0.3', [['>=1.0.3', '<1.1.0-0']]], + ['<1', [['<1.0.0-0']]], + ['< 1', [['<1.0.0-0']]], ['>=1', [['>=1.0.0']]], ['>= 1', [['>=1.0.0']]], - ['<1.2', [['<1.2.0']]], - ['< 1.2', [['<1.2.0']]], - ['1', [['>=1.0.0', '<2.0.0']]], - ['1 2', [['>=1.0.0', '<2.0.0', '>=2.0.0', '<3.0.0']]], + ['<1.2', [['<1.2.0-0']]], + ['< 1.2', [['<1.2.0-0']]], + ['1 2', [['>=1.0.0', '<2.0.0-0', '>=2.0.0', '<3.0.0-0']]], ['1.2 - 3.4.5', [['>=1.2.0', '<=3.4.5']]], - ['1.2.3 - 3.4', [['>=1.2.3', '<3.5.0']]], - ['1.2.3 - 3', [['>=1.2.3', '<4.0.0']]], - ['>*', [['<0.0.0']]], - ['<*', [['<0.0.0']]] + ['1.2.3 - 3.4', [['>=1.2.3', '<3.5.0-0']]], + ['1.2.3 - 3', [['>=1.2.3', '<4.0.0-0']]], + ['>*', [['<0.0.0-0']]], + ['<*', [['<0.0.0-0']]], + ['>X', [['<0.0.0-0']]], + ['* 2.x', [['<0.0.0-0']]], + ['>x 2.x || * || =1.3.0', true], - ['1.3.0', '>1.3.0', false], - ['>=1.3.0', '1.3.0', true], - ['>1.3.0', '1.3.0', false], - # Same direction increasing - ['>1.3.0', '>1.2.0', true], - ['>1.2.0', '>1.3.0', true], - ['>=1.2.0', '>1.3.0', true], - ['>1.2.0', '>=1.3.0', true], - # Same direction decreasing - ['<1.3.0', '<1.2.0', true], - ['<1.2.0', '<1.3.0', true], - ['<=1.2.0', '<1.3.0', true], - ['<1.2.0', '<=1.3.0', true], - # Different directions, same semver and inclusive operator - ['>=1.3.0', '<=1.3.0', true], - ['>=1.3.0', '>=1.3.0', true], - ['<=1.3.0', '<=1.3.0', true], - ['>1.3.0', '<=1.3.0', false], - ['>=1.3.0', '<1.3.0', false], - # Opposite matching directions - ['>1.0.0', '<2.0.0', true], - ['>=1.0.0', '<2.0.0', true], - ['>=1.0.0', '<=2.0.0', true], - ['>1.0.0', '<=2.0.0', true], - ['<=2.0.0', '>1.0.0', true], - ['<=1.0.0', '>=2.0.0', false] + # One is a Version + ['1.3.0', '>=1.3.0', true], + ['1.3.0', '>1.3.0', false], + ['>=1.3.0', '1.3.0', true], + ['>1.3.0', '1.3.0', false], + # Same direction increasing + ['>1.3.0', '>1.2.0', true], + ['>1.2.0', '>1.3.0', true], + ['>=1.2.0', '>1.3.0', true], + ['>1.2.0', '>=1.3.0', true], + # Same direction decreasing + ['<1.3.0', '<1.2.0', true], + ['<1.2.0', '<1.3.0', true], + ['<=1.2.0', '<1.3.0', true], + ['<1.2.0', '<=1.3.0', true], + # Different directions, same semver and inclusive operator + ['>=1.3.0', '<=1.3.0', true], + ['>=1.3.0', '>=1.3.0', true], + ['<=1.3.0', '<=1.3.0', true], + ['>1.3.0', '<=1.3.0', false], + ['>=1.3.0', '<1.3.0', false], + # Opposite matching directions + ['>1.0.0', '<2.0.0', true], + ['>=1.0.0', '<2.0.0', true], + ['>=1.0.0', '<=2.0.0', true], + ['>1.0.0', '<=2.0.0', true], + ['<=2.0.0', '>1.0.0', true], + ['<=1.0.0', '>=2.0.0', false] ].each do |c| comp_1 = SemanticRange::Comparator.new(c[0], nil) comp_2 = SemanticRange::Comparator.new(c[1], nil) expect(comp_1.intersects(comp_2)).to eq(c[2]) expect(comp_2.intersects(comp_1)).to eq(c[2]) - - # Backwards-compatibility - expect(comp_1.intersects(comp_2)).to eq(c[2]) - expect(comp_2.intersects(comp_1)).to eq(c[2]) end end it 'comparator satisfies range' do [ - ['1.3.0', '1.3.0 || <1.0.0 >2.0.0', true], - ['1.3.0', '<1.0.0 >2.0.0', false], - ['>=1.3.0', '<1.3.0', false], - ['<1.3.0', '>=1.3.0', false] + ['1.3.0', '1.3.0 || <1.0.0 >2.0.0', true], + ['1.3.0', '<1.0.0 >2.0.0', false], + ['>=1.3.0', '<1.3.0', false], + ['<1.3.0', '>=1.3.0', false] ].each do |c| comp = SemanticRange::Comparator.new(c[0], nil) range = SemanticRange::Range.new(c[1]) expect(comp.satisfies_range?(range)).to eq(c[2]) - - # Backwards-compatibility - expect(comp.satisfies_range(range)).to eq(c[2]) end end it 'ranges intersect' do [ - ['1.3.0 || <1.0.0 >2.0.0', '1.3.0 || <1.0.0 >2.0.0', true], - ['<1.0.0 >2.0.0', '>0.0.0', true], - ['<1.0.0 >2.0.0', '>1.4.0 <1.6.0', false], - ['<1.0.0 >2.0.0', '>1.4.0 <1.6.0 || 2.0.0', false], - ['>1.0.0 <=2.0.0', '2.0.0', true], - ['<1.0.0 >=2.0.0', '2.1.0', false], - ['<1.0.0 >=2.0.0', '>1.4.0 <1.6.0 || 2.0.0', false] + ['1.3.0 || <1.0.0 >2.0.0', '1.3.0 || <1.0.0 >2.0.0', true], + ['<1.0.0 >2.0.0', '>0.0.0', true], + ['<1.0.0 >2.0.0', '>1.4.0 <1.6.0', false], + ['<1.0.0 >2.0.0', '>1.4.0 <1.6.0 || 2.0.0', false], + ['>1.0.0 <=2.0.0', '2.0.0', true], + ['<1.0.0 >=2.0.0', '2.1.0', false], + ['<1.0.0 >=2.0.0', '>1.4.0 <1.6.0 || 2.0.0', false] ].each do |c| range_1 = SemanticRange::Range.new(c[0]) range_2 = SemanticRange::Range.new(c[1]) @@ -776,11 +757,11 @@ it 'filters an array of versions that satisfy a range' do [ - ['1.3.0 || <1.0.0 || >2.0.0', ['0.9.0', '1.3.0', '1.5.0', '2.0.5'], ['0.9.0', '1.3.0', '2.0.5']], - ['1.0.0 - 1.2.0', ['0.1.0', '1.0.1', '1.1.1', '1.2.0', '1.2.1'], ['1.0.1', '1.1.1', '1.2.0']], - ['^0.5.0', ['0.5.1', '0.6.0'], ['0.5.1']], - ['1.3.0', ['1.3.0', '2.0.0'], ['1.3.0']], - ['>=1.3.0', ['1.0.0', '1.3.0', '2.0.0'], ['1.3.0', '2.0.0']] + ['1.3.0 || <1.0.0 || >2.0.0', ['0.9.0', '1.3.0', '1.5.0', '2.0.5'], ['0.9.0', '1.3.0', '2.0.5']], + ['1.0.0 - 1.2.0', ['0.1.0', '1.0.1', '1.1.1', '1.2.0', '1.2.1'], ['1.0.1', '1.1.1', '1.2.0']], + ['^0.5.0', ['0.5.1', '0.6.0'], ['0.5.1']], + ['1.3.0', ['1.3.0', '2.0.0'], ['1.3.0']], + ['>=1.3.0', ['1.0.0', '1.3.0', '2.0.0'], ['1.3.0', '2.0.0']] ].each do |range, versions, expected| expect(SemanticRange.filter(versions, range)).to eq(expected) end