├── .gitignore ├── .travis.yml ├── package.json ├── .jshintrc ├── scripts └── update-readme.js ├── .jscsrc ├── index.js ├── bench.js ├── README.md ├── type.js └── test.js /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | .DS_Store 3 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | env: CI=true 3 | sudo: false 4 | node_js: 5 | - '0.10' 6 | before_script: 7 | - npm install mocha 8 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "github-page-type", 3 | "version": "0.1.1", 4 | "description": "", 5 | "main": "index.js", 6 | "scripts": { 7 | "test": "mocha", 8 | "bench": "matcha bench.js" 9 | }, 10 | "author": "Stefan Buck", 11 | "license": "MIT", 12 | "devDependencies": { 13 | "matcha": "^0.6.0" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /.jshintrc: -------------------------------------------------------------------------------- 1 | { 2 | "node": true, 3 | "esnext": true, 4 | "bitwise": false, 5 | "curly": false, 6 | "eqeqeq": true, 7 | "eqnull": true, 8 | "immed": true, 9 | "latedef": false, 10 | "newcap": true, 11 | "noarg": true, 12 | "undef": true, 13 | "strict": true, 14 | "quotmark": "single", 15 | "scripturl": true, 16 | "globals": { 17 | "require": false, 18 | "describe": false, 19 | "it": false, 20 | "before": false, 21 | "beforeEach": false, 22 | "after": false, 23 | "afterEach": false, 24 | "suite": false, 25 | "bench": false 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /scripts/update-readme.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | const path = require('path'); 4 | const fs = require('fs'); 5 | const types = require('../type.js'); 6 | const filePath = path.resolve(__dirname, '../README.md'); 7 | const readme = fs.readFileSync(filePath, 'utf-8'); 8 | 9 | const headerIndicator = '---|---'; 10 | const footerIndicator = '## License'; 11 | const startIndex = readme.indexOf(headerIndicator) + headerIndicator.length; 12 | const endIndex = readme.indexOf(footerIndicator); 13 | 14 | const header = readme.slice(0, startIndex); 15 | const footer = readme.slice(endIndex); 16 | 17 | let typeString = ''; 18 | types.forEach(function (type) { 19 | typeString += `${type.name}|${type.sample}\n`; 20 | }); 21 | 22 | fs.writeFileSync(filePath, `${header} 23 | ${typeString} 24 | 25 | 26 | ${footer}`, 'utf-8'); 27 | -------------------------------------------------------------------------------- /.jscsrc: -------------------------------------------------------------------------------- 1 | { 2 | "requireCurlyBraces": ["else", "for", "while", "do", "try", "catch"], 3 | "requireSpaceAfterKeywords": ["if", "else", "for", "while", "do", "switch", "return", "try", "catch", "function"], 4 | "requireSpacesInFunctionExpression": { 5 | "beforeOpeningCurlyBrace": true 6 | }, 7 | "disallowMultipleVarDecl": false, 8 | "requireSpacesInsideObjectBrackets": "allButNested", 9 | "disallowSpacesInsideArrayBrackets": true, 10 | "disallowSpacesInsideParentheses": true, 11 | "disallowSpaceAfterObjectKeys": true, 12 | "disallowQuotedKeysInObjects": true, 13 | "requireSpaceBeforeBinaryOperators": ["?", "+", "/", "*", "=", "==", "===", "!=", "!==", ">", ">=", "<", "<="], 14 | "disallowSpaceAfterBinaryOperators": ["!"], 15 | "requireSpaceAfterBinaryOperators": ["?", ",", "+", "/", "*", ":", "=", "==", "===", "!=", "!==", ">", ">=", "<", "<="], 16 | "disallowSpaceBeforeBinaryOperators": [","], 17 | "disallowSpaceAfterPrefixUnaryOperators": ["++", "--", "+", "-", "~", "!"], 18 | "disallowSpaceBeforePostfixUnaryOperators": ["++", "--"], 19 | "requireSpaceBeforeBinaryOperators": ["+", "-", "/", "*", "=", "==", "===", "!=", "!=="], 20 | "requireSpaceAfterBinaryOperators": ["+", "-", "/", "*", "=", "==", "===", "!=", "!=="], 21 | "disallowImplicitTypeConversion": ["numeric", "binary", "string"], 22 | "disallowKeywords": ["with", "eval"], 23 | "disallowMultipleLineBreaks": true, 24 | "disallowKeywordsOnNewLine": ["else"], 25 | "requireLineFeedAtFileEnd": true, 26 | "excludeFiles": ["node_modules/**", "bower_components/**"], 27 | "validateIndentation": 2 28 | } 29 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var urlParse = require('url').parse; 4 | var Type = require('./type.js'); 5 | 6 | function executeTest(test, urlObj) { 7 | if (test.pathname) { 8 | return urlObj.pathname === test.pathname; 9 | } else if (typeof test === 'function') { 10 | return test(urlObj); 11 | } 12 | } 13 | 14 | function getTypeFromURL (urlObj, list) { 15 | for (var i = 0; i < list.length; i++) { 16 | var rule = list[i]; 17 | 18 | if (executeTest(rule.test, urlObj)) { 19 | return rule.name; 20 | } 21 | } 22 | return null; 23 | } 24 | 25 | var GitHubPageType = function (url, isFromType) { 26 | if (!url) { 27 | throw new Error('Missing argument url'); 28 | } 29 | 30 | var urlObj = urlParse(url); 31 | if (!urlObj.hostname.match(/github\.com$/)) { 32 | throw new Error('hostname is not github.com'); 33 | } 34 | 35 | if (urlObj.pathname.length > 1) { 36 | var paths = urlObj.pathname.slice(1); 37 | if (paths.charAt(paths.length - 1) === '/') { 38 | paths = paths.slice(0, -1); 39 | } 40 | urlObj.pathlist = paths.split('/'); 41 | } else { 42 | urlObj.pathlist = []; 43 | } 44 | 45 | var result, 46 | lookup = Type; 47 | 48 | if (isFromType) { 49 | if (!Array.isArray(isFromType)) { 50 | isFromType = [isFromType]; 51 | } 52 | 53 | lookup = Type.filter(function (item) { 54 | return isFromType.indexOf(item.name) !== -1; 55 | }); 56 | } 57 | 58 | result = getTypeFromURL(urlObj, lookup); 59 | 60 | if (isFromType) { 61 | return !!result; 62 | } 63 | 64 | return result; 65 | }; 66 | 67 | // Add constants 68 | for (var i = 0; i < Type.length; i++) { 69 | var name = Type[i].name; 70 | GitHubPageType[name] = name; 71 | } 72 | 73 | module.exports = GitHubPageType; 74 | -------------------------------------------------------------------------------- /bench.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var ghType = require('./index.js'); 4 | 5 | suite('dynamic', function () { 6 | bench('user', function () { 7 | ghType('https://github.com/user'); 8 | }); 9 | bench('user/repo', function () { 10 | ghType('https://github.com/user/repo'); 11 | }); 12 | bench('user/repo/search', function () { 13 | ghType('https://github.com/user/repo/search'); 14 | }); 15 | }); 16 | 17 | suite('static', function () { 18 | bench('home', function () { 19 | ghType('https://github.com'); 20 | }); 21 | bench('blog', function () { 22 | ghType('https://github.com/blog'); 23 | }); 24 | bench('explore', function () { 25 | ghType('https://github.com/explore'); 26 | }); 27 | bench('notifications', function () { 28 | ghType('https://github.com/notifications'); 29 | }); 30 | bench('showcases', function () { 31 | ghType('https://github.com/showcases'); 32 | }); 33 | bench('stars', function () { 34 | ghType('https://github.com/stars'); 35 | }); 36 | bench('trending', function () { 37 | ghType('https://github.com/trending'); 38 | }); 39 | bench('watching', function () { 40 | ghType('https://github.com/watching'); 41 | }); 42 | bench('search', function () { 43 | ghType('https://github.com/search'); 44 | }); 45 | bench('settings/admin', function () { 46 | ghType('https://github.com/settings/admin'); 47 | }); 48 | bench('settings/applications', function () { 49 | ghType('https://github.com/settings/applications'); 50 | }); 51 | bench('settings/billing', function () { 52 | ghType('https://github.com/settings/billing'); 53 | }); 54 | bench('settings/emails', function () { 55 | ghType('https://github.com/settings/emails'); 56 | }); 57 | bench('settings/notifications', function () { 58 | ghType('https://github.com/settings/notifications'); 59 | }); 60 | bench('settings/organizations', function () { 61 | ghType('https://github.com/settings/organizations'); 62 | }); 63 | bench('settings/profile', function () { 64 | ghType('https://github.com/settings/profile'); 65 | }); 66 | bench('settings/repositories', function () { 67 | ghType('https://github.com/settings/repositories'); 68 | }); 69 | bench('settings/security', function () { 70 | ghType('https://github.com/settings/security'); 71 | }); 72 | bench('settings/ssh', function () { 73 | ghType('https://github.com/settings/ssh'); 74 | }); 75 | }); 76 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # github-page-type 2 | [![NPM version][npm-image]][npm-url] [![Build Status][travis-image]][travis-url] 3 | 4 | Returns a page type for the given github url. 5 | 6 | 7 | 8 | ## Install 9 | 10 | ```bash 11 | $ npm install --save github-page-type 12 | ``` 13 | 14 | 15 | 16 | ## Usage 17 | 18 | ```js 19 | githubPageType('https://github.com/octo-linker'); 20 | // => USER_ORGANIZATION_PROFILE 21 | 22 | githubPageType('https://github.com/blog'); 23 | // => BLOG 24 | 25 | githubPageType('https://github.com/octo-linker/core'); 26 | // => REPOSITORY 27 | 28 | githubPageType('https://github.com/blog', githubPageType.BLOG); 29 | // => true 30 | 31 | githubPageType('https://github.com/blog', [githubPageType.USER_ORGANIZATION_PROFILE]); 32 | // => false 33 | ``` 34 | 35 | 36 | 37 | ## Available types 38 | 39 | Type|Sample 40 | ---|--- 41 | HOME|https://github.com 42 | EXPLORE|https://github.com/explore 43 | NOTIFICATIONS|https://github.com/notifications 44 | SHOWCASES|https://github.com/showcases 45 | STARS|https://github.com/stars 46 | TRENDING|https://github.com/trending 47 | WATCHING|https://github.com/watching 48 | SEARCH|https://github.com/search 49 | ABOUT|https://github.com/about 50 | CONTACT|https://github.com/contact 51 | FEATURES|https://github.com/features 52 | SETTINGS_ADMIN|https://github.com/settings/admin 53 | SETTINGS_APPLICATIONS|https://github.com/settings/applications 54 | SETTINGS_BILLING|https://github.com/settings/billing 55 | SETTINGS_EMAILS|https://github.com/settings/emails 56 | SETTINGS_NOTIFICATIONS|https://github.com/settings/notifications 57 | SETTINGS_ORGANIZATIONS|https://github.com/settings/organizations 58 | SETTINGS_PROFILE|https://github.com/settings/profile 59 | SETTINGS_REPOSITORIES|https://github.com/settings/repositories 60 | SETTINGS_SECURITY|https://github.com/settings/security 61 | SETTINGS_SSH|https://github.com/settings/ssh 62 | BLOG|https://github.com/blog 63 | USER_ORGANIZATION_PROFILE|https://github.com/user 64 | REPOSITORY|https://github.com/user/repo 65 | REPOSITORY_BLOB|https://github.com/user/repo/blob/master/file 66 | REPOSITORY_TREE|https://github.com/user/repo/tree/master/folder 67 | REPOSITORY_COMMIT|https://github.com/user/repo/commit/4a30c6606465e294d1ae1c9ca394ba03368928f7 68 | REPOSITORY_COMMITS|https://github.com/user/repo/commits/master 69 | REPOSITORY_SEARCH|https://github.com/user/repo/search 70 | REPOSITORY_ISSUES|https://github.com/user/repo/issues 71 | REPOSITORY_ISSUE|https://github.com/user/repo/issues/123 72 | REPOSITORY_PULLS|https://github.com/user/repo/pulls 73 | REPOSITORY_PULL_CONVERSATION|https://github.com/user/repo/pull/123 74 | REPOSITORY_PULL_COMMITS|https://github.com/user/repo/pull/123/commits 75 | REPOSITORY_PULL_FILES|https://github.com/user/repo/pull/123/files 76 | REPOSITORY_COMPARE|https://github.com/user/repo/compare/master...dev 77 | REPOSITORY_COMPARE_OVERVIEW|https://github.com/user/repo/compare 78 | 79 | 80 | 81 | ## License 82 | 83 | Copyright (c) 2015 Stefan Buck. Licensed under the MIT license. 84 | 85 | 86 | 87 | [npm-url]: https://npmjs.org/package/github-page-type 88 | [npm-image]: https://badge.fury.io/js/github-page-type.svg 89 | [travis-url]: https://travis-ci.org/octo-linker/github-page-type 90 | [travis-image]: https://travis-ci.org/octo-linker/github-page-type.svg?branch=master 91 | -------------------------------------------------------------------------------- /type.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var Type = []; 4 | 5 | Type.push({ 6 | name: 'HOME', 7 | test: function (obj) { 8 | return obj.hostname === 'github.com' && obj.pathlist.length === 0; 9 | }, 10 | sample: 'https://github.com' 11 | }); 12 | 13 | var staticTypes = [ 14 | 'explore', 15 | 'notifications', 16 | 'showcases', 17 | 'stars', 18 | 'trending', 19 | 'watching', 20 | 'search', 21 | 'about', 22 | 'contact', 23 | 'features', 24 | 'settings/admin', 25 | 'settings/applications', 26 | 'settings/billing', 27 | 'settings/emails', 28 | 'settings/notifications', 29 | 'settings/organizations', 30 | 'settings/profile', 31 | 'settings/repositories', 32 | 'settings/security', 33 | 'settings/ssh' 34 | ]; 35 | 36 | for (var i = 0; i < staticTypes.length; i++) { 37 | var val = staticTypes[i]; 38 | Type.push({ 39 | name: val.toUpperCase().replace(/\//g, '_'), 40 | test: { 41 | pathname: '/' + val 42 | }, 43 | sample: 'https://github.com/' + val 44 | }); 45 | } 46 | 47 | Type.push({ 48 | name: 'BLOG', 49 | test: function (obj) { 50 | return obj.pathname.match(/^\/blog/); 51 | }, 52 | sample: 'https://github.com/blog' 53 | }); 54 | 55 | Type.push({ 56 | name: 'USER_ORGANIZATION_PROFILE', 57 | test: function (obj) { 58 | return obj.pathlist.length === 1; 59 | }, 60 | sample: 'https://github.com/user' 61 | }); 62 | 63 | Type.push({ 64 | name: 'REPOSITORY', 65 | test: function (obj) { 66 | return obj.pathlist.length === 2; 67 | }, 68 | sample: 'https://github.com/user/repo' 69 | }); 70 | 71 | Type.push({ 72 | name: 'REPOSITORY_BLOB', 73 | test: function (obj) { 74 | return obj.pathlist.length > 4 && obj.pathlist[2] === 'blob'; 75 | }, 76 | sample: 'https://github.com/user/repo/blob/master/file' 77 | }); 78 | 79 | Type.push({ 80 | name: 'REPOSITORY_TREE', 81 | test: function (obj) { 82 | return obj.pathlist.length > 3 && obj.pathlist[2] === 'tree'; 83 | }, 84 | sample: 'https://github.com/user/repo/tree/master/folder' 85 | }); 86 | 87 | Type.push({ 88 | name: 'REPOSITORY_COMMIT', 89 | test: function (obj) { 90 | return obj.pathlist.length === 4 && obj.pathlist[2] === 'commit'; 91 | }, 92 | sample: 'https://github.com/user/repo/commit/4a30c6606465e294d1ae1c9ca394ba03368928f7' 93 | }); 94 | 95 | Type.push({ 96 | name: 'REPOSITORY_COMMITS', 97 | test: function (obj) { 98 | return obj.pathlist.length < 5 && obj.pathlist[2] === 'commits' && !/\b[0-9a-f]{7,40}\b/.test(obj.pathlist[3]); 99 | }, 100 | sample: 'https://github.com/user/repo/commits/master' 101 | }); 102 | 103 | Type.push({ 104 | name: 'REPOSITORY_SEARCH', 105 | test: function (obj) { 106 | return obj.pathlist.length === 3 && obj.pathlist[2] === 'search'; 107 | }, 108 | sample: 'https://github.com/user/repo/search' 109 | }); 110 | 111 | Type.push({ 112 | name: 'REPOSITORY_ISSUES', 113 | test: function (obj) { 114 | return obj.pathlist.length === 3 && obj.pathlist[2] === 'issues'; 115 | }, 116 | sample: 'https://github.com/user/repo/issues' 117 | }); 118 | 119 | Type.push({ 120 | name: 'REPOSITORY_ISSUE', 121 | test: function (obj) { 122 | return obj.pathlist.length === 4 && obj.pathlist[2] === 'issues'; 123 | }, 124 | sample: 'https://github.com/user/repo/issues/123' 125 | }); 126 | 127 | Type.push({ 128 | name: 'REPOSITORY_PULLS', 129 | test: function (obj) { 130 | return obj.pathlist.length === 3 && obj.pathlist[2] === 'pulls'; 131 | }, 132 | sample: 'https://github.com/user/repo/pulls' 133 | }); 134 | 135 | Type.push({ 136 | name: 'REPOSITORY_PULL_CONVERSATION', 137 | test: function (obj) { 138 | return obj.pathlist.length === 4 && obj.pathlist[2] === 'pull'; 139 | }, 140 | sample: 'https://github.com/user/repo/pull/123' 141 | }); 142 | 143 | Type.push({ 144 | name: 'REPOSITORY_PULL_COMMITS', 145 | test: function (obj) { 146 | return obj.pathlist.length === 5 && obj.pathlist[2] === 'pull' && obj.pathlist[4] === 'commits'; 147 | }, 148 | sample: 'https://github.com/user/repo/pull/123/commits' 149 | }); 150 | 151 | Type.push({ 152 | name: 'REPOSITORY_PULL_FILES', 153 | test: function (obj) { 154 | return obj.pathlist.length === 5 && obj.pathlist[2] === 'pull' && obj.pathlist[4] === 'files'; 155 | }, 156 | sample: 'https://github.com/user/repo/pull/123/files' 157 | }); 158 | 159 | Type.push({ 160 | name: 'REPOSITORY_COMPARE', 161 | test: function (obj) { 162 | return obj.pathlist.length === 4 && obj.pathlist[2] === 'compare'; 163 | }, 164 | sample: 'https://github.com/user/repo/compare/master...dev' 165 | }); 166 | 167 | Type.push({ 168 | name: 'REPOSITORY_COMPARE_OVERVIEW', 169 | test: function (obj) { 170 | return obj.pathlist.length === 3 && obj.pathlist[2] === 'compare'; 171 | }, 172 | sample: 'https://github.com/user/repo/compare' 173 | }); 174 | 175 | // TODO add support for: 176 | 177 | // https://github.com/user/repo/branches 178 | // 179 | // https://github.com/orgs/foo/audit-log 180 | // https://github.com/orgs/foo/people 181 | // https://github.com/orgs/foo/teams 182 | // 183 | // https://github.com/settings/organizations/foo/settings/applications 184 | // https://github.com/settings/organizations/foo/settings/billing 185 | // https://github.com/settings/organizations/foo/settings/hooks 186 | // https://github.com/settings/organizations/foo/settings/oauth_application_policy 187 | // https://github.com/settings/organizations/foo/settings/profile 188 | // 189 | // https://github.com/user/repo/branches/active 190 | // https://github.com/user/repo/branches/all 191 | // https://github.com/user/repo/branches/stale 192 | // https://github.com/user/repo/branches/yours 193 | // https://github.com/user/repo/graphs/code-frequency 194 | // https://github.com/user/repo/graphs/commit-activity 195 | // https://github.com/user/repo/graphs/contributors 196 | // https://github.com/user/repo/graphs/punch-card 197 | // https://github.com/user/repo/graphs/traffic 198 | // https://github.com/user/repo/network 199 | // https://github.com/user/repo/network/members 200 | // https://github.com/user/repo/releases 201 | // https://github.com/user/repo/releases/tag/v0.18.9 202 | // https://github.com/user/repo/settings 203 | // https://github.com/user/repo/settings/collaboration 204 | // https://github.com/user/repo/settings/hooks 205 | // https://github.com/user/repo/settings/keys 206 | // https://github.com/user/repo/stargazers 207 | // https://github.com/user/repo/stargazers/you_know 208 | // https://github.com/user/repo/tags 209 | // https://github.com/user/repo/watchers 210 | // https://github.com/user/repo/wiki 211 | // 212 | // https://gist.github.com/user 213 | // https://gist.github.com/user/4a30c6606465e294d1ae1c9ca394ba03368928f7 214 | 215 | module.exports = Type; 216 | -------------------------------------------------------------------------------- /test.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | 3 | var assert = require('assert'); 4 | var ghType = require('./index.js'); 5 | 6 | var isEqualHelper = function (list, value) { 7 | describe(value, function () { 8 | list.forEach(function (url) { 9 | it(url.replace('!', 'not '), function () { 10 | var method = 'equal'; 11 | if (url.charAt(0) === '!') { 12 | method = 'notEqual'; 13 | url = url.slice(1); 14 | } 15 | assert[method](ghType(url), value); 16 | }); 17 | }); 18 | }); 19 | }; 20 | 21 | describe('githubPageType', function () { 22 | 23 | it('throws an error if url is not defined', function () { 24 | assert.throws(ghType.bind(), /Missing argument url/); 25 | }); 26 | 27 | it('throws an error if hostname is not github.com', function () { 28 | assert.throws(ghType.bind(null, 'http://google.com'), /hostname is not github.com/); 29 | }); 30 | 31 | it('takes a github url', function () { 32 | assert.doesNotThrow(ghType.bind(null, 'http://github.com')); 33 | }); 34 | 35 | it('takes an url', function () { 36 | assert.equal(ghType('https://github.com'), 'HOME'); 37 | }); 38 | 39 | it('returns page type', function () { 40 | assert.equal(ghType('https://github.com'), 'HOME'); 41 | }); 42 | 43 | it('returns a true when type was found', function () { 44 | assert.equal(ghType('https://github.com', 'HOME'), true); 45 | }); 46 | 47 | it('returns a false when type was not found', function () { 48 | assert.equal(ghType('https://github.com/user', 'HOME'), false); 49 | }); 50 | 51 | it('takes an array', function () { 52 | assert.equal(ghType('https://github.com', ['HOME']), true); 53 | }); 54 | 55 | describe('type', function () { 56 | 57 | isEqualHelper([ 58 | 'https://github.com/user', 59 | 'https://github.com/user/', 60 | 'https://github.com/us-er', 61 | '!https://github.com/us/er', 62 | ], 'USER_ORGANIZATION_PROFILE'); 63 | 64 | isEqualHelper([ 65 | 'https://github.com/user/repo', 66 | 'https://github.com/user/repo/', 67 | 'https://github.com/us-er/repo', 68 | 'https://github.com/user/re-po', 69 | 'https://github.com/us-er/re-po', 70 | '!https://github.com/user', 71 | '!https://github.com/user/repo/foo', 72 | ], 'REPOSITORY'); 73 | 74 | isEqualHelper([ 75 | 'https://github.com/user/repo/search', 76 | 'https://github.com/user/repo/search/', 77 | 'https://github.com/user/repo/search?utf8=✓&q=foo', 78 | '!https://github.com/search', 79 | '!https://github.com/user/search', 80 | '!https://github.com/user/repo/foo/search', 81 | ], 'REPOSITORY_SEARCH'); 82 | 83 | isEqualHelper([ 84 | 'https://github.com/user/repo/blob/master/.file', 85 | 'https://github.com/user/repo/blob/master/file', 86 | 'https://github.com/user/repo/blob/master/file.js', 87 | 'https://github.com/user/repo/blob/master/folder/.file', 88 | 'https://github.com/user/repo/blob/master/folder/file', 89 | 'https://github.com/user/repo/blob/master/folder/file.js', 90 | 'https://github.com/user/repo/blob/dev/folder/file.js', 91 | 'https://github.com/user/repo/blob/7ce2bf0dfc3e57cf3a2d2cda85224da23a8318b8/file.js', 92 | '!https://github.com/user/repo/blob/master', 93 | '!https://github.com/user/repo/blob/dev', 94 | ], 'REPOSITORY_BLOB'); 95 | 96 | isEqualHelper([ 97 | 'https://github.com/user/repo/tree/master/folder', 98 | 'https://github.com/user/repo/tree/master', 99 | 'https://github.com/user/repo/tree/dev/folder', 100 | 'https://github.com/user/repo/tree/dev', 101 | 'https://github.com/user/repo/tree/7ce2bf0dfc3e57cf3a2d2cda85224da23a8318b8/folder', 102 | '!https://github.com/user/repo/tree', 103 | ], 'REPOSITORY_TREE'); 104 | 105 | isEqualHelper([ 106 | 'https://github.com/user/repo/commit/4a30c6606465e294d1ae1c9ca394ba03368928f7', 107 | 'https://github.com/user/repo/commit/master', 108 | '!https://github.com/user/repo/commits', 109 | '!https://github.com/user/repo/commits/master' 110 | ], 'REPOSITORY_COMMIT'); 111 | 112 | isEqualHelper([ 113 | 'https://github.com/user/repo/commits', 114 | 'https://github.com/user/repo/commits/master', 115 | '!https://github.com/user/repo/commit/4a30c6606465e294d1ae1c9ca394ba03368928f7' 116 | ], 'REPOSITORY_COMMITS'); 117 | 118 | isEqualHelper([ 119 | 'https://github.com/user/repo/issues', 120 | 'https://github.com/user/repo/issues?q=is%3Aissue+is%3Aclosed', 121 | ], 'REPOSITORY_ISSUES'); 122 | 123 | isEqualHelper([ 124 | 'https://github.com/user/repo/issues/1', 125 | 'https://github.com/user/repo/issues/1#ref-commit-3c8959c', 126 | ], 'REPOSITORY_ISSUE'); 127 | 128 | isEqualHelper([ 129 | 'https://github.com/user/repo/pulls', 130 | 'https://github.com/user/repo/pulls?q=is%3Apr+is%3Aclosed', 131 | ], 'REPOSITORY_PULLS'); 132 | 133 | isEqualHelper([ 134 | 'https://github.com/user/repo/pull/123', 135 | 'https://github.com/user/repo/pull/123#issue-56141270', 136 | '!https://github.com/user/repo/pull/123/commits', 137 | '!https://github.com/user/repo/pull/123/files', 138 | ], 'REPOSITORY_PULL_CONVERSATION'); 139 | 140 | isEqualHelper([ 141 | 'https://github.com/user/repo/pull/123/commits', 142 | '!https://github.com/user/repo/pull/123', 143 | '!https://github.com/user/repo/pull/123/files', 144 | ], 'REPOSITORY_PULL_COMMITS'); 145 | 146 | isEqualHelper([ 147 | 'https://github.com/user/repo/pull/123/files', 148 | 'https://github.com/user/repo/pull/123/files?diff=split', 149 | '!https://github.com/user/repo/pull/123', 150 | '!https://github.com/user/repo/pull/123/commits', 151 | ], 'REPOSITORY_PULL_FILES'); 152 | 153 | isEqualHelper([ 154 | 'https://github.com/user/repo/compare/master...dev', 155 | '!https://github.com/user/repo/compare', 156 | ], 'REPOSITORY_COMPARE'); 157 | 158 | isEqualHelper([ 159 | 'https://github.com/user/repo/compare', 160 | '!https://github.com/user/repo/compare/master...dev' 161 | ], 'REPOSITORY_COMPARE_OVERVIEW'); 162 | 163 | isEqualHelper([ 164 | 'http://github.com', 165 | 'https://github.com', 166 | 'https://github.com/', 167 | '!https://github.com/foo', 168 | '!https://foo.github.com', 169 | ], 'HOME'); 170 | 171 | isEqualHelper([ 172 | 'http://github.com/blog', 173 | 'https://github.com/blog/', 174 | 'https://github.com/blog/foo', 175 | '!https://github.com/foo', 176 | ], 'BLOG'); 177 | 178 | isEqualHelper(['http://github.com/explore'], 'EXPLORE'); 179 | isEqualHelper(['http://github.com/notifications'], 'NOTIFICATIONS'); 180 | isEqualHelper(['http://github.com/showcases'], 'SHOWCASES'); 181 | isEqualHelper(['http://github.com/stars'], 'STARS'); 182 | isEqualHelper(['http://github.com/trending'], 'TRENDING'); 183 | isEqualHelper(['http://github.com/watching'], 'WATCHING'); 184 | isEqualHelper(['http://github.com/search'], 'SEARCH'); 185 | isEqualHelper(['http://github.com/about'], 'ABOUT'); 186 | isEqualHelper(['http://github.com/contact'], 'CONTACT'); 187 | isEqualHelper(['http://github.com/features'], 'FEATURES'); 188 | isEqualHelper(['http://github.com/settings/admin'], 'SETTINGS_ADMIN'); 189 | isEqualHelper(['http://github.com/settings/applications'], 'SETTINGS_APPLICATIONS'); 190 | isEqualHelper(['https://github.com/settings/billing'], 'SETTINGS_BILLING'); 191 | isEqualHelper(['https://github.com/settings/emails'], 'SETTINGS_EMAILS'); 192 | isEqualHelper(['https://github.com/settings/notifications'], 'SETTINGS_NOTIFICATIONS'); 193 | isEqualHelper(['https://github.com/settings/organizations'], 'SETTINGS_ORGANIZATIONS'); 194 | isEqualHelper(['https://github.com/settings/profile'], 'SETTINGS_PROFILE'); 195 | isEqualHelper(['https://github.com/settings/repositories'], 'SETTINGS_REPOSITORIES'); 196 | isEqualHelper(['https://github.com/settings/security'], 'SETTINGS_SECURITY'); 197 | isEqualHelper(['https://github.com/settings/ssh'], 'SETTINGS_SSH'); 198 | 199 | }); 200 | }); 201 | --------------------------------------------------------------------------------