Skip to content

Instantly share code, notes, and snippets.

@jamesdaniels
Last active December 18, 2015 19:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jamesdaniels/5831116 to your computer and use it in GitHub Desktop.
Save jamesdaniels/5831116 to your computer and use it in GitHub Desktop.
require "minitest/autorun"
# Usage: IosVersion.new('11A4372q') #=> '7.0b1'
class IosVersion
IOS = {
'7' => [
3, {
'D' => [[1, 2]],
'E' => [[1, 3]],
'B' => [
2, {
'367' => [0],
'500' => [2]
}
]
}
],
'8' => [
4, {
'A' => [
0, {
'293' => [0],
'306' => [1],
'400' => [2]
}
],
'B' => [
1, {
'5080c' => [0, 1],
'5091b' => [0, 2],
'117' => [0],
}
],
'C' => [
2, {
'5091e' => [0, 1],
'5101c' => [0, 2],
'5115c' => [0, 3],
'134' => [0],
'134b' => [0],
'148' => [1],
'148a' => [1]
}
],
'E' => [
2, {
'128' => [5],
'200' => [6],
'303' => [7],
'401' => [8],
'501' => [9],
'600' => [10],
}
],
'F' => [
3, {
'5148b' => [0, 1],
'5153d' => [0, 2],
'5166b' => [0, 3],
'190' => [0],
'191' => [0],
}
],
'G' => [
3, {
'4' => [1]
}
],
'H' => [
3, {
'7' => [2],
'8' => [2],
}
],
'J' => [
3, {
'2' => [3],
'3' => [3],
}
],
'K' => [
3, {
'2' => [4],
}
],
'L' => [
3, {
'1' => [5],
}
]
}
],
'9' => [
5, {
'A' => [
0, {
'5220p' => [0, 1],
'5248d' => [0, 2],
'5258f' => [0, 3],
'5274d' => [0, 4],
'5288d' => [0, 5],
'5302b' => [0, 6],
'5313e' => [0, 7],
'334' => [0],
'402' => [1, 1],
'404' => [1, 2],
'405' => [1],
'406' => [1]
}
],
'B' => [
1, {
'5117b' => [0, 1],
'5127c' => [0, 2],
'5141a' => [0, 3],
'176' => [0],
'179' => [0],
'206' => [1],
'208' => [1]
}
]
}
],
'10' => [
6, {
'A' => [
0, {
'5316k' => [0, 1],
'5338d' => [0, 2],
'5355d' => [0, 3],
'5376e' => [0, 4],
'403' => [0],
'405' => [0],
'406' => [0],
'407' => [0],
'523' => [1],
'525' => [1],
'8426' => [1],
'550' => [2],
'551' => [2],
'8500' => [2],
}
],
'B' => [
1, {
'5095f' => [0, 1],
'5105c' => [0, 2],
'5117b' => [0, 3],
'5126b' => [0, 4],
'141' => [0],
'142' => [0],
'143' => [0],
'144' => [0],
'311' => [1, 1],
'145' => [1],
'146' => [2],
'147' => [2],
'318' => [3, 2],
'329' => [3],
'350' => [4],
}
]
}
],
'11' => [
7, {
'A' => [
0, {
'4372q' => [0, 1]
}
]
}
]
}
attr_accessor :build, :major, :humanized_major, :minor, :humanized_minor, :patch, :humanized_patch, :beta, :humanized_beta
def initialize(build)
@build = build
build =~ /([1-9][0-9]*)([A-Z])(\d+)([a-z]*)/
@major, @minor, @patch, @beta = $1.to_i, $2, $3.to_i, $4
built_version = []
if IOS[major.to_s]
built_version << IOS[major.to_s][0]
built_version << (IOS[major.to_s][1][minor.to_s] && IOS[major.to_s][1][minor.to_s][0])
built_version << (IOS[major.to_s][1][minor.to_s] && IOS[major.to_s][1][minor.to_s][1] && IOS[major.to_s][1][minor.to_s][1]["#{patch}#{beta}"])
end
built_version.flatten!
@humanized_major, @humanized_minor, @humanized_patch, @humanized_beta = built_version
@is_beta ||= !@humanized_beta.nil?
@humanized_major ||= @guessed = true && major - 4
@humanized_minor ||= @guessed = true && minor.ord - 65
@humanized_patch ||= @guessed = true && 0
end
def to_s
humanized_major && humanized_minor && "#{humanized_major}.#{humanized_minor}#{".#{humanized_patch}" if humanized_patch}#{"b#{humanized_beta}" if humanized_beta}".gsub(/\.0$/, '').gsub(/\.0b/, "b") || build
end
def <=>(other_version)
major_diff = humanized_major <=> other_version.humanized_major
return major_diff unless major_diff == 0
minor_diff = humanized_minor <=> other_version.humanized_minor
return minor_diff unless minor_diff == 0
patch_diff = humanized_patch <=> other_version.humanized_patch
return patch_diff unless patch_diff == 0
if beta? || other_version.beta?
return -1 if beta? && !other_version.beta?
return 1 if !beta? && other_version.beta?
beta_diff = humanized_beta <=> other_version.humanized_beta
return beta_diff unless beta_diff == 0
return beta <=> other_version.beta
else
raw_patch_diff = patch <=> other_version.patch
return raw_patch_diff unless raw_patch_diff == 0
return beta <=> other_version.beta
end
end
def beta?
!!@is_beta
end
def guessed?
!!@guessed
end
end
class TestIosVersion < Minitest::Test
KnownIosVersions = {
'7D11' => '3.1.2',
'7E18' => '3.1.3',
'7B367' => '3.2',
'7B500' => '3.2.2',
'8A293' => '4.0',
'8A306' => '4.0.1',
'8A400' => '4.0.2',
'8B5080c' => '4.1b1',
'8B5091b' => '4.1b2',
'8B117' => '4.1',
'8C5115c' => '4.2b3',
'8C134' => '4.2',
'8C134b' => '4.2',
'8C148' => '4.2.1',
'8C148a' => '4.2.1',
'8E128' => '4.2.5',
'8E200' => '4.2.6',
'8E303' => '4.2.7',
'8E401' => '4.2.8',
'8E501' => '4.2.9',
'8E600' => '4.2.10',
'8F5148b' => '4.3b1',
'8F5153d' => '4.3b2',
'8F5166b' => '4.3b3',
'8F190' => '4.3',
'8F191' => '4.3',
'8G4' => '4.3.1',
'8H7' => '4.3.2',
'8H8' => '4.3.2',
'8J2' => '4.3.3',
'8J3' => '4.3.3',
'8K2' => '4.3.4',
'8L1' => '4.3.5',
'9A5220p' => '5.0b1',
'9A5248d' => '5.0b2',
'9A5258f' => '5.0b3',
'9A5274d' => '5.0b4',
'9A5288d' => '5.0b5',
'9A5302b' => '5.0b6',
'9A5313e' => '5.0b7',
'9A334' => '5.0',
'9A402' => '5.0.1b1',
'9A404' => '5.0.1b2',
'9A405' => '5.0.1',
'9A406' => '5.0.1',
'9B5117b' => '5.1b1',
'9B5127c' => '5.1b2',
'9B5141a' => '5.1b3',
'9B176' => '5.1',
'9B179' => '5.1',
'9B206' => '5.1.1',
'9B208' => '5.1.1',
'10A5316k' => '6.0b1',
'10A5338d' => '6.0b2',
'10A5355d' => '6.0b3',
'10A5376e' => '6.0b4',
'10A403' => '6.0',
'10A405' => '6.0',
'10A406' => '6.0',
'10A407' => '6.0',
'10A523' => '6.0.1',
'10A525' => '6.0.1',
'10A8426' => '6.0.1',
'10A550' => '6.0.2',
'10A551' => '6.0.2',
'10A8500' => '6.0.2',
'10B5105c' => '6.1b2',
'10B5117b' => '6.1b3',
'10B5126b' => '6.1b4',
'10B141' => '6.1',
'10B142' => '6.1',
'10B143' => '6.1',
'10B144' => '6.1',
'10B311' => '6.1.1b1',
'10B145' => '6.1.1',
'10B146' => '6.1.2',
'10B147' => '6.1.2',
'10B318' => '6.1.3b2',
'10B329' => '6.1.3',
'10B350' => '6.1.4',
'11A4372q' => '7.0b1'
}
def test_stringification_of_known_versions
KnownIosVersions.each do |known_ios_build, humanized_version|
IosVersion.new(known_ios_build).tap do |ios_version|
assert_equal humanized_version, ios_version.to_s, ios_version.build
end
end
end
def test_guess_of_known_versions
KnownIosVersions.each do |known_ios_build, humanized_version|
IosVersion.new(known_ios_build).tap do |ios_version|
assert !ios_version.guessed?, ios_version.build
end
end
end
def test_order_of_known_versions
KnownIosVersions.map do |known_ios_build, humanized_version|
IosVersion.new(known_ios_build)
end.shuffle.sort.each_with_index do |ios_version, index|
assert_equal index, KnownIosVersions.keys.index(ios_version.build), "#{ios_version.build} <=> #{KnownIosVersions.keys[index]}"
end
end
GuessedVersions = {
'10A408' => '6.0',
'10A8501' => '6.0',
'10B351' => '6.1',
'10C351' => '6.2',
'11A459' => '7.0',
'11A4372r' => '7.0',
'11B345' => '7.1',
'12A234' => '8.0'
}
def test_stringification_of_guessed_versions
GuessedVersions.each do |made_up_ios_build, humanized_version|
IosVersion.new(made_up_ios_build).tap do |ios_version|
assert_equal humanized_version, ios_version.to_s, made_up_ios_build
end
end
end
def test_guess_of_guessed_versions
GuessedVersions.each do |made_up_ios_build, humanized_version|
IosVersion.new(made_up_ios_build).tap do |ios_version|
assert ios_version.guessed?
end
end
end
def test_order_of_guessed_versions
GuessedVersions.map do |made_up_ios_build, humanized_version|
IosVersion.new(made_up_ios_build)
end.shuffle.sort.each_with_index do |ios_version, index|
assert_equal index, GuessedVersions.keys.index(ios_version.build), "#{ios_version.build} <=> #{GuessedVersions.keys[index]}"
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment