From 9a6989e67f2de11c40f661a80089a0780d64bdcd Mon Sep 17 00:00:00 2001 From: Nikko Pisciotti Date: Wed, 22 Mar 2017 13:43:30 -0700 Subject: [PATCH 1/6] added scaffold and dependencies, also index.html --- .babelrc | 3 ++ .eslintignore | 5 ++ .eslintrc | 22 ++++++++ .gitignore | 132 ++++++++++++++++++++++++++++++++++++++++++++++ app/entry.js | 0 app/index.html | 70 ++++++++++++++++++++++++ karma.conf.js | 69 ++++++++++++++++++++++++ package.json | 44 ++++++++++++++++ webpack.config.js | 4 ++ 9 files changed, 349 insertions(+) create mode 100644 .babelrc create mode 100644 .eslintignore create mode 100644 .eslintrc create mode 100644 .gitignore create mode 100644 app/entry.js create mode 100644 app/index.html create mode 100644 karma.conf.js create mode 100644 package.json create mode 100644 webpack.config.js diff --git a/.babelrc b/.babelrc new file mode 100644 index 0000000..c13c5f6 --- /dev/null +++ b/.babelrc @@ -0,0 +1,3 @@ +{ + "presets": ["es2015"] +} diff --git a/.eslintignore b/.eslintignore new file mode 100644 index 0000000..6738afc --- /dev/null +++ b/.eslintignore @@ -0,0 +1,5 @@ +/node_modules + +*.md + +npm-debug.log diff --git a/.eslintrc b/.eslintrc new file mode 100644 index 0000000..2b88e95 --- /dev/null +++ b/.eslintrc @@ -0,0 +1,22 @@ +{ + "rules": { + "no-console": "off", + "indent": [ "error", 2 ], + "quotes": [ "error", "single" ], + "semi": ["error", "always"], + "linebreak-style": [ "error", "unix" ], + # "no-unused-vars": [2, {"vars": "local", "args": "after-used"}] + }, + "env": { + "es6": true, + "node": true, + "mocha": true, + "jasmine": true + }, + "ecmaFeatures": { + "modules": true, + "experimentalObjectRestSpread": true, + "impliedStrict": true + }, + "extends": "eslint:recommended" +} diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..4785718 --- /dev/null +++ b/.gitignore @@ -0,0 +1,132 @@ + +# Created by https://www.gitignore.io/api/node,osx,windows,linux + +### Linux ### +*~ + +#Build (webpack) +build/ + +# temporary files which can be created if a process still has a handle open of a deleted file +.fuse_hidden* + +# KDE directory preferences +.directory + +# Linux trash folder which might appear on any partition or disk +.Trash-* + +# .nfs files are created when an open file is removed but is still being accessed +.nfs* + +### Node ### +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* + +# Runtime data +pids +*.pid +*.seed +*.pid.lock + +# Directory for instrumented libs generated by jscoverage/JSCover +lib-cov + +# Coverage directory used by tools like istanbul +coverage + +# nyc test coverage +.nyc_output + +# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) +.grunt + +# Bower dependency directory (https://bower.io/) +bower_components + +# node-waf configuration +.lock-wscript + +# Compiled binary addons (http://nodejs.org/api/addons.html) +build/Release + +# Dependency directories +node_modules/ +jspm_packages/ + +# Typescript v1 declaration files +typings/ + +# Optional npm cache directory +.npm + +# Optional eslint cache +.eslintcache + +# Optional REPL history +.node_repl_history + +# Output of 'npm pack' +*.tgz + +# Yarn Integrity file +.yarn-integrity + +# dotenv environment variables file +.env + + +### OSX ### +*.DS_Store +.AppleDouble +.LSOverride + +# Icon must end with two \r +Icon + + +# Thumbnails +._* + +# Files that might appear in the root of a volume +.DocumentRevisions-V100 +.fseventsd +.Spotlight-V100 +.TemporaryItems +.Trashes +.VolumeIcon.icns +.com.apple.timemachine.donotpresent + +# Directories potentially created on remote AFP share +.AppleDB +.AppleDesktop +Network Trash Folder +Temporary Items +.apdisk + +### Windows ### +# Windows thumbnail cache files +Thumbs.db +ehthumbs.db +ehthumbs_vista.db + +# Folder config file +Desktop.ini + +# Recycle Bin used on file shares +$RECYCLE.BIN/ + +# Windows Installer files +*.cab +*.msi +*.msm +*.msp + +# Windows shortcuts +*.lnk + +# End of https://www.gitignore.io/api/node,osx,windows,linux diff --git a/app/entry.js b/app/entry.js new file mode 100644 index 0000000..e69de29 diff --git a/app/index.html b/app/index.html new file mode 100644 index 0000000..c347a96 --- /dev/null +++ b/app/index.html @@ -0,0 +1,70 @@ + + + + + MooMoo Tests + + +
+
+ +

cowcontrol.io

+
+ +
+ +
+ +
+

{{ cowsayCtrl.title }}

+

make it, view it, and undo it!

+
+ +
+        {{ cowsayCtrl.update(cowsayCtrl.text) }}
+      
+ +
+

Select a cowfile

+ +

What does it say?

+ +

View it!

+ +
+ +
+ +
+
+

View it!

+

check out the cow you just made!

+
+
+          {{ cowsayCtrl.spoken }}
+        
+
+ +
+
+ +
+ + + + diff --git a/karma.conf.js b/karma.conf.js new file mode 100644 index 0000000..6ae67a7 --- /dev/null +++ b/karma.conf.js @@ -0,0 +1,69 @@ +// Karma configuration +// Generated on Wed Mar 22 2017 13:16:39 GMT-0700 (PDT) + +module.exports = function(config) { + config.set({ + + // base path that will be used to resolve all patterns (eg. files, exclude) + basePath: '', + + + // frameworks to use + // available frameworks: https://npmjs.org/browse/keyword/karma-adapter + frameworks: ['jasmine'], + + + // list of files / patterns to load in the browser + files: [ + '"test/**/*-test.js"' + ], + + + // list of files to exclude + exclude: [ + ], + + + // preprocess matching files before serving them to the browser + // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor + preprocessors: { + }, + + + // test results reporter to use + // possible values: 'dots', 'progress' + // available reporters: https://npmjs.org/browse/keyword/karma-reporter + reporters: ['progress'], + + + // web server port + port: 9876, + + + // enable / disable colors in the output (reporters and logs) + colors: true, + + + // level of logging + // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG + logLevel: config.LOG_INFO, + + + // enable / disable watching file and executing tests whenever any file changes + autoWatch: true, + + + // start these browsers + // available browser launchers: https://npmjs.org/browse/keyword/karma-launcher + browsers: ['PhantomJS'], + + + // Continuous Integration mode + // if true, Karma captures browsers, runs the tests and exits + singleRun: false, + + // Concurrency level + // how many browser should be started simultaneous + concurrency: Infinity + }) +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..83008b1 --- /dev/null +++ b/package.json @@ -0,0 +1,44 @@ +{ + "name": "22-testing_controllers", + "version": "1.0.0", + "description": "![cf](https://i.imgur.com/7v5ASc8.png) Lab 22 - Testing Angular Controllers ======", + "main": "karma.conf.js", + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/npisciotti1/22-testing_controllers.git" + }, + "keywords": [], + "author": "", + "license": "ISC", + "bugs": { + "url": "https://github.com/npisciotti1/22-testing_controllers/issues" + }, + "homepage": "https://github.com/npisciotti1/22-testing_controllers#readme", + "dependencies": { + "angular": "^1.6.3", + "babel-core": "^6.24.0", + "babel-loader": "^6.4.1", + "babel-preset-es2015": "^6.24.0", + "cowsay-browser": "^1.1.8", + "css-loader": "^0.27.3", + "extract-text-webpack-plugin": "^1.0.1", + "html-webpack-plugin": "^2.28.0", + "node-sass": "^4.5.1", + "sass-loader": "^6.0.3", + "style-loader": "^0.16.0", + "webpack": "^1.14.0" + }, + "devDependencies": { + "angular-mocks": "^1.6.3", + "jasmine-core": "^2.5.2", + "karma": "^1.5.0", + "karma-jasmine": "^1.1.0", + "karma-mocha-reporter": "^2.2.3", + "karma-phantomjs-launcher": "^1.0.4", + "karma-webpack": "^2.0.3", + "webpack-dev-server": "^1.16.2" + } +} diff --git a/webpack.config.js b/webpack.config.js new file mode 100644 index 0000000..029279a --- /dev/null +++ b/webpack.config.js @@ -0,0 +1,4 @@ +'use strict'; + +const HTMLPlugin = require('html-webpack-plugin'); +const ExtractTextPlugin = require('extract-text-webpack-plugin'); From 4af33f120c9d6a6c1ce891364eeb09a637c5a167 Mon Sep 17 00:00:00 2001 From: Nikko Pisciotti Date: Wed, 22 Mar 2017 15:05:20 -0700 Subject: [PATCH 2/6] added 3 initial tests for initla properties --- app/entry.js | 63 +++++++++++++ app/scss/main.scss | 171 ++++++++++++++++++++++++++++++++++++ app/scss/reset.scss | 48 ++++++++++ assets/moo-moo-logo.png | Bin 0 -> 8159 bytes assets/muli-font.ttf | Bin 0 -> 94320 bytes karma.conf.js | 60 ++----------- package.json | 5 +- test/cow-controller-test.js | 31 +++++++ test/lib/test-setup.js | 4 + webpack.config.js | 32 +++++++ 10 files changed, 362 insertions(+), 52 deletions(-) create mode 100644 app/scss/main.scss create mode 100644 app/scss/reset.scss create mode 100644 assets/moo-moo-logo.png create mode 100644 assets/muli-font.ttf create mode 100644 test/cow-controller-test.js create mode 100644 test/lib/test-setup.js diff --git a/app/entry.js b/app/entry.js index e69de29..d6167cd 100644 --- a/app/entry.js +++ b/app/entry.js @@ -0,0 +1,63 @@ +'use strict'; + +require('./scss/reset.scss'); +require('./scss/main.scss'); + +const angular = require('angular'); +const cowsay = require('cowsay-browser'); + +const mooMooApp = angular.module('mooMooApp', []); + +mooMooApp.controller('CowsayController', ['$log', CowsayController]); + +function CowsayController($log) { + $log.debug('CowsayController'); + + this.title = 'Cow Creator'; + this.history = []; + + cowsay.list((err, cowfiles) => { + this.cowfiles = cowfiles; + this.current = cowfiles[0]; + }); + + this.update = function(input) { + $log.debug('cowsayCtrl.update'); + return cowsay.say({ text: input || 'cowcontrol.io', f: this.current }); + }; + + this.speak = function(input) { + $log.debug('cowsayCtrl.update'); + + this.spoken = this.update(input); + this.history.push(this.spoken); + }; + + this.undo = function() { + $log.debug('cowsayCtrl.undo'); + + this.history.pop(); + this.spoken = this.history.pop() || ''; + }; +} + +mooMooApp.controller('NavController', ['$log', NavController]); + +function NavController($log) { + $log.debug('NavController'); + + this.routes = [ + { + name: 'Home', + url: '/home' + }, + { + name: 'Cow Creator', + url: '/cow-creator' + }, + { + name: 'Account', + url: '/account' + } + ]; +} diff --git a/app/scss/main.scss b/app/scss/main.scss new file mode 100644 index 0000000..d2a01ae --- /dev/null +++ b/app/scss/main.scss @@ -0,0 +1,171 @@ +$site-primary: #d8d8d8; +$nav-bg: #4a4a4a; +$footer-bg: #9b9b9b; +$header-color: #949494; +$font-color: #484848; + +//:::: base styles ::::// + +//couldnt figure out how to use my custom font =( + +// @font-face { +// font-family: Muli; +// src: url('../../assets/muli-font.ttf') format('ttf'); +// } + +p { + font-family: muli; + color: $font-color; +} + +body { + width: 900px; + height: 100%; + background-color: $site-primary; + margin: auto; + outline: 1px solid black; +} + +//:::: nav & logo styles ::::// + +header { + background-color: $nav-bg; + width: 100%; + height: 8%; + color: $header-color; +} + +.logo-container { + display: inline-block; + margin: 2% 0% 3% 3%; + position: relative; + + h1 { + display: inline-block; + font-size: 22px; + position: absolute; + top: 10px; + left: 50px; + } + + #logo { + display: inline-block; + position: absolute; + } +} + +.nav-bar { + display: inline-block; + margin: 0% 0% 3% 50%; + + ul { + display: inline; + + li { + display: inline; + padding: 0px 10px 0px 10px; + + a { + font-size: 20px; + } + } + } +} + +.nav-link { + font-size: 20px; + text-decoration: none; + color: $header-color; + font-family: sans-serif; +} + + +//:::: content styles ::::// + +.cow-header { + display: block; + width: 100%; + margin: 3% 0 0 17%; + + h2 { + font-size: 20px; + color: #484848; + font-family: sans-serif; + display: inline; + + } + p { + display: inline; + padding: 0 0 0 10px; + } +} + +.cow { + width: 40%; + display: inline-block; + margin: 2% 0 0 18%; + outline: 1px black solid; + font-size: 25px; + color: $font-color; +} + +.opts-container { + margin: auto 20px auto 20px; + width: 20%; + display: inline-block; + + p { + font-size: 18px; + margin-bottom: 10px; + } + + select{ + display: block; + width: 100%; + height: 25px; + margin-bottom: 35px; + border-radiu: 5px; + border: 2px solid black; + } + input { + display: block; + width: 100%; + height: 18px; + margin-bottom: 35px; + border-radius: 5px; + border: 2px solid black; + } + button { + width: 100%; + height: 25px; + display: block; + margin-bottom: 35px; + border-radius: 5px; + border: 2px solid black; + background-color: #4a4a4a; + color: #b0b0b0; + } +} + +.thinline { + display: block; + height: 1px; + width: 75%; + margin: 20px auto 20px auto; + border-top: 1px solid +} + +//:::: footer ::::// + +footer { + height: 90px; + background-color: $footer-bg; + position: relative; + + p { + display: inline-block; + position: absolute; + top: 70%; + left: 89%; + } +} diff --git a/app/scss/reset.scss b/app/scss/reset.scss new file mode 100644 index 0000000..ed11813 --- /dev/null +++ b/app/scss/reset.scss @@ -0,0 +1,48 @@ +/* http://meyerweb.com/eric/tools/css/reset/ + v2.0 | 20110126 + License: none (public domain) +*/ + +html, body, div, span, applet, object, iframe, +h1, h2, h3, h4, h5, h6, p, blockquote, pre, +a, abbr, acronym, address, big, cite, code, +del, dfn, em, img, ins, kbd, q, s, samp, +small, strike, strong, sub, sup, tt, var, +b, u, i, center, +dl, dt, dd, ol, ul, li, +fieldset, form, label, legend, +table, caption, tbody, tfoot, thead, tr, th, td, +article, aside, canvas, details, embed, +figure, figcaption, footer, header, hgroup, +menu, nav, output, ruby, section, summary, +time, mark, audio, video { + margin: 0; + padding: 0; + border: 0; + font-size: 100%; + font: inherit; + vertical-align: baseline; +} +/* HTML5 display-role reset for older browsers */ +article, aside, details, figcaption, figure, +footer, header, hgroup, menu, nav, section { + display: block; +} +body { + line-height: 1; +} +ol, ul { + list-style: none; +} +blockquote, q { + quotes: none; +} +blockquote:before, blockquote:after, +q:before, q:after { + content: ''; + content: none; +} +table { + border-collapse: collapse; + border-spacing: 0; +} diff --git a/assets/moo-moo-logo.png b/assets/moo-moo-logo.png new file mode 100644 index 0000000000000000000000000000000000000000..837e40f3ef336a7e1425aa24a9f9190126c6665e GIT binary patch literal 8159 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 Lbts8Q$G`sor|jUH literal 0 HcmV?d00001 diff --git a/karma.conf.js b/karma.conf.js index 6ae67a7..d4c983d 100644 --- a/karma.conf.js +++ b/karma.conf.js @@ -1,69 +1,27 @@ -// Karma configuration -// Generated on Wed Mar 22 2017 13:16:39 GMT-0700 (PDT) + +const webpackConfig = require('./webpack.config.js'); +webpackConfig.entry = {}; module.exports = function(config) { config.set({ - - // base path that will be used to resolve all patterns (eg. files, exclude) + webpack: webpackConfig, basePath: '', - - - // frameworks to use - // available frameworks: https://npmjs.org/browse/keyword/karma-adapter frameworks: ['jasmine'], - - - // list of files / patterns to load in the browser files: [ - '"test/**/*-test.js"' + 'test/**/*-test.js' ], - - - // list of files to exclude exclude: [ ], - - - // preprocess matching files before serving them to the browser - // available preprocessors: https://npmjs.org/browse/keyword/karma-preprocessor preprocessors: { + 'test/**/*-test.js': ['webpack'] }, - - - // test results reporter to use - // possible values: 'dots', 'progress' - // available reporters: https://npmjs.org/browse/keyword/karma-reporter - reporters: ['progress'], - - - // web server port + reporters: ['mocha'], port: 9876, - - - // enable / disable colors in the output (reporters and logs) colors: true, - - - // level of logging - // possible values: config.LOG_DISABLE || config.LOG_ERROR || config.LOG_WARN || config.LOG_INFO || config.LOG_DEBUG logLevel: config.LOG_INFO, - - - // enable / disable watching file and executing tests whenever any file changes autoWatch: true, - - - // start these browsers - // available browser launchers: https://npmjs.org/browse/keyword/karma-launcher browsers: ['PhantomJS'], - - - // Continuous Integration mode - // if true, Karma captures browsers, runs the tests and exits singleRun: false, - - // Concurrency level - // how many browser should be started simultaneous concurrency: Infinity - }) -} + }); +}; diff --git a/package.json b/package.json index 83008b1..b5c5938 100644 --- a/package.json +++ b/package.json @@ -4,7 +4,10 @@ "description": "![cf](https://i.imgur.com/7v5ASc8.png) Lab 22 - Testing Angular Controllers ======", "main": "karma.conf.js", "scripts": { - "test": "echo \"Error: no test specified\" && exit 1" + "build": "./node_modules/webpack/bin/webpack.js", + "watch": "./node_modules/webpack-dev-server/bin/webpack-dev-server.js --inline --hot", + "test": "./node_modules/karma/bin/karma start --single", + "test-watch": "./node_modules/karma/bin/karma start" }, "repository": { "type": "git", diff --git a/test/cow-controller-test.js b/test/cow-controller-test.js new file mode 100644 index 0000000..16fdd8a --- /dev/null +++ b/test/cow-controller-test.js @@ -0,0 +1,31 @@ +'use strict'; + +require('./lib/test-setup.js'); + +const angular = require('angular'); +const cowsay = require('cowsay-browser'); + +describe('Cowsay Controller', () => { + beforeEach( () => { + angular.mock.module('mooMooApp'); + angular.mock.inject($controller => { + this.cowsayCtrl = new $controller('CowsayController'); + }); + + describe('initial properties', () => { + it('title should be cowcreator.io', () => { + expect(this.cowsayCtrl.title).toBe('cowcreator.io'); + }); + + it('history property should be an empty array', () => { + expect(Array.isArray(this.cowsayCtrl.history)).toBe(true); + }); + + it('list of cowfiles should show proper cowfiles', () => { + cowsay.list((err, cowfiles) => { + expect(this.cowsayCtrl.cowfiles).toEqual(cowfiles); + }); + }); + }); + }); +}); diff --git a/test/lib/test-setup.js b/test/lib/test-setup.js new file mode 100644 index 0000000..4b6e777 --- /dev/null +++ b/test/lib/test-setup.js @@ -0,0 +1,4 @@ +'use strict;' + +require('../../app/entry.js'); +require('angular-mocks'); diff --git a/webpack.config.js b/webpack.config.js index 029279a..4541036 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -2,3 +2,35 @@ const HTMLPlugin = require('html-webpack-plugin'); const ExtractTextPlugin = require('extract-text-webpack-plugin'); + + +module.exports = { + entry: `${__dirname}/app/entry.js`, + output: { + file: 'bundle.js', + path: 'build' + }, + plugins: [ + new HTMLPlugin({ + template: `${__dirname}/app/index.html` + }), + new ExtractTextPlugin('bundle.css') + ], + module: { + loaders: [ + { + test: /\.scss$/, + loader: 'style!css!sass!' + }, + { + test: /\.js$/, + exclude: /node_modules/, + loader: 'babel' + }, + { + test: /\.(eot|woff|ttf|svg).*/, + loader: 'url?limit=10000@name=fonts/[hash].[ext]' + } + ] + } +}; From 68fedc17075a8cc81fd50fb2b602579c5d47615e Mon Sep 17 00:00:00 2001 From: Nikko Pisciotti Date: Wed, 22 Mar 2017 16:03:35 -0700 Subject: [PATCH 3/6] got my .scss partials to work, woohoo --- app/scss/_base.scss | 13 ++ app/scss/_footer.scss | 14 +++ app/scss/_main.scss | 74 ++++++++++++ app/scss/_nav.scss | 52 ++++++++ app/scss/{reset.scss => _reset.scss} | 0 app/scss/_vars.scss | 5 + app/scss/core.scss | 6 + app/scss/main.scss | 171 --------------------------- 8 files changed, 164 insertions(+), 171 deletions(-) create mode 100644 app/scss/_base.scss create mode 100644 app/scss/_footer.scss create mode 100644 app/scss/_main.scss create mode 100644 app/scss/_nav.scss rename app/scss/{reset.scss => _reset.scss} (100%) create mode 100644 app/scss/_vars.scss create mode 100644 app/scss/core.scss delete mode 100644 app/scss/main.scss diff --git a/app/scss/_base.scss b/app/scss/_base.scss new file mode 100644 index 0000000..8fd22b4 --- /dev/null +++ b/app/scss/_base.scss @@ -0,0 +1,13 @@ +//:::: Base Styles ::::// +p { + font-family: muli; + color: $font-color; +} + +body { + width: 900px; + height: 100%; + background-color: $site-primary; + margin: auto; + outline: 1px solid black; +} diff --git a/app/scss/_footer.scss b/app/scss/_footer.scss new file mode 100644 index 0000000..c9136fa --- /dev/null +++ b/app/scss/_footer.scss @@ -0,0 +1,14 @@ +//:::: footer ::::// + +footer { + height: 90px; + background-color: $footer-bg; + position: relative; + + p { + display: inline-block; + position: absolute; + top: 70%; + left: 89%; + } +} diff --git a/app/scss/_main.scss b/app/scss/_main.scss new file mode 100644 index 0000000..3e1ca6c --- /dev/null +++ b/app/scss/_main.scss @@ -0,0 +1,74 @@ +//:::: content styles ::::// + +.cow-header { + display: block; + width: 100%; + margin: 3% 0 0 17%; + + h2 { + font-size: 20px; + color: #484848; + font-family: sans-serif; + display: inline; + + } + p { + display: inline; + padding: 0 0 0 10px; + } +} + +.cow { + width: 40%; + display: inline-block; + margin: 2% 0 0 18%; + outline: 1px black solid; + font-size: 25px; + color: $font-color; +} + +.opts-container { + margin: auto 20px auto 20px; + width: 20%; + display: inline-block; + + p { + font-size: 18px; + margin-bottom: 10px; + } + + select{ + display: block; + width: 100%; + height: 25px; + margin-bottom: 35px; + border-radiu: 5px; + border: 2px solid black; + } + input { + display: block; + width: 100%; + height: 18px; + margin-bottom: 35px; + border-radius: 5px; + border: 2px solid black; + } + button { + width: 100%; + height: 25px; + display: block; + margin-bottom: 35px; + border-radius: 5px; + border: 2px solid black; + background-color: #4a4a4a; + color: #b0b0b0; + } +} + +.thinline { + display: block; + height: 1px; + width: 75%; + margin: 20px auto 20px auto; + border-top: 1px solid +} diff --git a/app/scss/_nav.scss b/app/scss/_nav.scss new file mode 100644 index 0000000..3767876 --- /dev/null +++ b/app/scss/_nav.scss @@ -0,0 +1,52 @@ +//:::: nav & header styles ::::// + +header { + background-color: $nav-bg; + width: 100%; + height: 8%; + color: $header-color; +} + +.logo-container { + display: inline-block; + margin: 2% 0% 3% 3%; + position: relative; + + h1 { + display: inline-block; + font-size: 22px; + position: absolute; + top: 10px; + left: 50px; + } + + #logo { + display: inline-block; + position: absolute; + } +} + +.nav-bar { + display: inline-block; + margin: 0% 0% 3% 50%; + + ul { + display: inline; + + li { + display: inline; + padding: 0px 10px 0px 10px; + + a { + font-size: 20px; + } + } + } +} + +.nav-link { + font-size: 20px; + text-decoration: none; + color: $header-color; + font-family: sans-serif; +} diff --git a/app/scss/reset.scss b/app/scss/_reset.scss similarity index 100% rename from app/scss/reset.scss rename to app/scss/_reset.scss diff --git a/app/scss/_vars.scss b/app/scss/_vars.scss new file mode 100644 index 0000000..ad5b097 --- /dev/null +++ b/app/scss/_vars.scss @@ -0,0 +1,5 @@ +$site-primary: #d8d8d8; +$nav-bg: #4a4a4a; +$font-color: #484848; +$header-color: #949494; +$footer-bg: #9b9b9b; diff --git a/app/scss/core.scss b/app/scss/core.scss new file mode 100644 index 0000000..b342318 --- /dev/null +++ b/app/scss/core.scss @@ -0,0 +1,6 @@ +@import 'vars'; +@import 'reset'; +@import 'base'; +@import 'main'; +@import 'nav'; +@import 'footer'; diff --git a/app/scss/main.scss b/app/scss/main.scss deleted file mode 100644 index d2a01ae..0000000 --- a/app/scss/main.scss +++ /dev/null @@ -1,171 +0,0 @@ -$site-primary: #d8d8d8; -$nav-bg: #4a4a4a; -$footer-bg: #9b9b9b; -$header-color: #949494; -$font-color: #484848; - -//:::: base styles ::::// - -//couldnt figure out how to use my custom font =( - -// @font-face { -// font-family: Muli; -// src: url('../../assets/muli-font.ttf') format('ttf'); -// } - -p { - font-family: muli; - color: $font-color; -} - -body { - width: 900px; - height: 100%; - background-color: $site-primary; - margin: auto; - outline: 1px solid black; -} - -//:::: nav & logo styles ::::// - -header { - background-color: $nav-bg; - width: 100%; - height: 8%; - color: $header-color; -} - -.logo-container { - display: inline-block; - margin: 2% 0% 3% 3%; - position: relative; - - h1 { - display: inline-block; - font-size: 22px; - position: absolute; - top: 10px; - left: 50px; - } - - #logo { - display: inline-block; - position: absolute; - } -} - -.nav-bar { - display: inline-block; - margin: 0% 0% 3% 50%; - - ul { - display: inline; - - li { - display: inline; - padding: 0px 10px 0px 10px; - - a { - font-size: 20px; - } - } - } -} - -.nav-link { - font-size: 20px; - text-decoration: none; - color: $header-color; - font-family: sans-serif; -} - - -//:::: content styles ::::// - -.cow-header { - display: block; - width: 100%; - margin: 3% 0 0 17%; - - h2 { - font-size: 20px; - color: #484848; - font-family: sans-serif; - display: inline; - - } - p { - display: inline; - padding: 0 0 0 10px; - } -} - -.cow { - width: 40%; - display: inline-block; - margin: 2% 0 0 18%; - outline: 1px black solid; - font-size: 25px; - color: $font-color; -} - -.opts-container { - margin: auto 20px auto 20px; - width: 20%; - display: inline-block; - - p { - font-size: 18px; - margin-bottom: 10px; - } - - select{ - display: block; - width: 100%; - height: 25px; - margin-bottom: 35px; - border-radiu: 5px; - border: 2px solid black; - } - input { - display: block; - width: 100%; - height: 18px; - margin-bottom: 35px; - border-radius: 5px; - border: 2px solid black; - } - button { - width: 100%; - height: 25px; - display: block; - margin-bottom: 35px; - border-radius: 5px; - border: 2px solid black; - background-color: #4a4a4a; - color: #b0b0b0; - } -} - -.thinline { - display: block; - height: 1px; - width: 75%; - margin: 20px auto 20px auto; - border-top: 1px solid -} - -//:::: footer ::::// - -footer { - height: 90px; - background-color: $footer-bg; - position: relative; - - p { - display: inline-block; - position: absolute; - top: 70%; - left: 89%; - } -} From 439dfc033e0542a75eeceafe92232d2b22930442 Mon Sep 17 00:00:00 2001 From: Nikko Pisciotti Date: Wed, 22 Mar 2017 16:09:10 -0700 Subject: [PATCH 4/6] forgot my lint script in package.json --- app/scss/_base.scss | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/scss/_base.scss b/app/scss/_base.scss index 8fd22b4..1a3cc38 100644 --- a/app/scss/_base.scss +++ b/app/scss/_base.scss @@ -1,4 +1,6 @@ //:::: Base Styles ::::// +$font-color: #484848; + p { font-family: muli; color: $font-color; From 1e89d5d832feec5912b4d16656711c5a897fe643 Mon Sep 17 00:00:00 2001 From: Nikko Pisciotti Date: Wed, 22 Mar 2017 18:23:10 -0700 Subject: [PATCH 5/6] oops forgot to push last changes, thanks jeff --- app/entry.js | 3 +-- app/index.html | 2 +- package.json | 3 ++- test/cow-controller-test.js | 53 ++++++++++++++++++++++++++++--------- 4 files changed, 45 insertions(+), 16 deletions(-) diff --git a/app/entry.js b/app/entry.js index d6167cd..8788ca7 100644 --- a/app/entry.js +++ b/app/entry.js @@ -1,7 +1,6 @@ 'use strict'; -require('./scss/reset.scss'); -require('./scss/main.scss'); +require('./scss/core.scss'); const angular = require('angular'); const cowsay = require('cowsay-browser'); diff --git a/app/index.html b/app/index.html index c347a96..7a6f645 100644 --- a/app/index.html +++ b/app/index.html @@ -20,7 +20,7 @@

cowcontrol.io

+ ng-init="cowsayCtrl.current = 'default'">

{{ cowsayCtrl.title }}

diff --git a/package.json b/package.json index b5c5938..c126618 100644 --- a/package.json +++ b/package.json @@ -7,7 +7,8 @@ "build": "./node_modules/webpack/bin/webpack.js", "watch": "./node_modules/webpack-dev-server/bin/webpack-dev-server.js --inline --hot", "test": "./node_modules/karma/bin/karma start --single", - "test-watch": "./node_modules/karma/bin/karma start" + "test-watch": "./node_modules/karma/bin/karma start", + "lint": "./node_modules/eslint/bin/eslint.js ./*" }, "repository": { "type": "git", diff --git a/test/cow-controller-test.js b/test/cow-controller-test.js index 16fdd8a..aa1ccd7 100644 --- a/test/cow-controller-test.js +++ b/test/cow-controller-test.js @@ -5,27 +5,56 @@ require('./lib/test-setup.js'); const angular = require('angular'); const cowsay = require('cowsay-browser'); -describe('Cowsay Controller', () => { +describe('Cowsay Controller', function() { beforeEach( () => { angular.mock.module('mooMooApp'); angular.mock.inject($controller => { this.cowsayCtrl = new $controller('CowsayController'); + this.navCtrl = new $controller('NavController'); }); + }); - describe('initial properties', () => { - it('title should be cowcreator.io', () => { - expect(this.cowsayCtrl.title).toBe('cowcreator.io'); - }); + describe('initial properties', () => { + it('title should be cowcreator.io', () => { + expect(this.cowsayCtrl.title).toBe('Cow Creator'); + }); - it('history property should be an empty array', () => { - expect(Array.isArray(this.cowsayCtrl.history)).toBe(true); - }); + it('history property should be an empty array', () => { + expect(Array.isArray(this.cowsayCtrl.history)).toBe(true); + }); - it('list of cowfiles should show proper cowfiles', () => { - cowsay.list((err, cowfiles) => { - expect(this.cowsayCtrl.cowfiles).toEqual(cowfiles); - }); + it('list of cowfiles should show proper cowfiles', () => { + cowsay.list((err, cowfiles) => { + expect(this.cowsayCtrl.cowfiles).toEqual(cowfiles); }); }); }); + + describe('#update', () => { + it('should return a cow that says testing', () => { + let expected = cowsay.say({ text: 'testing', f: this.cowsayCtrl.current }); + let testResult = this.cowsayCtrl.update('testing'); + expect(testResult).toEqual(expected); + }); + }); + + describe('#speak', () => { + it('should return a cow that says testing', () => { + let expected = cowsay.say({ text: 'testing', f: this.cowsayCtrl.current }) + this.cowsayCtrl.speak('testing'); + expect(this.cowsayCtrl.spoken).toEqual(expected); + expect(this.cowsayCtrl.history.length).toEqual(1); + }); + }); + + describe('#undo', () => { + it('should modify our history array and return a cow that says testing', () => { + let expected = cowsay.say({ text: 'testing', f: this.cowsayCtrl.current }); + this.cowsayCtrl.speak('testing'); + this.cowsayCtrl.speak('test control'); + this.cowsayCtrl.undo(); + expect(this.cowsayCtrl.spoken).toEqual(expected); + expect(this.cowsayCtrl.history.length).toEqual(0); + }); + }); }); From 1a11fe190447bbd6e036d23b5b18b6ffa5bd30d9 Mon Sep 17 00:00:00 2001 From: Nikko Pisciotti Date: Wed, 22 Mar 2017 18:43:25 -0700 Subject: [PATCH 6/6] webpack 'filename:' fix --- webpack.config.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/webpack.config.js b/webpack.config.js index 4541036..6748bdc 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -7,7 +7,7 @@ const ExtractTextPlugin = require('extract-text-webpack-plugin'); module.exports = { entry: `${__dirname}/app/entry.js`, output: { - file: 'bundle.js', + filename: 'bundle.js', path: 'build' }, plugins: [