diff --git a/Sources/Tentacle/Release.swift b/Sources/Tentacle/Release.swift index fddcbbd..23ac5ca 100644 --- a/Sources/Tentacle/Release.swift +++ b/Sources/Tentacle/Release.swift @@ -9,10 +9,19 @@ import Foundation extension Repository { + /// A request to get the latest release for the repository. + /// + /// If the repository doesn't have any releases, this will result in a `.doesNotExist` error. + /// + /// https://developer.github.com/v3/repos/releases/#get-the-latest-release + public var latestRelease: Request { + return Request(method: .get, path: "/repos/\(owner)/\(name)/releases/latest") + } + /// A request for the release corresponding to the given tag. /// /// If the tag exists, but there's not a correspoding GitHub Release, this will result in a - /// `.DoesNotExist` error. This is indistinguishable from a nonexistent tag. + /// `.doesNotExist` error. This is indistinguishable from a nonexistent tag. /// /// https://developer.github.com/v3/repos/releases/#get-a-release-by-tag-name public func release(forTag tag: String) -> Request { diff --git a/Tentacle.xcodeproj/project.pbxproj b/Tentacle.xcodeproj/project.pbxproj index 9b59a86..412d6fa 100644 --- a/Tentacle.xcodeproj/project.pbxproj +++ b/Tentacle.xcodeproj/project.pbxproj @@ -167,6 +167,10 @@ BE1E036C1C9AD87F001296C2 /* ResponseTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = BE1E036A1C9AD87F001296C2 /* ResponseTests.swift */; }; BE2B6A6C1C8B854F0080BFEB /* ClientTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = BE2B6A6B1C8B854F0080BFEB /* ClientTests.swift */; }; BE2B6A6D1C8B854F0080BFEB /* ClientTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = BE2B6A6B1C8B854F0080BFEB /* ClientTests.swift */; }; + BE424662222D5FDB0033D475 /* repos-mdiep-MDPSplitView-releases-latest.data in Resources */ = {isa = PBXBuildFile; fileRef = BE424660222D5FDB0033D475 /* repos-mdiep-MDPSplitView-releases-latest.data */; }; + BE424663222D5FDB0033D475 /* repos-mdiep-MDPSplitView-releases-latest.data in Resources */ = {isa = PBXBuildFile; fileRef = BE424660222D5FDB0033D475 /* repos-mdiep-MDPSplitView-releases-latest.data */; }; + BE424664222D5FDB0033D475 /* repos-mdiep-MDPSplitView-releases-latest.response in Resources */ = {isa = PBXBuildFile; fileRef = BE424661222D5FDB0033D475 /* repos-mdiep-MDPSplitView-releases-latest.response */; }; + BE424665222D5FDB0033D475 /* repos-mdiep-MDPSplitView-releases-latest.response in Resources */ = {isa = PBXBuildFile; fileRef = BE424661222D5FDB0033D475 /* repos-mdiep-MDPSplitView-releases-latest.response */; }; BE88E7F61C88C6B30034A112 /* Tentacle.h in Headers */ = {isa = PBXBuildFile; fileRef = BE88E7F51C88C6B30034A112 /* Tentacle.h */; settings = {ATTRIBUTES = (Public, ); }; }; BE88E7FD1C88C6B30034A112 /* Tentacle.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = BE88E7F21C88C6B30034A112 /* Tentacle.framework */; }; BE88E80D1C88C72B0034A112 /* Client.swift in Sources */ = {isa = PBXBuildFile; fileRef = BE88E80C1C88C72B0034A112 /* Client.swift */; }; @@ -307,6 +311,8 @@ BE0F40A11C8909EB00E3B11A /* ReleaseTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ReleaseTests.swift; sourceTree = ""; }; BE1E036A1C9AD87F001296C2 /* ResponseTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ResponseTests.swift; sourceTree = ""; }; BE2B6A6B1C8B854F0080BFEB /* ClientTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ClientTests.swift; sourceTree = ""; }; + BE424660222D5FDB0033D475 /* repos-mdiep-MDPSplitView-releases-latest.data */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; path = "repos-mdiep-MDPSplitView-releases-latest.data"; sourceTree = ""; }; + BE424661222D5FDB0033D475 /* repos-mdiep-MDPSplitView-releases-latest.response */ = {isa = PBXFileReference; lastKnownFileType = file.bplist; path = "repos-mdiep-MDPSplitView-releases-latest.response"; sourceTree = ""; }; BE88E7F21C88C6B30034A112 /* Tentacle.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Tentacle.framework; sourceTree = BUILT_PRODUCTS_DIR; }; BE88E7F51C88C6B30034A112 /* Tentacle.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Tentacle.h; sourceTree = ""; }; BE88E7F71C88C6B30034A112 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; @@ -388,21 +394,7 @@ BE0F40961C8908CB00E3B11A /* Fixtures */ = { isa = PBXGroup; children = ( - 7AFB05641FDCAB4F00C3414D /* repos-Palleas-opensource-Sample-repository-issues-1.data */, - 7AFB05651FDCAB4F00C3414D /* repos-Palleas-opensource-Sample-repository-issues-1.response */, - 7A8BA1531FCF765A003241C7 /* repos-mdiep-Tentacle.data */, - 7A8BA1521FCF7659003241C7 /* repos-mdiep-Tentacle.response */, - 7A8A9D671E5548070009DA9E /* repos-Carthage-ReactiveTask-branches.data */, - 7A8A9D681E5548070009DA9E /* repos-Carthage-ReactiveTask-branches.response */, 928DF21D1E0E692600E6DE35 /* create-file-sample-response.data */, - 7A3CC6361E01BC200025E711 /* repos-mdiep-Tentacle-contents-Carthage-Checkouts-ReactiveSwift.data */, - 7A3CC6371E01BC200025E711 /* repos-mdiep-Tentacle-contents-Carthage-Checkouts-ReactiveSwift.response */, - 7A3CC6381E01BC200025E711 /* repos-Palleas-opensource-Sample-repository-contents-README.md.data */, - 7A3CC6391E01BC200025E711 /* repos-Palleas-opensource-Sample-repository-contents-README.md.response */, - 7A3CC63A1E01BC200025E711 /* repos-Palleas-opensource-Sample-repository-contents-Tools-say.data */, - 7A3CC63B1E01BC200025E711 /* repos-Palleas-opensource-Sample-repository-contents-Tools-say.response */, - 7A3CC63C1E01BC200025E711 /* repos-Palleas-opensource-Sample-repository-contents-Tools.data */, - 7A3CC63D1E01BC200025E711 /* repos-Palleas-opensource-Sample-repository-contents-Tools.response */, 7A3CC63E1E01BC200025E711 /* orgs-raccommunity-repos.data */, 7A3CC63F1E01BC200025E711 /* orgs-raccommunity-repos.response */, 7A3CC6401E01BC200025E711 /* repos-Carthage-Carthage-releases-tags-0.15.data */, @@ -411,30 +403,46 @@ 7A3CC6431E01BC200025E711 /* repos-Carthage-Carthage-releases.page-1-per_page-30.response */, 7A3CC6441E01BC200025E711 /* repos-Carthage-Carthage-releases.page-2-per_page-30.data */, 7A3CC6451E01BC200025E711 /* repos-Carthage-Carthage-releases.page-2-per_page-30.response */, + 7A8A9D671E5548070009DA9E /* repos-Carthage-ReactiveTask-branches.data */, + 7A8A9D681E5548070009DA9E /* repos-Carthage-ReactiveTask-branches.response */, + 7A3CC6561E01BC200025E711 /* repos-mdiep-MDPSplitView-releases-assets-433845.data */, + 7A3CC6571E01BC200025E711 /* repos-mdiep-MDPSplitView-releases-assets-433845.response */, + BE424660222D5FDB0033D475 /* repos-mdiep-MDPSplitView-releases-latest.data */, + BE424661222D5FDB0033D475 /* repos-mdiep-MDPSplitView-releases-latest.response */, 7A3CC6461E01BC200025E711 /* repos-mdiep-MDPSplitView-releases-tags-1.0.2.data */, 7A3CC6471E01BC200025E711 /* repos-mdiep-MDPSplitView-releases-tags-1.0.2.response */, + 7A3CC6581E01BC200025E711 /* repos-mdiep-NonExistent-releases-tags-tag.data */, + 7A3CC6591E01BC200025E711 /* repos-mdiep-NonExistent-releases-tags-tag.response */, + 7A3CC6361E01BC200025E711 /* repos-mdiep-Tentacle-contents-Carthage-Checkouts-ReactiveSwift.data */, + 7A3CC6371E01BC200025E711 /* repos-mdiep-Tentacle-contents-Carthage-Checkouts-ReactiveSwift.response */, + 7A3CC6541E01BC200025E711 /* repos-mdiep-Tentacle-contents-update-test-fixtures.data */, + 7A3CC6551E01BC200025E711 /* repos-mdiep-Tentacle-contents-update-test-fixtures.response */, + 7A8BA1531FCF765A003241C7 /* repos-mdiep-Tentacle.data */, + 7A8BA1521FCF7659003241C7 /* repos-mdiep-Tentacle.response */, + 7A3CC6381E01BC200025E711 /* repos-Palleas-opensource-Sample-repository-contents-README.md.data */, + 7A3CC6391E01BC200025E711 /* repos-Palleas-opensource-Sample-repository-contents-README.md.response */, + 7A3CC6531E01BC200025E711 /* repos-Palleas-opensource-Sample-repository-contents-say.data */, + 7A3CC6521E01BC200025E711 /* repos-Palleas-opensource-Sample-repository-contents-say.response */, + 7A3CC63A1E01BC200025E711 /* repos-Palleas-opensource-Sample-repository-contents-Tools-say.data */, + 7A3CC63B1E01BC200025E711 /* repos-Palleas-opensource-Sample-repository-contents-Tools-say.response */, + 7A3CC63C1E01BC200025E711 /* repos-Palleas-opensource-Sample-repository-contents-Tools.data */, + 7A3CC63D1E01BC200025E711 /* repos-Palleas-opensource-Sample-repository-contents-Tools.response */, + BF5691C21EAE6F9600A92D3E /* repos-Palleas-opensource-Sample-repository-git-trees-0c0dfafa361836e11aedcbb95c1f05d3f654aef0.data */, + BF5691C31EAE6F9600A92D3E /* repos-Palleas-opensource-Sample-repository-git-trees-0c0dfafa361836e11aedcbb95c1f05d3f654aef0.response */, 7A3CC6481E01BC200025E711 /* repos-Palleas-Opensource-Sample-repository-issues-1-comments.data */, 7A3CC6491E01BC200025E711 /* repos-Palleas-Opensource-Sample-repository-issues-1-comments.response */, + 7AFB05641FDCAB4F00C3414D /* repos-Palleas-opensource-Sample-repository-issues-1.data */, + 7AFB05651FDCAB4F00C3414D /* repos-Palleas-opensource-Sample-repository-issues-1.response */, 7A3CC64A1E01BC200025E711 /* repos-Palleas-opensource-Sample-repository-issues.data */, 7A3CC64B1E01BC200025E711 /* repos-Palleas-opensource-Sample-repository-issues.response */, + 7A3CC65A1E01BC200025E711 /* repos-torvalds-linux-releases-tags-v4.4.data */, + 7A3CC65B1E01BC200025E711 /* repos-torvalds-linux-releases-tags-v4.4.response */, 7A3CC64C1E01BC200025E711 /* users-mdiep.data */, 7A3CC64D1E01BC200025E711 /* users-mdiep.response */, 7A3CC64E1E01BC200025E711 /* users-Palleas-Opensource-repos.data */, 7A3CC64F1E01BC200025E711 /* users-Palleas-Opensource-repos.response */, 7A3CC6501E01BC200025E711 /* users-test.data */, 7A3CC6511E01BC200025E711 /* users-test.response */, - 7A3CC6521E01BC200025E711 /* repos-Palleas-opensource-Sample-repository-contents-say.response */, - 7A3CC6531E01BC200025E711 /* repos-Palleas-opensource-Sample-repository-contents-say.data */, - 7A3CC6541E01BC200025E711 /* repos-mdiep-Tentacle-contents-update-test-fixtures.data */, - 7A3CC6551E01BC200025E711 /* repos-mdiep-Tentacle-contents-update-test-fixtures.response */, - 7A3CC6561E01BC200025E711 /* repos-mdiep-MDPSplitView-releases-assets-433845.data */, - 7A3CC6571E01BC200025E711 /* repos-mdiep-MDPSplitView-releases-assets-433845.response */, - 7A3CC6581E01BC200025E711 /* repos-mdiep-NonExistent-releases-tags-tag.data */, - 7A3CC6591E01BC200025E711 /* repos-mdiep-NonExistent-releases-tags-tag.response */, - 7A3CC65A1E01BC200025E711 /* repos-torvalds-linux-releases-tags-v4.4.data */, - 7A3CC65B1E01BC200025E711 /* repos-torvalds-linux-releases-tags-v4.4.response */, - BF5691C21EAE6F9600A92D3E /* repos-Palleas-opensource-Sample-repository-git-trees-0c0dfafa361836e11aedcbb95c1f05d3f654aef0.data */, - BF5691C31EAE6F9600A92D3E /* repos-Palleas-opensource-Sample-repository-git-trees-0c0dfafa361836e11aedcbb95c1f05d3f654aef0.response */, ); path = Fixtures; sourceTree = ""; @@ -735,6 +743,7 @@ 7A3CC69F1E01BC200025E711 /* repos-mdiep-MDPSplitView-releases-assets-433845.response in Resources */, 7A8A9D6A1E5548070009DA9E /* repos-Carthage-ReactiveTask-branches.data in Resources */, BF5691C71EAE6F9600A92D3E /* repos-Palleas-opensource-Sample-repository-git-trees-0c0dfafa361836e11aedcbb95c1f05d3f654aef0.response in Resources */, + BE424665222D5FDB0033D475 /* repos-mdiep-MDPSplitView-releases-latest.response in Resources */, 7A3CC6771E01BC200025E711 /* repos-Carthage-Carthage-releases.page-1-per_page-30.response in Resources */, 7A3CC6751E01BC200025E711 /* repos-Carthage-Carthage-releases.page-1-per_page-30.data in Resources */, 7A3CC66F1E01BC200025E711 /* orgs-raccommunity-repos.response in Resources */, @@ -771,6 +780,7 @@ 7A3CC69B1E01BC200025E711 /* repos-mdiep-Tentacle-contents-update-test-fixtures.response in Resources */, 7A3CC6851E01BC200025E711 /* repos-Palleas-opensource-Sample-repository-issues.data in Resources */, 7A3CC6831E01BC200025E711 /* repos-Palleas-Opensource-Sample-repository-issues-1-comments.response in Resources */, + BE424663222D5FDB0033D475 /* repos-mdiep-MDPSplitView-releases-latest.data in Resources */, 7A3CC6871E01BC200025E711 /* repos-Palleas-opensource-Sample-repository-issues.response in Resources */, 7A3CC67D1E01BC200025E711 /* repos-mdiep-MDPSplitView-releases-tags-1.0.2.data in Resources */, 7A3CC6671E01BC200025E711 /* repos-Palleas-opensource-Sample-repository-contents-Tools-say.response in Resources */, @@ -796,6 +806,7 @@ 7A3CC69E1E01BC200025E711 /* repos-mdiep-MDPSplitView-releases-assets-433845.response in Resources */, 7A8A9D691E5548070009DA9E /* repos-Carthage-ReactiveTask-branches.data in Resources */, BF5691C61EAE6F9600A92D3E /* repos-Palleas-opensource-Sample-repository-git-trees-0c0dfafa361836e11aedcbb95c1f05d3f654aef0.response in Resources */, + BE424664222D5FDB0033D475 /* repos-mdiep-MDPSplitView-releases-latest.response in Resources */, 7A3CC6761E01BC200025E711 /* repos-Carthage-Carthage-releases.page-1-per_page-30.response in Resources */, 7A3CC6741E01BC200025E711 /* repos-Carthage-Carthage-releases.page-1-per_page-30.data in Resources */, 7A3CC66E1E01BC200025E711 /* orgs-raccommunity-repos.response in Resources */, @@ -832,6 +843,7 @@ 7A3CC69A1E01BC200025E711 /* repos-mdiep-Tentacle-contents-update-test-fixtures.response in Resources */, 7A3CC6841E01BC200025E711 /* repos-Palleas-opensource-Sample-repository-issues.data in Resources */, 7A3CC6821E01BC200025E711 /* repos-Palleas-Opensource-Sample-repository-issues-1-comments.response in Resources */, + BE424662222D5FDB0033D475 /* repos-mdiep-MDPSplitView-releases-latest.data in Resources */, 7A3CC6861E01BC200025E711 /* repos-Palleas-opensource-Sample-repository-issues.response in Resources */, 7A3CC67C1E01BC200025E711 /* repos-mdiep-MDPSplitView-releases-tags-1.0.2.data in Resources */, 7A3CC6661E01BC200025E711 /* repos-Palleas-opensource-Sample-repository-contents-Tools-say.response in Resources */, diff --git a/Tests/TentacleTests/Fixture.swift b/Tests/TentacleTests/Fixture.swift index 0d89b96..974afdd 100644 --- a/Tests/TentacleTests/Fixture.swift +++ b/Tests/TentacleTests/Fixture.swift @@ -142,6 +142,7 @@ struct Fixture { static var allFixtures: [FixtureType] = [ Repositories.Tentacle, + LatestRelease.release, Release.Carthage0_15, Release.MDPSplitView1_0_2, Release.Nonexistent, @@ -168,6 +169,10 @@ struct Fixture { static func fixtureForURL(_ url: URL) -> FixtureType? { return allFixtures.first { $0.url == url } } + + struct LatestRelease { + static let release = Repository(owner: "mdiep", name: "MDPSplitView").latestRelease + } struct Release { static let Carthage0_15 = Repository(owner: "Carthage", name: "Carthage").release(forTag: "0.15") diff --git a/Tests/TentacleTests/Fixtures/repos-mdiep-MDPSplitView-releases-latest.data b/Tests/TentacleTests/Fixtures/repos-mdiep-MDPSplitView-releases-latest.data new file mode 100644 index 0000000..a54a761 --- /dev/null +++ b/Tests/TentacleTests/Fixtures/repos-mdiep-MDPSplitView-releases-latest.data @@ -0,0 +1,74 @@ +{ + "id" : 961251, + "draft" : false, + "published_at" : "2015-02-17T21:35:40Z", + "assets" : [ + { + "id" : 433845, + "uploader" : { + "id" : 432536, + "organizations_url" : "https:\/\/api.github.com\/users\/jspahrsummers\/orgs", + "received_events_url" : "https:\/\/api.github.com\/users\/jspahrsummers\/received_events", + "following_url" : "https:\/\/api.github.com\/users\/jspahrsummers\/following{\/other_user}", + "login" : "jspahrsummers", + "avatar_url" : "https:\/\/avatars0.githubusercontent.com\/u\/432536?v=4", + "url" : "https:\/\/api.github.com\/users\/jspahrsummers", + "node_id" : "MDQ6VXNlcjQzMjUzNg==", + "subscriptions_url" : "https:\/\/api.github.com\/users\/jspahrsummers\/subscriptions", + "repos_url" : "https:\/\/api.github.com\/users\/jspahrsummers\/repos", + "type" : "User", + "html_url" : "https:\/\/github.com\/jspahrsummers", + "events_url" : "https:\/\/api.github.com\/users\/jspahrsummers\/events{\/privacy}", + "site_admin" : false, + "starred_url" : "https:\/\/api.github.com\/users\/jspahrsummers\/starred{\/owner}{\/repo}", + "gists_url" : "https:\/\/api.github.com\/users\/jspahrsummers\/gists{\/gist_id}", + "gravatar_id" : "", + "followers_url" : "https:\/\/api.github.com\/users\/jspahrsummers\/followers" + }, + "label" : null, + "state" : "uploaded", + "created_at" : "2015-02-20T22:44:56Z", + "content_type" : "application\/zip", + "url" : "https:\/\/api.github.com\/repos\/mdiep\/MDPSplitView\/releases\/assets\/433845", + "node_id" : "MDEyOlJlbGVhc2VBc3NldDQzMzg0NQ==", + "size" : 11784, + "updated_at" : "2015-02-20T22:44:57Z", + "browser_download_url" : "https:\/\/github.com\/mdiep\/MDPSplitView\/releases\/download\/1.0.2\/MDPSplitView.framework.zip", + "name" : "MDPSplitView.framework.zip", + "download_count" : 155 + } + ], + "prerelease" : false, + "author" : { + "id" : 1302, + "organizations_url" : "https:\/\/api.github.com\/users\/mdiep\/orgs", + "received_events_url" : "https:\/\/api.github.com\/users\/mdiep\/received_events", + "following_url" : "https:\/\/api.github.com\/users\/mdiep\/following{\/other_user}", + "login" : "mdiep", + "avatar_url" : "https:\/\/avatars2.githubusercontent.com\/u\/1302?v=4", + "url" : "https:\/\/api.github.com\/users\/mdiep", + "node_id" : "MDQ6VXNlcjEzMDI=", + "subscriptions_url" : "https:\/\/api.github.com\/users\/mdiep\/subscriptions", + "repos_url" : "https:\/\/api.github.com\/users\/mdiep\/repos", + "type" : "User", + "html_url" : "https:\/\/github.com\/mdiep", + "events_url" : "https:\/\/api.github.com\/users\/mdiep\/events{\/privacy}", + "site_admin" : false, + "starred_url" : "https:\/\/api.github.com\/users\/mdiep\/starred{\/owner}{\/repo}", + "gists_url" : "https:\/\/api.github.com\/users\/mdiep\/gists{\/gist_id}", + "gravatar_id" : "", + "followers_url" : "https:\/\/api.github.com\/users\/mdiep\/followers" + }, + "created_at" : "2015-02-17T21:34:52Z", + "zipball_url" : "https:\/\/api.github.com\/repos\/mdiep\/MDPSplitView\/zipball\/1.0.2", + "url" : "https:\/\/api.github.com\/repos\/mdiep\/MDPSplitView\/releases\/961251", + "node_id" : "MDc6UmVsZWFzZTk2MTI1MQ==", + "body" : "This release fixes up the bugs introduced in 1.0.1 (#15).\n", + "target_commitish" : "master", + "tarball_url" : "https:\/\/api.github.com\/repos\/mdiep\/MDPSplitView\/tarball\/1.0.2", + "html_url" : "https:\/\/github.com\/mdiep\/MDPSplitView\/releases\/tag\/1.0.2", + "assets_url" : "https:\/\/api.github.com\/repos\/mdiep\/MDPSplitView\/releases\/961251\/assets", + "upload_url" : "https:\/\/uploads.github.com\/repos\/mdiep\/MDPSplitView\/releases\/961251\/assets{?name,label}", + "tag_name" : "1.0.2", + "name" : "1.0.2" +} \ No newline at end of file diff --git a/Tests/TentacleTests/Fixtures/repos-mdiep-MDPSplitView-releases-latest.response b/Tests/TentacleTests/Fixtures/repos-mdiep-MDPSplitView-releases-latest.response new file mode 100644 index 0000000..add750d Binary files /dev/null and b/Tests/TentacleTests/Fixtures/repos-mdiep-MDPSplitView-releases-latest.response differ diff --git a/Tests/TentacleTests/ReleaseTests.swift b/Tests/TentacleTests/ReleaseTests.swift index b184398..3335f52 100644 --- a/Tests/TentacleTests/ReleaseTests.swift +++ b/Tests/TentacleTests/ReleaseTests.swift @@ -35,4 +35,23 @@ class ReleaseTests: XCTestCase { ) XCTAssertEqual(Fixture.Release.Carthage0_15.decode(), expected) } + + func testDecodeLatestRelease() { + let expected = Release( + id: 961251, + tag: "1.0.2", + url: URL(string: "https://github.com/mdiep/MDPSplitView/releases/tag/1.0.2")!, + name: "1.0.2", + assets: [ + Release.Asset( + id: 433845, + name: "MDPSplitView.framework.zip", + contentType: "application/zip", + url: URL(string: "https://github.com/mdiep/MDPSplitView/releases/download/1.0.2/MDPSplitView.framework.zip")!, + apiURL: URL(string: "https://api.github.com/repos/mdiep/MDPSplitView/releases/assets/433845")! + ), + ] + ) + XCTAssertEqual(Fixture.LatestRelease.release.decode(), expected) + } }