diff --git a/.bowerrc b/.bowerrc
index 5bdbb80..69fad35 100644
--- a/.bowerrc
+++ b/.bowerrc
@@ -1,3 +1,3 @@
{
- "directory" : "vendor"
-}
\ No newline at end of file
+ "directory": "bower_components"
+}
diff --git a/.gitignore b/.gitignore
index aec7f25..82d38a2 100644
--- a/.gitignore
+++ b/.gitignore
@@ -15,13 +15,5 @@ npm-debug.log
test/test-results.xml
-vendor/angular-cookies/
-vendor/angular-mocks/
-vendor/angular-resource/
-vendor/angular-sanitize/
-vendor/angular/
-vendor/bootstrap-less-themes/
-vendor/bootstrap/
-vendor/console-polyfill/
-vendor/font-awesome/
-vendor/jquery/
+# Bower stuff.
+bower_components/
diff --git a/README.md b/README.md
index 139fb3a..cbd6f7a 100644
--- a/README.md
+++ b/README.md
@@ -3,6 +3,11 @@
[AngularJS](http://angularjs.org) + [Brunch](http://brunch.io)
+#### ** MAJOR UPDATES **
+v0.4.1 Brings with it some major changes. If you're upgrading from a previous release,
+please run `./scripts/init.sh` and remove any bower components from `vendor`. Bower
+now uses the `bower_components` directory.
+
Features:
* Coffeescript / Jade / Less / Stylus automatically compiled on save
* auto-reload during development saves you from manually refreshing the page
@@ -10,6 +15,26 @@ Features:
* [karma](https://github.com/karma-runner/karma) integration for
unit tests
* Bootstrap integration with themes.
+* Source map support
+* Modularized code, see /app/sections
+* angular/ui-router for more flexible routing
+
+## Why modularize?
+
+This "modularized" version is intended to be as simple as possible while laying down patterns that, if followed, will create an easily-maintained complex application. The original Angular-Seed entices one down the path of code segregated by type (controllers, views, etc.) rather than by feature (todo, view1, view2). Misko recommends organizing code around features (see [this](http://www.youtube.com/watch?feature=player_embedded&v=E87rXWE62WU#t=106s) 10/27/13 presentation).
+
+Modularized code is better for
+* unit testing
+* working with larger teams (to not step on each others’ work)
+* preparing for the future because modules will be able to be lazy-loaded and so this structure will be either required or firmly recommended
+
+## What, exactly, is different in the modularized code?
+Differences
+* Instead of one controller, one partials folder, one module, there are several
+ * top level ones under /app
+ * lower-level ones under /app/sections
+ * (to make that work, karma.conf.js and config.coffee had to be changed, to pick up and integrate the files from more locations)
+* Instead of using the $routeProvider, it uses angular-ui-router to allow output to multiple named views, nested views, etc. Routing and ng-view was mentioned by many online as pain points for larger apps. This arrangement should be much better.
## Alternate Versions
@@ -22,6 +47,9 @@ Features:
- [brunch-on-asteroids](https://github.com/exlee/brunch-on-asteroids)
by [@exlee](https://github.com/exlee) - A minimalistic version that adds Generators,
Bootswatch themes, D3, and more.
+- [angular-brunch-seed-modularized](https://github.com/sanfordredlich/angular-brunch-seed-modularized)
+ by [@sanfordredlich](https://github.com/sanfordredlich) - Demonstrates a modular
+ design, consistent with best practices and better suited for larger projects
## How to use angular-brunch-seed
@@ -32,7 +60,7 @@ Features:
Or if you have **Brunch** installed run:
-`brunch new myapp --skeleton https://github.com/scotch/angular-brunch-seed`
+`brunch new https://github.com/scotch/angular-brunch-seed myapp`
You must also install packages using bower. Either
@@ -41,7 +69,7 @@ bower install
```
or
```
-./node_modules/.bin/bower
+./node_modules/.bin/bower install
```
*NOTE:* Depending upon your connection and processor speed the build can take
@@ -110,11 +138,10 @@ and run `bower install`. The component will be added to the `vendor` directory.
### Running unit tests
* `./scripts/test.sh` to run unit tests with [karma](https://github.com/karma-runner/karma)
-* Open the browser you would like to test to [http://localhost:3334](http://localhost:3334)
Notes:
-- Testacular will run tests on save. To insure that changes are saved be sure
+- Karma will run tests on save. To insure that changes are saved be sure
to have `./script/server.sh` or `./script/development.sh` running in the console.
- Set the browsers that you would like to target in the `/test/karma.conf.js` file
E.g. `browser = ["ChromeCanary", "Firefox"]`
@@ -155,8 +182,6 @@ git pull origin master
assets --> a place for static assets. These files will be copied to
the public directory un-modified.
- font/ --> [fontawesome](http://fortawesome.github.com/Font-Awesome/) rendering icons
- fontawesome-webfont.*
img/ --> image files
partials/ --> angular view partials (partial HTML templates)
nav.html If you are using HTML you may modify these files directly.
@@ -186,6 +211,9 @@ git pull origin master
index.jade --> Index file. This will be converted to assets/index.html on save
init.coffee --> application bootstrap
+ bower_components/ --> The bower_components dirctory is populated by Bower.
+ It contains Angular, Bootstrap Font-Awesome
+ and other utility files.
node_modules --> NodeJS modules
scripts/ --> handy shell scripts
@@ -207,14 +235,13 @@ git pull origin master
filters.spec.js --> specs for filters
services.spec.js --> specs for services
vendor/
- test-results.xml --> Testacular test resuls
- karma-e2e.conf.js --> Testacular end-to-end tests config
- karma.conf.js --> Testacular unit tests config
+ test-results.xml --> Karma test resuls
+ karma-e2e.conf.js --> Karma end-to-end tests config
+ karma.conf.js --> Karma unit tests config
- vendor/ --> The vendor dirctory is populated by Bower.
- It contains Angular, Bootstrap Font-Awesome
- and other utility files.
- component.json --> Bower component config
+ vendor/ --> The vendor directory is can be used for 3rd Party libraries.
+ Any files located in this directory will be included in js/vendor.js
+ bower.json --> Bower component config
config.coffee --> Brunch config
package.json --> node modules config
diff --git a/app/app.coffee b/app/app.coffee
index 9f9029d..c83adb8 100644
--- a/app/app.coffee
+++ b/app/app.coffee
@@ -1,31 +1,55 @@
+
'use strict'
# Declare app level module which depends on filters, and services
App = angular.module('app', [
+ #used for angular-ui-router
+ 'ui.state'
+
'ngCookies'
'ngResource'
'app.controllers'
'app.directives'
'app.filters'
'app.services'
- 'partials'
+ 'navbar.partials'
+ 'todo.partials'
+ 'app.todo.controllers'
+ 'view1.partials'
+ 'app.view1.controllers'
+ 'view2.partials'
+ 'app.view2.controllers'
])
App.config([
- '$routeProvider'
- '$locationProvider'
+ '$stateProvider'
+ '$urlRouterProvider'
-($routeProvider, $locationProvider, config) ->
+ ($stateProvider, $urlRouterProvider) ->
- $routeProvider
+ # default to the todo page
+ $urlRouterProvider.otherwise("/todo")
+
+ $stateProvider
- .when('/todo', {templateUrl: '/partials/todo.html'})
- .when('/view1', {templateUrl: '/partials/partial1.html'})
- .when('/view2', {templateUrl: '/partials/partial2.html'})
+ .state('todo',
+ url: "/todo"
+ views:
+ "main-content":
+ templateUrl: "/todo/todo.html"
+ )
- # Catch all
- .otherwise({redirectTo: '/todo'})
+ .state('view1',
+ url: "/view1"
+ views:
+ "main-content":
+ templateUrl: "/view1/partial1.html"
+ )
- # Without server side support html5 must be disabled.
- $locationProvider.html5Mode(false)
+ .state('view2',
+ url: "/view2"
+ views:
+ "main-content":
+ templateUrl: "/view2/partial2.html"
+ )
])
diff --git a/app/index.jade b/app/index.jade
index 6c2b039..7969f58 100644
--- a/app/index.jade
+++ b/app/index.jade
@@ -8,20 +8,7 @@ html(lang='en', ng-app='app')
meta(name='author', content='')
title(ng-bind-template='{{pageTitle}}')
link(rel='stylesheet', href='/css/app.css')
- //-script(src='http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js')
- //if lte IE 7
- script(src='http://cdnjs.cloudflare.com/ajax/libs/json2/20110223/json2.js')
- //if lte IE 8
- script(src='//html5shiv.googlecode.com/svn/trunk/html5.js')
- script
- window.brunch = window.brunch || {};
- window.brunch['auto-reload'] = {
- enabled: true
- };
- script(src='/js/auto-reload.js')
- script(src='/js/vendor.js')
- script(src='/js/partials.js')
- script(src='/js/app.js')
+
body(ng-controller='AppCtrl')
.wrapper
.navbar.navbar-static-top
@@ -33,9 +20,9 @@ html(lang='en', ng-app='app')
span.icon-bar
a(href='/').brand Angular Brunch Seed
.nav-collapse
- div(ng-include="'/partials/nav.html'")
+ div(ng-include="'/navbar/nav.html'")
.container.main-content
- div(ng-view)
+ div(ui-view="main-content")
div Angular Brunch seed app: v
.push
@@ -43,4 +30,22 @@ html(lang='en', ng-app='app')
.container
p
small
- a(href='https://github.com/scotch/angular-brunch-seed') angular-brunch-seed | source
+ a(href='https://github.com/scotch/angular-brunch-seed.git') angular-brunch-seed (modularized) | source
+
+ //-script(src='http://ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js')
+ //if lte IE 7
+ script(src='http://cdnjs.cloudflare.com/ajax/libs/json2/20110223/json2.js')
+ //if lte IE 8
+ script(src='//html5shiv.googlecode.com/svn/trunk/html5.js')
+ script.
+ window.brunch = window.brunch || {};
+ window.brunch['auto-reload'] = {
+ enabled: true
+ };
+ script(src='/js/auto-reload.js')
+ script(src='/js/vendor.js')
+ script(src='/js/navbar.partials.js')
+ script(src='/js/todo.partials.js')
+ script(src='/js/view1.partials.js')
+ script(src='/js/view2.partials.js')
+ script(src='/js/app.js')
diff --git a/app/scripts/controllers.coffee b/app/scripts/controllers.coffee
index 5c6ce68..0b5130b 100644
--- a/app/scripts/controllers.coffee
+++ b/app/scripts/controllers.coffee
@@ -11,6 +11,8 @@ angular.module('app.controllers', [])
'$rootScope'
($scope, $location, $resource, $rootScope) ->
+
+ $scope.appData = {}
# Uses the url to determine if the selected
# menu item should have the class active.
@@ -32,54 +34,4 @@ angular.module('app.controllers', [])
return 'active'
else
return ''
-])
-
-.controller('MyCtrl1', [
- '$scope'
-
-($scope) ->
- $scope.onePlusOne = 2
-])
-
-.controller('MyCtrl2', [
- '$scope'
-
-($scope) ->
- $scope
-])
-
-.controller('TodoCtrl', [
- '$scope'
-
-($scope) ->
-
- $scope.todos = [
- text: "learn angular"
- done: true
- ,
- text: "build an angular app"
- done: false
- ]
-
- $scope.addTodo = ->
- $scope.todos.push
- text: $scope.todoText
- done: false
-
- $scope.todoText = ""
-
- $scope.remaining = ->
- count = 0
- angular.forEach $scope.todos, (todo) ->
- count += (if todo.done then 0 else 1)
-
- count
-
- $scope.archive = ->
- oldTodos = $scope.todos
- $scope.todos = []
- angular.forEach oldTodos, (todo) ->
- $scope.todos.push todo unless todo.done
-
-])
-
+])
\ No newline at end of file
diff --git a/app/partials/todo.jade b/app/sections/home/partials/todo.jade
similarity index 100%
rename from app/partials/todo.jade
rename to app/sections/home/partials/todo.jade
diff --git a/app/sections/home/scripts/home.controllers.coffee b/app/sections/home/scripts/home.controllers.coffee
new file mode 100644
index 0000000..e0e2860
--- /dev/null
+++ b/app/sections/home/scripts/home.controllers.coffee
@@ -0,0 +1,37 @@
+angular.module('app.home.controllers', [])
+
+.controller('TodoCtrl', [
+ '$scope'
+
+($scope) ->
+
+ $scope.todos = [
+ text: "learn angular"
+ done: true
+ ,
+ text: "build an angular app"
+ done: false
+ ]
+
+ $scope.addTodo = ->
+ $scope.todos.push
+ text: $scope.todoText
+ done: false
+
+ $scope.todoText = ""
+
+ $scope.remaining = ->
+ count = 0
+ angular.forEach $scope.todos, (todo) ->
+ count += (if todo.done then 0 else 1)
+
+ count
+
+ $scope.archive = ->
+ oldTodos = $scope.todos
+ $scope.todos = []
+ angular.forEach oldTodos, (todo) ->
+ $scope.todos.push todo unless todo.done
+
+])
+
diff --git a/app/partials/nav.jade b/app/sections/navbar/partials/nav.jade
similarity index 100%
rename from app/partials/nav.jade
rename to app/sections/navbar/partials/nav.jade
diff --git a/app/sections/todo/partials/todo.jade b/app/sections/todo/partials/todo.jade
new file mode 100644
index 0000000..2d24528
--- /dev/null
+++ b/app/sections/todo/partials/todo.jade
@@ -0,0 +1,16 @@
+div(ng-app='ng-app')
+ h2 Todo
+ div(ng-controller='TodoCtrl')
+ span {{remaining()}} of {{todos.length}} remaining
+ | [
+ a(href='', ng-click='archive()') archive
+ | ]
+ ul.unstyled
+ li(ng-repeat='todo in todos')
+ label(class='checkbox inline')
+ input(type='checkbox', ng-model='todo.done')
+ span(class='done{{todo.done}}') {{todo.text}}
+ form(class='form-inline', ng-submit='addTodo()')
+ p
+ input(type='text', ng-model='todoText', size='30', placeholder='add new todo here')
+ input.btn.btn-primary(type='submit', value='add')
diff --git a/app/sections/todo/scripts/todo.controllers.coffee b/app/sections/todo/scripts/todo.controllers.coffee
new file mode 100644
index 0000000..943899b
--- /dev/null
+++ b/app/sections/todo/scripts/todo.controllers.coffee
@@ -0,0 +1,37 @@
+angular.module('app.todo.controllers', [])
+
+.controller('TodoCtrl', [
+ '$scope'
+
+($scope) ->
+
+ $scope.todos = [
+ text: "learn angular"
+ done: true
+ ,
+ text: "build an angular app"
+ done: false
+ ]
+
+ $scope.addTodo = ->
+ $scope.todos.push
+ text: $scope.todoText
+ done: false
+
+ $scope.todoText = ""
+
+ $scope.remaining = ->
+ count = 0
+ angular.forEach $scope.todos, (todo) ->
+ count += (if todo.done then 0 else 1)
+
+ count
+
+ $scope.archive = ->
+ oldTodos = $scope.todos
+ $scope.todos = []
+ angular.forEach oldTodos, (todo) ->
+ $scope.todos.push todo unless todo.done
+
+])
+
diff --git a/app/sections/top/partials/nav.jade b/app/sections/top/partials/nav.jade
new file mode 100644
index 0000000..fc31234
--- /dev/null
+++ b/app/sections/top/partials/nav.jade
@@ -0,0 +1,7 @@
+ul.nav
+ li(ng-class="getClass('/todo')")
+ a(ng-href='#/todo') todo
+ li(ng-class="getClass('/view1')")
+ a(ng-href='#/view1') view1
+ li(ng-class="getClass('/view2')")
+ a(ng-href='#/view2') view2
diff --git a/app/partials/partial1.jade b/app/sections/view1/partials/partial1.jade
similarity index 100%
rename from app/partials/partial1.jade
rename to app/sections/view1/partials/partial1.jade
diff --git a/app/sections/view1/scripts/view1.controllers.coffee b/app/sections/view1/scripts/view1.controllers.coffee
new file mode 100644
index 0000000..c234419
--- /dev/null
+++ b/app/sections/view1/scripts/view1.controllers.coffee
@@ -0,0 +1,10 @@
+'use strict'
+
+angular.module('app.view1.controllers', [])
+
+.controller('MyCtrl1', [
+ '$scope'
+
+($scope) ->
+ $scope.onePlusOne = 2
+])
\ No newline at end of file
diff --git a/app/partials/partial2.jade b/app/sections/view2/partials/partial2.jade
similarity index 68%
rename from app/partials/partial2.jade
rename to app/sections/view2/partials/partial2.jade
index eb8129a..52b9138 100644
--- a/app/partials/partial2.jade
+++ b/app/sections/view2/partials/partial2.jade
@@ -1,4 +1,4 @@
p This is the partial for view 2.
p
- | Showing of 'interpolate' filter:
+ | Demonstrating an 'interpolate' filter:
| {{ 'Current version is v%VERSION%.' | interpolate }}
diff --git a/app/sections/view2/scripts/view2.controllers.coffee b/app/sections/view2/scripts/view2.controllers.coffee
new file mode 100644
index 0000000..71825fb
--- /dev/null
+++ b/app/sections/view2/scripts/view2.controllers.coffee
@@ -0,0 +1,9 @@
+angular.module('app.view2.controllers', [])
+
+.controller('MyCtrl2', [
+ '$scope'
+
+($scope) ->
+ $scope.twoPlusTwo = 4
+])
+
diff --git a/app/styles/app.less b/app/styles/app.less
index 7cc9e3a..32519d5 100644
--- a/app/styles/app.less
+++ b/app/styles/app.less
@@ -1,5 +1,5 @@
/*!
- * Bootstrap v2.3.0
+ * Bootstrap v2.3.2
*
* Copyright 2012 Twitter, Inc
* Licensed under the Apache License v2.0
@@ -9,7 +9,7 @@
*/
// CSS Reset
-@import "/vendor/bootstrap/less/reset.less";
+@import "/bower_components/bootstrap-less/less/reset.less";
// Theme variables
// Uncomment the theme you would like to use. Themes may include
@@ -17,87 +17,87 @@
// override.less file to the bottom of this file.
// Bootstrap default
-// @import "/vendor/bootstrap-less-themes/themes/default/variables.less";
+// @import "/bower_components/bootstrap-less-themes/themes/default/variables.less";
// Sapling default
-// @import "/vendor/bootstrap-less-themes/themes/sapling/variables.less";
+@import "/bower_components/bootstrap-less-themes/themes/sapling/variables.less";
// Your custom theme
@import "_variables.less";
// Core variables and mixins
-@import "/vendor/bootstrap/less/mixins.less";
+@import "/bower_components/bootstrap-less/less/mixins.less";
// Grid system and page structure
-@import "/vendor/bootstrap/less/scaffolding.less";
-@import "/vendor/bootstrap/less/grid.less";
-@import "/vendor/bootstrap/less/layouts.less";
+@import "/bower_components/bootstrap-less/less/scaffolding.less";
+@import "/bower_components/bootstrap-less/less/grid.less";
+@import "/bower_components/bootstrap-less/less/layouts.less";
// Base CSS
-@import "/vendor/bootstrap/less/type.less";
-@import "/vendor/bootstrap/less/code.less";
-@import "/vendor/bootstrap/less/forms.less";
-@import "/vendor/bootstrap/less/tables.less";
+@import "/bower_components/bootstrap-less/less/type.less";
+@import "/bower_components/bootstrap-less/less/code.less";
+@import "/bower_components/bootstrap-less/less/forms.less";
+@import "/bower_components/bootstrap-less/less/tables.less";
// vendor: common
-@import "/vendor/bootstrap/less/sprites.less";
+@import "/bower_components/bootstrap-less/less/sprites.less";
-@import "/vendor/font-awesome/less/font-awesome.less";
+// @import "/bower_components/font-awesome/less/font-awesome.less";
-@import "/vendor/bootstrap/less/dropdowns.less";
-@import "/vendor/bootstrap/less/wells.less";
-@import "/vendor/bootstrap/less/component-animations.less";
-@import "/vendor/bootstrap/less/close.less";
+@import "/bower_components/bootstrap-less/less/dropdowns.less";
+@import "/bower_components/bootstrap-less/less/wells.less";
+@import "/bower_components/bootstrap-less/less/component-animations.less";
+@import "/bower_components/bootstrap-less/less/close.less";
// vendor: Buttons & Alerts
-@import "/vendor/bootstrap/less/buttons.less";
-@import "/vendor/bootstrap/less/button-groups.less";
-@import "/vendor/bootstrap/less/alerts.less"; // Note: alerts share common CSS with buttons and thus have styles in buttons.less
+@import "/bower_components/bootstrap-less/less/buttons.less";
+@import "/bower_components/bootstrap-less/less/button-groups.less";
+@import "/bower_components/bootstrap-less/less/alerts.less"; // Note: alerts share common CSS with buttons and thus have styles in buttons.less
// vendor: Nav
-@import "/vendor/bootstrap/less/navs.less";
-@import "/vendor/bootstrap/less/navbar.less";
-@import "/vendor/bootstrap/less/breadcrumbs.less";
-@import "/vendor/bootstrap/less/pagination.less";
-@import "/vendor/bootstrap/less/pager.less";
+@import "/bower_components/bootstrap-less/less/navs.less";
+@import "/bower_components/bootstrap-less/less/navbar.less";
+@import "/bower_components/bootstrap-less/less/breadcrumbs.less";
+@import "/bower_components/bootstrap-less/less/pagination.less";
+@import "/bower_components/bootstrap-less/less/pager.less";
// vendor: Popovers
-@import "/vendor/bootstrap/less/modals.less";
-@import "/vendor/bootstrap/less/tooltip.less";
-@import "/vendor/bootstrap/less/popovers.less";
+@import "/bower_components/bootstrap-less/less/modals.less";
+@import "/bower_components/bootstrap-less/less/tooltip.less";
+@import "/bower_components/bootstrap-less/less/popovers.less";
// vendor: Misc
-@import "/vendor/bootstrap/less/thumbnails.less";
-@import "/vendor/bootstrap/less/media.less";
-@import "/vendor/bootstrap/less/labels-badges.less";
-@import "/vendor/bootstrap/less/progress-bars.less";
-@import "/vendor/bootstrap/less/accordion.less";
-@import "/vendor/bootstrap/less/carousel.less";
-@import "/vendor/bootstrap/less/hero-unit.less";
+@import "/bower_components/bootstrap-less/less/thumbnails.less";
+@import "/bower_components/bootstrap-less/less/media.less";
+@import "/bower_components/bootstrap-less/less/labels-badges.less";
+@import "/bower_components/bootstrap-less/less/progress-bars.less";
+@import "/bower_components/bootstrap-less/less/accordion.less";
+@import "/bower_components/bootstrap-less/less/carousel.less";
+@import "/bower_components/bootstrap-less/less/hero-unit.less";
// Componets: Footer
-@import "/vendor/bootstrap-less-themes/themes/sapling/sticky-footer.less";
+@import "/bower_components/bootstrap-less-themes/themes/sapling/sticky-footer.less";
// Responsive
-@import "/vendor/bootstrap/less/responsive-utilities.less";
-@import "/vendor/bootstrap/less/responsive-1200px-min.less";
-@import "/vendor/bootstrap/less/responsive-768px-979px.less";
-@import "/vendor/bootstrap/less/responsive-767px-max.less";
-@import "/vendor/bootstrap/less/responsive-navbar.less";
+@import "/bower_components/bootstrap-less/less/responsive-utilities.less";
+@import "/bower_components/bootstrap-less/less/responsive-1200px-min.less";
+@import "/bower_components/bootstrap-less/less/responsive-768px-979px.less";
+@import "/bower_components/bootstrap-less/less/responsive-767px-max.less";
+@import "/bower_components/bootstrap-less/less/responsive-navbar.less";
// AngularJS
-@import "/vendor/bootstrap-less-themes/themes/angular/forms.less";
+@import "/bower_components/bootstrap-less-themes/themes/angular/forms.less";
// Utility classes
-@import "/vendor/bootstrap/less/utilities.less"; // Has to be last to override when necessary
+@import "/bower_components/bootstrap-less/less/utilities.less"; // Has to be last to override when necessary
// Theme Overrides
// Bootstrap default
-// @import "/vendor/bootstrap-less-themes/themes/default/overrides.less";
+// @import "/bower_components/bootstrap-less-themes/themes/default/overrides.less";
// Sapling default
-// @import "/vendor/bootstrap-less-themes/themes/sapling/overrides.less";
+@import "/bower_components/bootstrap-less-themes/themes/sapling/overrides.less";
// Your custom theme
@import "_overrides.less";
diff --git a/bower.json b/bower.json
index f826fc2..e1d800f 100644
--- a/bower.json
+++ b/bower.json
@@ -1,20 +1,34 @@
{
"name": "angular-brunch-seed",
+ "repo": "scotch/angular-brunch-seed",
"version": "0.3.0",
- "main": [],
+ "main": "_public/js/app.js",
+ "ignore": [
+ "**/.*",
+ "node_modules",
+ "components"
+ ],
"dependencies": {
- "console-polyfill": "*",
-
- "jquery": "1.8.3",
-
- "bootstrap": "~2.3.1",
- "bootstrap-less-themes": "git://github.com/angular-brunch/bootstrap-less-themes.git",
- "font-awesome": "3.0.2",
-
- "angular": "1.0.6",
- "angular-sanitize": "1.0.6",
- "angular-resource": "1.0.6",
- "angular-cookies": "1.0.6",
- "angular-mocks": "1.0.6"
+ "console-polyfill": "~0.1.0",
+ "jquery": "~2.0.3",
+ "bootstrap-less": "~2.3.2",
+ "bootstrap-less-themes": "https://github.com/angular-brunch/bootstrap-less-themes.git",
+ "angular-bootstrap": "~0.4.0",
+ "angular": "1.0.7",
+ "angular-sanitize": "1.0.7",
+ "angular-resource": "1.0.7",
+ "angular-cookies": "1.0.7",
+ "angular-mocks": "1.0.7",
+ "angular-ui-router": "0.0.1"
+ },
+ "overrides": {
+ "bootstrap-less": {
+ "ignore": [
+ "*"
+ ]
+ },
+ "angular-mocks": {
+ "main": "README.md"
+ }
}
}
diff --git a/config.coffee b/config.coffee
index f8ce2c7..6d112f9 100644
--- a/config.coffee
+++ b/config.coffee
@@ -1,7 +1,6 @@
exports.config =
# See docs at http://brunch.readthedocs.org/en/latest/config.html.
conventions:
- ignored: /(^vendor\\.*\.less)|(^vendor\/.*\.less)|(^|\/)node_modules\/|(^|\/)_/
assets: /^app\/assets\//
modules:
definition: false
@@ -12,22 +11,11 @@ exports.config =
javascripts:
joinTo:
'js/app.js': /^app/
- 'js/vendor.js': /^vendor/
- 'test/scenarios.js': /^test(\/|\\)e2e/
- order:
- before: [
- 'vendor/console-polyfill/index.js'
- 'vendor/jquery/jquery.js'
- 'vendor/angular/angular.js'
- 'vendor/angular-resource/angular-resource.js'
- 'vendor/angular-cookies/angular-cookies.js'
- 'vendor/angular-sanitize/angular-sanitize.js'
- 'vendor/bootstrap/docs/assets/js/bootstrap.js'
- ]
+ 'js/vendor.js': /^(bower_components|vendor)/
stylesheets:
joinTo:
- 'css/app.css': /^(app|vendor)/
+ 'css/app.css': /^(app|vendor|bower_components)/
order:
before: [
'app/styles/app.less'
@@ -44,15 +32,5 @@ exports.config =
modules_folder: 'partials'
locals: {}
- bower:
- extend:
- "bootstrap" : 'vendor/bootstrap/docs/assets/js/bootstrap.js'
- "angular-mocks": []
- "styles": []
- asserts:
- "img" : /bootstrap(\\|\/)img/
- "font": /font-awesome(\\|\/)font/
-
-
# Enable or disable minifying of result js / css files.
# minify: true
diff --git a/package.json b/package.json
index d84e2f3..21f3a30 100644
--- a/package.json
+++ b/package.json
@@ -1,42 +1,40 @@
{
- "author": "Kyle Finley ",
- "name": "sapling-seed",
- "description": "AngularJS + Brunch",
- "version": "0.3.0",
- "homepage": "https://github.com/scotch/angular-brunch-seed",
+ "author": "Your Name",
+ "name": "package-name",
+ "description": "Package description",
+ "version": "0.0.1",
+ "homepage": "",
"repository": {
"type": "git",
- "url": "https://github.com/scotch/angular-brunch-seed"
- },
- "engines": {
- "node": "~0.6.10 || 0.8 || 0.9"
+ "url": ""
},
"scripts": {
"start": "node_modules/.bin/brunch watch --server",
"test": "node_modules/.bin/karma start test/karma.conf.js"
},
"dependencies": {
- "jade": ">= 0.28",
- "coffee-script": ">= 1.4",
- "brunch": ">= 1.5 < 1.6",
+ "jade": "~0.33",
+ "coffee-script": "~1.6",
+ "brunch": "~1.7",
- "coffee-script-brunch": ">= 1.5 < 1.6",
+ "javascript-brunch": ">= 1.0 < 1.8",
+ "coffee-script-brunch": ">= 1.0 < 1.8",
- "less-brunch": ">= 1.5 < 1.6",
- "stylus-brunch": ">= 1.5 < 1.6",
+ "css-brunch": ">= 1.0 < 1.8",
+ "less-brunch": ">= 1.0 < 1.8",
+ "stylus-brunch": ">= 1.0 < 1.8",
- "auto-reload-brunch": ">= 1.5 < 1.7",
+ "auto-reload-brunch": ">= 1.0 < 1.8",
- "uglify-js-brunch": ">= 1.5 < 1.6",
- "clean-css-brunch": ">= 1.5 < 1.6",
+ "uglify-js-brunch": ">= 1.0 < 1.8",
+ "clean-css-brunch": ">= 1.0 < 1.8",
- "bower-stylesheet-brunch": "git://github.com/angular-brunch/bower-stylesheet-brunch/#master",
- "bower-javascript-brunch": "git://github.com/angular-brunch/bower-javascript-brunch/#master",
- "bower-asserts-brunch": "git://github.com/angular-brunch/bower-assets-brunch/#master",
- "bower": "~0.9.2",
+ "bower": "~1.0",
- "jade-angularjs-brunch": ">= 0.0.5 <= 0.1",
+ "jade-angularjs-brunch": "~0.0.5",
- "karma": ">= 0.8.4 < 0.9.0"
+ "karma": "~0.9.4",
+ "karma-coffee-preprocessor": "~0.0.2",
+ "karma-ng-scenario": "~0.0.2"
}
}
diff --git a/scripts/development.sh b/scripts/development.sh
index ede6be7..80b174f 100755
--- a/scripts/development.sh
+++ b/scripts/development.sh
@@ -1,4 +1,4 @@
#!/bin/bash
rm -rf _public
-node_modules/.bin/brunch watch
+node_modules/.bin/brunch watch --server
diff --git a/scripts/init.bat b/scripts/init.bat
index a67fec0..c75c50f 100644
--- a/scripts/init.bat
+++ b/scripts/init.bat
@@ -1,3 +1,4 @@
rd /s /q node_modules
+rd /s /q bower_components
npm install
./node_modules/.bin/bower install
diff --git a/scripts/init.sh b/scripts/init.sh
index 7c569da..65f876f 100755
--- a/scripts/init.sh
+++ b/scripts/init.sh
@@ -1,5 +1,5 @@
#!/bin/bash
-rm -rf node_modules
+rm -rf node_modules bower_components
npm install
./node_modules/.bin/bower install
diff --git a/test/e2e/app/scenario.coffee b/test/e2e/app/scenario.coffee
index 7e4bc78..3e810e1 100644
--- a/test/e2e/app/scenario.coffee
+++ b/test/e2e/app/scenario.coffee
@@ -5,46 +5,63 @@ describe "my app", ->
beforeEach ->
browser().navigateTo "/"
- it "should automatically redirect to /todo when location hash/fragment is empty", ->
- expect(browser().location().url()).toBe "/todo"
+ NEW_ITEM_LABEL = "test newly added item"
- it "should navigate to /view1 when the View 1 link in nav is clicked", ->
+ switchToToDo = ->
+ element(".nav a[href=\"#/todo\"]").click()
+ expect(browser().location().url()).toBe "/todo"
+
+ switchToView1 = ->
element(".nav a[href=\"#/view1\"]").click()
expect(browser().location().url()).toBe "/view1"
+ it "should automatically redirect to /todo when location hash/fragment is empty", ->
+ expect(browser().location().url()).toBe "/todo"
+
describe "todo", ->
+ addToDoItem = ->
+ input("todoText").enter NEW_ITEM_LABEL
+ element("input[type=\"submit\"]").click()
+ expect(repeater("[ui-view] ul li").count()).toEqual 3
+ expect(element("[ui-view] ul li:last span").text()).toEqual NEW_ITEM_LABEL
+ expect(input("todoText").val()).toEqual ""
+
it "should list 2 items", ->
- expect(repeater("[ng-view] ul li").count()).toEqual 2
+ expect(repeater("[ui-view] ul li").count()).toEqual 2
it "should display checked items with a line-through", ->
- expect(element("[ng-view] ul li input:checked + span").css("text-decoration")).toEqual "line-through"
+ expect(element("[ui-view] ul li input:checked + span").css("text-decoration")).toEqual "line-through"
it "should sync done status with checkbox state", ->
- element("[ng-view] ul li input:not(:checked)").click()
- expect(element("[ng-view] ul li span").attr("class")).toEqual "donetrue"
- element("[ng-view] ul li input:checked").click()
- expect(element("[ng-view] ul li span").attr("class")).toEqual "donefalse"
+ element("[ui-view] ul li input:not(:checked)").click()
+ expect(element("[ui-view] ul li span").attr("class")).toEqual "donetrue"
+ element("[ui-view] ul li input:checked").click()
+ expect(element("[ui-view] ul li span").attr("class")).toEqual "donefalse"
it "should remove checked items when the archive link is clicked", ->
- element("[ng-view] a[ng-click=\"archive()\"]").click()
- expect(repeater("[ng-view] ul li").count()).toEqual 1
-
- it "should add a newly submitted item to the end of the list and empty the text input", ->
- newItemLabel = "test newly added item"
- input("todoText").enter newItemLabel
- element("[ng-view] input[type=\"submit\"]").click()
- expect(repeater("[ng-view] ul li").count()).toEqual 3
- expect(element("[ng-view] ul li:last span").text()).toEqual newItemLabel
- expect(input("todoText").val()).toEqual ""
+ element("[ui-view] a[ng-click=\"archive()\"]").click()
+ expect(repeater("[ui-view] ul li").count()).toEqual 1
+
+ it "should add a newly submitted item to the end of the list and empty the text input", addToDoItem
+ it "should still have a newly submitted item after switching views", ->
+ addToDoItem
+ switchToView1
+ switchToToDo
+ expect(repeater("[ui-view] ul li").count()).toEqual 3
+ expect(element("[ui-view] ul li:last span").text()).toEqual NEW_ITEM_LABEL
+
+
+ it "should navigate to /view1 when the View 1 link in nav is clicked", ->
+ switchToView1
describe "view1", ->
beforeEach ->
browser().navigateTo "#/view1"
it "should render view1 when user navigates to /view1", ->
- expect(element("[ng-view] p:first").text()).toMatch /partial for view 1/
+ expect(element("p:first").text()).toMatch /partial for view 1/
describe "view2", ->
@@ -52,4 +69,4 @@ describe "my app", ->
browser().navigateTo "#/view2"
it "should render view2 when user navigates to /view2", ->
- expect(element("[ng-view] p:first").text()).toMatch /partial for view 2/
+ expect(element("p:first").text()).toMatch /partial for view 2/
diff --git a/test/karma-e2e.conf.js b/test/karma-e2e.conf.js
index b8dc3f6..806e6d8 100644
--- a/test/karma-e2e.conf.js
+++ b/test/karma-e2e.conf.js
@@ -1,25 +1,86 @@
-basePath = '../';
+// Karma configuration
-files = [
- ANGULAR_SCENARIO,
- ANGULAR_SCENARIO_ADAPTER,
- 'test/e2e/**/*.js',
- 'test/e2e/**/*.coffee'
-];
+module.exports = function(karma) {
+ karma.configure({
-autoWatch = false;
+ // base path, that will be used to resolve files and exclude
+ basePath: '../',
-browsers = ['Chrome'];
-singleRun = true;
+ // frameworks to use
+ frameworks: ['ng-scenario'],
-urlRoot = '/__karma/';
-proxies = {
- '/': 'http://localhost:3333/'
-};
+ // list of files / patterns to load in the browser
+ files: [
+ 'test/e2e/**/*.js',
+ 'test/e2e/**/*.coffee'
+ ],
+
+ // list of files to exclude
+ exclude: [
+ // 'vendor/angular-mocks/angular-mocks.min.js',
+ ],
+
+
+ // test results reporter to use
+ // possible values: 'dots', 'progress', 'junit', 'growl', 'coverage'
+ reporters: ['progress'],
+
+
+ // web server port
+ port: 9876,
+
+
+ // cli runner port
+ runnerPort: 9100,
+
+
+ // enable / disable colors in the output (reporters and logs)
+ colors: true,
+
+
+ // level of logging
+ // possible values: karma.LOG_DISABLE || karma.LOG_ERROR || karma.LOG_WARN || karma.LOG_INFO || karma.LOG_DEBUG
+ logLevel: karma.LOG_INFO,
+
+
+ urlRoot: '/__karma/',
+
+
+ // enable / disable watching file and executing tests whenever any file changes
+ autoWatch: true,
+
+
+ // Start these browsers, currently available:
+ // - Chrome
+ // - ChromeCanary
+ // - Firefox
+ // - Opera
+ // - Safari (only Mac)
+ // - PhantomJS
+ // - IE (only Windows)
+ browsers: ['Chrome'],
+
+
+ // If browser does not capture in given timeout [ms], kill it
+ captureTimeout: 60000,
+
+
+ // Plugins to load
+ plugins: [
+ 'karma-ng-scenario',
+ 'karma-coffee-preprocessor',
+ 'karma-chrome-launcher'
+ ],
+
+
+ proxies: {
+ '/': 'http://localhost:3333/'
+ },
-// compile coffee scripts
-preprocessors = {
- '**/*.coffee': 'coffee'
+ // Continuous Integration mode
+ // if true, it capture browsers, run tests and exit
+ singleRun: false
+ });
};
diff --git a/test/karma.conf.js b/test/karma.conf.js
index 3f0aeb5..9e3e000 100644
--- a/test/karma.conf.js
+++ b/test/karma.conf.js
@@ -1,92 +1,88 @@
// Karma configuration
+module.exports = function(karma) {
+ karma.configure({
-// base path, that will be used to resolve files and exclude
-basePath = '../';
+ // base path, that will be used to resolve files and exclude
+ basePath: '../',
-// list of files / patterns to load in the browser
-files = [
- JASMINE,
- JASMINE_ADAPTER,
- // Application Code //
- 'vendor/jquery/jquery.js',
- 'vendor/angular/angular.js',
- 'vendor/angular-*/angular-*.js',
- 'vendor/bootstrap/docs/assets/js/bootstrap.js',
+ // frameworks to use
+ frameworks: ['jasmine'],
- //'app/scripts/**/*.js',
- 'app/scripts/**/*.coffee',
- // Specs //
+ // list of files / patterns to load in the browser
+ files: [
- // CoffeeScript //
- 'test/unit/**/*.spec.coffee'
+ // Program files
+ '_public/js/vendor.js',
+ '_public/js/app.js',
- // Javascript //
- // 'test/unit/**/*.spec.js'
-];
+ // Specs
-// list of files to exclude
-exclude = [
- 'vendor/angular-mocks/angular-mocks.min.js',
-];
+ // Load mocks directly from bower
+ 'bower_components/angular-mocks/angular-mocks.js',
-// use dots reporter, as travis terminal does not support escaping sequences
-// possible values: 'dots', 'progress', 'junit'
-// CLI --reporters progress
-reporters = ['progress', 'junit'];
+ 'test/unit/**/*.spec.*'
+ ],
+
+
+ // list of files to exclude
+ exclude: [
+ ],
+
+
+ // test results reporter to use
+ // possible values: 'dots', 'progress', 'junit', 'growl', 'coverage'
+ reporters: ['progress'],
+
+
+ // web server port
+ port: 9876,
+
+
+ // cli runner port
+ runnerPort: 9100,
+
+
+ // enable / disable colors in the output (reporters and logs)
+ colors: true,
+
+
+ // level of logging
+ // possible values: karma.LOG_DISABLE || karma.LOG_ERROR || karma.LOG_WARN || karma.LOG_INFO || karma.LOG_DEBUG
+ logLevel: karma.LOG_INFO,
+
+
+ // enable / disable watching file and executing tests whenever any file changes
+ autoWatch: true,
+
+
+ // Start these browsers, currently available:
+ // - Chrome
+ // - ChromeCanary
+ // - Firefox
+ // - Opera
+ // - Safari (only Mac)
+ // - PhantomJS
+ // - IE (only Windows)
+ browsers: ['Chrome'],
+
+
+ // If browser does not capture in given timeout [ms], kill it
+ captureTimeout: 60000,
+
+
+ // Plugins to load
+ plugins: [
+ 'karma-jasmine',
+ 'karma-coffee-preprocessor',
+ 'karma-chrome-launcher'
+ ],
-junitReporter = {
- // will be resolved to basePath (in the same way as files/exclude patterns)
- outputFile: 'test/test-results.xml'
-};
-// web server port
-// CLI --port 3334
-port = 3334;
-
-// cli runner port
-// CLI --runner-port 9100
-runnerPort = 9100;
-
-// enable / disable colors in the output (reporters and logs)
-// CLI --colors --no-colors
-colors = true;
-
-// level of logging
-// possible values: LOG_DISABLE || LOG_ERROR || LOG_WARN || LOG_INFO || LOG_DEBUG
-// CLI --log-level debug
-logLevel = LOG_INFO;
-
-// enable / disable watching file and executing tests whenever any file changes
-// CLI --auto-watch --no-auto-watch
-autoWatch = true;
-
-// Start these browsers, currently available:
-// - Chrome
-// - ChromeCanary
-// - Firefox
-// - Opera
-// - Safari (only Mac)
-// - PhantomJS
-// - IE (only Windows)
-// CLI --browsers Chrome,Firefox,Safari
-browsers = [];
-
-// If browser does not capture in given timeout [ms], kill it
-// CLI --capture-timeout 5000
-captureTimeout = 5000;
-
-// Auto run tests on start (when browsers are captured) and exit
-// CLI --single-run --no-single-run
-singleRun = false;
-
-// report which specs are slower than 500ms
-// CLI --report-slower-than 500
-reportSlowerThan = 500;
-
-// compile coffee scripts
-preprocessors = {
- '**/*.coffee': 'coffee'
+ // Continuous Integration mode
+ // if true, it capture browsers, run tests and exit
+ singleRun: false
+ });
};
diff --git a/test/unit/contoller.spec.coffee b/test/unit/contoller.spec.coffee
index a14ac3e..c24735e 100644
--- a/test/unit/contoller.spec.coffee
+++ b/test/unit/contoller.spec.coffee
@@ -3,18 +3,3 @@
# jasmine specs for controllers go here
# TODO figure out how to test Controllers that use modules
-describe "controllers", ->
-
- beforeEach(module "app.controllers")
-
- describe "MyCtrl1", ->
-
- it "should make scope testable", inject ($rootScope, $controller) ->
- scope = $rootScope.$new()
- ctrl = $controller "MyCtrl1",
- $scope: scope,
- expect(scope.onePlusOne).toEqual(2)
-
- describe "MyCtrl2", ->
-
- it "should..."
diff --git a/test/unit/sections/view1/view1.controller.spec.coffee b/test/unit/sections/view1/view1.controller.spec.coffee
new file mode 100644
index 0000000..6ac5020
--- /dev/null
+++ b/test/unit/sections/view1/view1.controller.spec.coffee
@@ -0,0 +1,11 @@
+describe "controllers", ->
+
+ beforeEach(module "app.view1.controllers")
+
+ describe "MyCtrl1", ->
+
+ it "should make scope testable", inject ($rootScope, $controller) ->
+ scope = $rootScope.$new()
+ ctrl = $controller "MyCtrl1",
+ $scope: scope,
+ expect(scope.onePlusOne).toEqual(2)
\ No newline at end of file
diff --git a/test/unit/sections/view2/view2.controller.spec.coffee b/test/unit/sections/view2/view2.controller.spec.coffee
new file mode 100644
index 0000000..c96acde
--- /dev/null
+++ b/test/unit/sections/view2/view2.controller.spec.coffee
@@ -0,0 +1,11 @@
+describe "controllers", ->
+
+ beforeEach(module "app.view2.controllers")
+
+ describe "MyCtrl2", ->
+
+ it "should make scope testable", inject ($rootScope, $controller) ->
+ scope = $rootScope.$new()
+ ctrl = $controller "MyCtrl2",
+ $scope: scope,
+ expect(scope.twoPlusTwo).toEqual(4)
\ No newline at end of file