diff --git a/.bowerrc b/.bowerrc new file mode 100644 index 00000000..959e1696 --- /dev/null +++ b/.bowerrc @@ -0,0 +1,4 @@ +{ + "directory": "bower_components", + "analytics": false +} diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 00000000..2fe4874a --- /dev/null +++ b/.editorconfig @@ -0,0 +1,33 @@ +# EditorConfig helps developers define and maintain consistent +# coding styles between different editors and IDEs +# editorconfig.org + +root = true + + +[*] +end_of_line = lf +charset = utf-8 +trim_trailing_whitespace = true +insert_final_newline = true +indent_style = space +indent_size = 2 + +[*.js] +indent_style = space +indent_size = 2 + +[*.hbs] +indent_style = space +indent_size = 2 + +[*.css] +indent_style = space +indent_size = 2 + +[*.html] +indent_style = space +indent_size = 2 + +[*.{diff,md}] +trim_trailing_whitespace = false diff --git a/.ember-cli b/.ember-cli new file mode 100644 index 00000000..ee64cfed --- /dev/null +++ b/.ember-cli @@ -0,0 +1,9 @@ +{ + /** + Ember CLI sends analytics information by default. The data is completely + anonymous, but there are times when you might want to disable this behavior. + + Setting `disableAnalytics` to true will prevent any data from being sent. + */ + "disableAnalytics": false +} diff --git a/.gitignore b/.gitignore index ec47c7b9..20b90e33 100644 --- a/.gitignore +++ b/.gitignore @@ -1,15 +1,15 @@ -/.bundle -/config/travis.yml +# compiled output +/dist /tmp -.sass-cache -.localeapp/key -/assets/scripts/config/locales.js -.DS_Store -*.sw[op] -/public/images -/public/scripts -/public/styles/app.css -/public/styles/dashboard.css -/public/version -vendor/bundle +# dependencies +/node_modules +/bower_components + +# misc +/.sass-cache +/connect.lock +/coverage/* +/libpeerconnection.log +npm-debug.log +testem.log diff --git a/.jshintrc b/.jshintrc new file mode 100644 index 00000000..08096eff --- /dev/null +++ b/.jshintrc @@ -0,0 +1,32 @@ +{ + "predef": [ + "document", + "window", + "-Promise" + ], + "browser": true, + "boss": true, + "curly": true, + "debug": false, + "devel": true, + "eqeqeq": true, + "evil": true, + "forin": false, + "immed": false, + "laxbreak": false, + "newcap": true, + "noarg": true, + "noempty": false, + "nonew": false, + "nomen": false, + "onevar": false, + "plusplus": false, + "regexp": false, + "undef": true, + "sub": true, + "strict": false, + "white": false, + "eqnull": true, + "esnext": true, + "unused": true +} diff --git a/Brocfile.js b/Brocfile.js new file mode 100644 index 00000000..dad08e20 --- /dev/null +++ b/Brocfile.js @@ -0,0 +1,26 @@ +/* global require, module */ + +var EmberApp = require('ember-cli/lib/broccoli/ember-app'); + +var app = new EmberApp(); + +app.import('bower_components/jquery-timeago/jquery.timeago.js'); +app.import('bower_components/visibilityjs/lib/visibility.core.js'); +app.import('bower_components/visibilityjs/lib/visibility.timers.js'); +app.import('bower_components/JavaScript-MD5/js/md5.js'); +app.import('vendor/ansiparse.js'); +app.import('bower_components/moment/moment.js'); +// Use `app.import` to add additional libraries to the generated +// output files. +// +// If you need to use different assets in different +// environments, specify an object as the first parameter. That +// object's keys should be the environment name and the values +// should be the asset to use in that environment. +// +// If the library that you are including contains AMD or ES6 +// modules that you would like to import into your application +// please specify an object with the list of modules as keys +// along with the exports of each module as its value. + +module.exports = app.toTree(); diff --git a/bower.json b/bower.json new file mode 100644 index 00000000..c1b4d7d9 --- /dev/null +++ b/bower.json @@ -0,0 +1,20 @@ +{ + "name": "travis", + "dependencies": { + "handlebars": "2.0.0", + "jquery": "^1.11.1", + "ember": "1.9.1", + "ember-data": "1.0.0-beta.12", + "ember-resolver": "~0.1.11", + "loader.js": "ember-cli/loader.js#1.0.1", + "ember-cli-shims": "ember-cli/ember-cli-shims#0.0.3", + "ember-cli-test-loader": "ember-cli/ember-cli-test-loader#0.1.0", + "ember-load-initializers": "ember-cli/ember-load-initializers#0.0.2", + "ember-qunit": "0.1.8", + "ember-qunit-notifications": "0.0.5", + "qunit": "~1.17.1", + "visibilityjs": "~1.2.1", + "JavaScript-MD5": "~1.1.0", + "moment": "~2.9.0" + } +} diff --git a/config/environment.js b/config/environment.js new file mode 100644 index 00000000..dbc3c1c9 --- /dev/null +++ b/config/environment.js @@ -0,0 +1,69 @@ +/* jshint node: true */ + +module.exports = function(environment) { + var ENV = { + modulePrefix: 'travis', + environment: environment, + baseURL: '/', + locationType: 'auto', + EmberENV: { + FEATURES: { + // Here you can enable experimental features on an ember canary build + // e.g. 'with-controller': true + } + }, + + APP: { + // Here you can pass flags/options to your application instance + // when it is created + } + }; + + if (environment === 'development') { + // ENV.APP.LOG_RESOLVER = true; + // ENV.APP.LOG_ACTIVE_GENERATION = true; + // ENV.APP.LOG_TRANSITIONS = true; + // ENV.APP.LOG_TRANSITIONS_INTERNAL = true; + // ENV.APP.LOG_VIEW_LOOKUPS = true; + } + + if (environment === 'test') { + // Testem prefers this... + ENV.baseURL = '/'; + ENV.locationType = 'none'; + + // keep test console output quieter + ENV.APP.LOG_ACTIVE_GENERATION = false; + ENV.APP.LOG_VIEW_LOOKUPS = false; + + ENV.APP.rootElement = '#ember-testing'; + } + + if (environment === 'production') { + + } + + ENV.endpoints = { + ssh_key: false, + caches: false + }; + ENV.pro = false; + ENV.pusher = {}; + ENV.intervals = { updateTimes: 1000, times: -1 }; + ENV.api_endpoint = 'https://api.travis-ci.org'; + + ENV.contentSecurityPolicy = { + 'default-src': "'none'", + // TODO: for some reason unsafe-eval is needed when I use collection helper, + // we should probably remove it at some point + 'script-src': "'self' 'unsafe-eval'", + 'font-src': "'self'", + 'connect-src': "'self' https://api.travis-ci.org", + 'img-src': "'self' data: https://www.gravatar.com http://www.gravatar.com", + 'style-src': "'self'", + 'media-src': "'self'", + 'frame-src': "'self' https://api.travis-ci.org" + } + + return ENV; +}; diff --git a/package.json b/package.json new file mode 100644 index 00000000..beecb008 --- /dev/null +++ b/package.json @@ -0,0 +1,39 @@ +{ + "name": "travis", + "version": "0.0.0", + "description": "Small description for travis goes here", + "private": true, + "directories": { + "doc": "doc", + "test": "tests" + }, + "scripts": { + "start": "ember server", + "build": "ember build", + "test": "ember test" + }, + "repository": "", + "engines": { + "node": ">= 0.10.0" + }, + "author": "", + "license": "MIT", + "devDependencies": { + "broccoli-asset-rev": "^2.0.0", + "ember-cli": "0.1.11", + "ember-cli-6to5": "^3.0.0", + "ember-cli-app-version": "0.3.0", + "ember-cli-coffeescript": "0.7.0", + "ember-cli-content-security-policy": "0.3.0", + "ember-cli-dependency-checker": "0.0.7", + "ember-cli-htmlbars": "^0.6.0", + "ember-cli-ic-ajax": "0.1.1", + "ember-cli-inject-live-reload": "^1.3.0", + "ember-cli-qunit": "0.3.0", + "ember-cli-uglify": "1.0.1", + "ember-data": "1.0.0-beta.12", + "ember-export-application-global": "^1.0.0", + "express": "^4.8.5", + "glob": "^4.0.5" + } +} diff --git a/public/crossdomain.xml b/public/crossdomain.xml new file mode 100644 index 00000000..29a035d7 --- /dev/null +++ b/public/crossdomain.xml @@ -0,0 +1,15 @@ + + + + + + + + + + + diff --git a/public/robots.txt b/public/robots.txt new file mode 100644 index 00000000..5debfa4d --- /dev/null +++ b/public/robots.txt @@ -0,0 +1,2 @@ +# http://www.robotstxt.org +User-agent: * diff --git a/testem.json b/testem.json new file mode 100644 index 00000000..42a4ddb2 --- /dev/null +++ b/testem.json @@ -0,0 +1,11 @@ +{ + "framework": "qunit", + "test_page": "tests/index.html?hidepassed", + "launch_in_ci": [ + "PhantomJS" + ], + "launch_in_dev": [ + "PhantomJS", + "Chrome" + ] +} diff --git a/tests/.jshintrc b/tests/.jshintrc new file mode 100644 index 00000000..6ebf71a0 --- /dev/null +++ b/tests/.jshintrc @@ -0,0 +1,74 @@ +{ + "predef": [ + "document", + "window", + "location", + "setTimeout", + "$", + "-Promise", + "QUnit", + "define", + "console", + "equal", + "notEqual", + "notStrictEqual", + "test", + "asyncTest", + "testBoth", + "testWithDefault", + "raises", + "throws", + "deepEqual", + "start", + "stop", + "ok", + "strictEqual", + "module", + "moduleFor", + "moduleForComponent", + "moduleForModel", + "process", + "expect", + "visit", + "exists", + "fillIn", + "click", + "keyEvent", + "triggerEvent", + "find", + "findWithAssert", + "wait", + "DS", + "isolatedContainer", + "startApp", + "andThen", + "currentURL", + "currentPath", + "currentRouteName" + ], + "node": false, + "browser": false, + "boss": true, + "curly": false, + "debug": false, + "devel": false, + "eqeqeq": true, + "evil": true, + "forin": false, + "immed": false, + "laxbreak": false, + "newcap": true, + "noarg": true, + "noempty": false, + "nonew": false, + "nomen": false, + "onevar": false, + "plusplus": false, + "regexp": false, + "undef": true, + "sub": true, + "strict": false, + "white": false, + "eqnull": true, + "esnext": true +} diff --git a/tests/helpers/resolver.js b/tests/helpers/resolver.js new file mode 100644 index 00000000..28f4ece4 --- /dev/null +++ b/tests/helpers/resolver.js @@ -0,0 +1,11 @@ +import Resolver from 'ember/resolver'; +import config from '../../config/environment'; + +var resolver = Resolver.create(); + +resolver.namespace = { + modulePrefix: config.modulePrefix, + podModulePrefix: config.podModulePrefix +}; + +export default resolver; diff --git a/tests/helpers/start-app.js b/tests/helpers/start-app.js new file mode 100644 index 00000000..16cc7c39 --- /dev/null +++ b/tests/helpers/start-app.js @@ -0,0 +1,19 @@ +import Ember from 'ember'; +import Application from '../../app'; +import Router from '../../router'; +import config from '../../config/environment'; + +export default function startApp(attrs) { + var application; + + var attributes = Ember.merge({}, config.APP); + attributes = Ember.merge(attributes, attrs); // use defaults, but you can override; + + Ember.run(function() { + application = Application.create(attributes); + application.setupForTesting(); + application.injectTestHelpers(); + }); + + return application; +} diff --git a/tests/index.html b/tests/index.html new file mode 100644 index 00000000..86513a02 --- /dev/null +++ b/tests/index.html @@ -0,0 +1,33 @@ + + + + + + Travis Tests + + + + {{content-for 'head'}} + {{content-for 'test-head'}} + + + + + + {{content-for 'head-footer'}} + {{content-for 'test-head-footer'}} + + + + {{content-for 'body'}} + {{content-for 'test-body'}} + + + + + + + {{content-for 'body-footer'}} + {{content-for 'test-body-footer'}} + + diff --git a/tests/test-helper.js b/tests/test-helper.js new file mode 100644 index 00000000..e6cfb70f --- /dev/null +++ b/tests/test-helper.js @@ -0,0 +1,6 @@ +import resolver from './helpers/resolver'; +import { + setResolver +} from 'ember-qunit'; + +setResolver(resolver); diff --git a/tests/unit/.gitkeep b/tests/unit/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/tests/unit/initializers/auth-test.coffee b/tests/unit/initializers/auth-test.coffee new file mode 100644 index 00000000..f8c70675 --- /dev/null +++ b/tests/unit/initializers/auth-test.coffee @@ -0,0 +1,19 @@ +`import Ember from 'ember'` +`import { initialize } from 'travis/initializers/auth'` + +container = null +application = null + +module 'AuthInitializer', + setup: -> + Ember.run -> + application = Ember.Application.create() + container = application.__container__ + application.deferReadiness() + +# Replace this with your real tests. +test 'it works', -> + initialize container, application + + # you would normally confirm the results of the initializer here + ok true diff --git a/tests/unit/initializers/config-test.coffee b/tests/unit/initializers/config-test.coffee new file mode 100644 index 00000000..faea5eb8 --- /dev/null +++ b/tests/unit/initializers/config-test.coffee @@ -0,0 +1,19 @@ +`import Ember from 'ember'` +`import { initialize } from 'travis/initializers/config'` + +container = null +application = null + +module 'ConfigInitializer', + setup: -> + Ember.run -> + application = Ember.Application.create() + container = application.__container__ + application.deferReadiness() + +# Replace this with your real tests. +test 'it works', -> + initialize container, application + + # you would normally confirm the results of the initializer here + ok true diff --git a/tests/unit/initializers/storage-test.coffee b/tests/unit/initializers/storage-test.coffee new file mode 100644 index 00000000..81c9a132 --- /dev/null +++ b/tests/unit/initializers/storage-test.coffee @@ -0,0 +1,19 @@ +`import Ember from 'ember'` +`import { initialize } from 'travis/initializers/storage'` + +container = null +application = null + +module 'StorageInitializer', + setup: -> + Ember.run -> + application = Ember.Application.create() + container = application.__container__ + application.deferReadiness() + +# Replace this with your real tests. +test 'it works', -> + initialize container, application + + # you would normally confirm the results of the initializer here + ok true diff --git a/vendor/.gitkeep b/vendor/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/vendor/ansiparse.js b/vendor/ansiparse.js new file mode 100644 index 00000000..692247d7 --- /dev/null +++ b/vendor/ansiparse.js @@ -0,0 +1,186 @@ +ansiparse = function (str) { + // + // I'm terrible at writing parsers. + // + var matchingControl = null, + matchingData = null, + matchingText = '', + ansiState = [], + result = [], + state = {}, + eraseChar; + + // + // General workflow for this thing is: + // \033\[33mText + // | | | + // | | matchingText + // | matchingData + // matchingControl + // + // In further steps we hope it's all going to be fine. It usually is. + // + + // + // Erases a char from the output + // + eraseChar = function () { + var index, text; + if (matchingText.length) { + matchingText = matchingText.substr(0, matchingText.length - 1); + } + else if (result.length) { + index = result.length - 1; + text = result[index].text; + if (text.length === 1) { + // + // A result bit was fully deleted, pop it out to simplify the final output + // + result.pop(); + } + else { + result[index].text = text.substr(0, text.length - 1); + } + } + }; + + for (var i = 0; i < str.length; i++) { + if (matchingControl != null) { + if (matchingControl == '\033' && str[i] == '\[') { + // + // We've matched full control code. Lets start matching formating data. + // + + // + // "emit" matched text with correct state + // + if (matchingText) { + state.text = matchingText; + result.push(state); + state = {}; + matchingText = ""; + } + + matchingControl = null; + matchingData = ''; + } + else { + // + // We failed to match anything - most likely a bad control code. We + // go back to matching regular strings. + // + matchingText += matchingControl + str[i]; + matchingControl = null; + } + continue; + } + else if (matchingData != null) { + if (str[i] == ';') { + // + // `;` separates many formatting codes, for example: `\033[33;43m` + // means that both `33` and `43` should be applied. + // + // TODO: this can be simplified by modifying state here. + // + ansiState.push(matchingData); + matchingData = ''; + } + else if (str[i] == 'm') { + // + // `m` finished whole formatting code. We can proceed to matching + // formatted text. + // + ansiState.push(matchingData); + matchingData = null; + matchingText = ''; + + // + // Convert matched formatting data into user-friendly state object. + // + // TODO: DRY. + // + ansiState.forEach(function (ansiCode) { + if (ansiparse.foregroundColors[ansiCode]) { + state.foreground = ansiparse.foregroundColors[ansiCode]; + } + else if (ansiparse.backgroundColors[ansiCode]) { + state.background = ansiparse.backgroundColors[ansiCode]; + } + else if (ansiCode == 39) { + delete state.foreground; + } + else if (ansiCode == 49) { + delete state.background; + } + else if (ansiparse.styles[ansiCode]) { + state[ansiparse.styles[ansiCode]] = true; + } + else if (ansiCode == 22) { + state.bold = false; + } + else if (ansiCode == 23) { + state.italic = false; + } + else if (ansiCode == 24) { + state.underline = false; + } + }); + ansiState = []; + } + else { + matchingData += str[i]; + } + continue; + } + + if (str[i] == '\033') { + matchingControl = str[i]; + } + else if (str[i] == '\u0008') { + eraseChar(); + } + else { + matchingText += str[i]; + } + } + + if (matchingText) { + state.text = matchingText + (matchingControl ? matchingControl : ''); + result.push(state); + } + return result; +} + +ansiparse.foregroundColors = { + '30': 'black', + '31': 'red', + '32': 'green', + '33': 'yellow', + '34': 'blue', + '35': 'magenta', + '36': 'cyan', + '37': 'white', + '90': 'grey' +}; + +ansiparse.backgroundColors = { + '40': 'black', + '41': 'red', + '42': 'green', + '43': 'yellow', + '44': 'blue', + '45': 'magenta', + '46': 'cyan', + '47': 'white' +}; + +ansiparse.styles = { + '1': 'bold', + '3': 'italic', + '4': 'underline' +}; + +if (typeof module == "object" && typeof window == "undefined") { + module.exports = ansiparse; +} +