├── .editorconfig ├── .gitattributes ├── .gitignore ├── .jshintrc ├── .travis.yml ├── CHANGELOG.md ├── Gruntfile.js ├── app ├── USAGE ├── index.js └── templates │ └── api │ ├── .htaccess │ ├── Makefile │ ├── _gitignore │ ├── composer.json │ ├── config │ ├── .gitignore │ ├── README.md │ └── application.config.php │ ├── index.php │ ├── phpunit.xml │ ├── src │ └── Api │ │ ├── Application.php │ │ └── Model │ │ └── Features.php │ └── tests │ ├── Test │ ├── Functional │ │ ├── ApplicationTest.php │ │ └── FeaturesTest.php │ └── Unit │ │ └── FeaturesTest.php │ └── bootstrap.php ├── common └── index.js ├── constant ├── USAGE └── index.js ├── contributing.md ├── controller ├── USAGE └── index.js ├── decorator ├── USAGE └── index.js ├── directive ├── USAGE └── index.js ├── factory ├── USAGE └── index.js ├── filter ├── USAGE └── index.js ├── main └── index.js ├── package.json ├── provider ├── USAGE └── index.js ├── readme.md ├── route ├── USAGE └── index.js ├── script-base.js ├── service ├── USAGE └── index.js ├── templates ├── coffeescript │ ├── app.coffee │ ├── controller.coffee │ ├── decorator.coffee │ ├── directive.coffee │ ├── filter.coffee │ ├── service │ │ ├── constant.coffee │ │ ├── factory.coffee │ │ ├── provider.coffee │ │ ├── service.coffee │ │ └── value.coffee │ └── spec │ │ ├── controller.coffee │ │ ├── directive.coffee │ │ ├── filter.coffee │ │ └── service.coffee ├── common │ ├── app │ │ ├── .buildignore │ │ ├── .htaccess │ │ ├── 404.html │ │ ├── favicon.ico │ │ ├── images │ │ │ └── yeoman.png │ │ ├── index.html │ │ ├── robots.txt │ │ ├── styles │ │ │ ├── main.css │ │ │ └── main.scss │ │ └── views │ │ │ ├── main.html │ │ │ └── view.html │ └── root │ │ ├── .editorconfig │ │ ├── .gitattributes │ │ ├── .jshintrc │ │ ├── _Gruntfile.js │ │ ├── _bower.json │ │ ├── _bowerrc │ │ ├── _package.json │ │ ├── gitignore │ │ └── test │ │ └── .jshintrc └── javascript │ ├── app.js │ ├── controller.js │ ├── decorator.js │ ├── directive.js │ ├── filter.js │ ├── service │ ├── constant.js │ ├── factory.js │ ├── provider.js │ ├── service.js │ └── value.js │ └── spec │ ├── controller.js │ ├── directive.js │ ├── filter.js │ └── service.js ├── test ├── test-appname-substitution.js ├── test-apppath.js ├── test-file-creation.js ├── test-load.js └── test-route-creation.js ├── util.js ├── value ├── USAGE └── index.js └── view ├── USAGE └── index.js /.editorconfig: -------------------------------------------------------------------------------- 1 | # EditorConfig helps developers define and maintain consistent 2 | # coding styles between different editors and IDEs 3 | # editorconfig.org 4 | 5 | root = true 6 | 7 | # Due to a bug in the EditorConfig for SublimeText, we set tab indentation for 8 | # all files and we set exceptions for all files with an extension 9 | 10 | [*] 11 | indent_style = tab 12 | indent_size = 4 13 | 14 | end_of_line = lf 15 | charset = utf-8 16 | trim_trailing_whitespace = true 17 | insert_final_newline = true 18 | 19 | [*.*] 20 | indent_style = space 21 | indent_size = 2 22 | 23 | [*.php] 24 | indent_size = 4 25 | 26 | [*.md] 27 | trim_trailing_whitespace = false 28 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | node_modules 3 | test/tmp 4 | -------------------------------------------------------------------------------- /.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": true, 10 | "newcap": true, 11 | "noarg": true, 12 | "undef": true, 13 | "strict": false, 14 | "globalstrict": true, 15 | "trailing": true, 16 | "smarttabs": true, 17 | "node": true 18 | } 19 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - '0.10' 4 | before_install: 5 | - currentfolder=${PWD##*/} 6 | - if [ "$currentfolder" != 'generator-angular-php' ]; then cd .. && eval "mv $currentfolder generator-angular-php" && cd generator-angular-php; fi 7 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | 2 | ### 0.9.0-1 (2014-06-20) 3 | 4 | 5 | #### Bug Fixes 6 | 7 | * **app:** 8 | * fix bower path problem ([db4ec0eb](yeoman/generator-angular/commit/db4ec0eb101b221135a353d008ed3c662814ac79), closes [#733](yeoman/generator-angular/issues/733)) 9 | * fix provider CoffeeScript template ([c2572d23](yeoman/generator-angular/commit/c2572d236cce5afe5a66037e558325018153ca97)) 10 | * correct cssmin/concat build-tag paths ([27dd848f](yeoman/generator-angular/commit/27dd848f58c45ba5536da502bfd5a147ced35572)) 11 | * **gen:** fix ref to Karma config for --coffee ([380018f0](yeoman/generator-angular/commit/380018f0bbbb6a59d38ee86f39e3879e05c8b203), closes [#748](yeoman/generator-angular/issues/748)) 12 | * **karma:** use the correct CoffeeScript extension ([ddbab964](yeoman/generator-angular/commit/ddbab9646fcc8883d3850e7e9a02daa32e8ea4d8), closes [#737](yeoman/generator-angular/issues/737)) 13 | * **release:** get rid of circular loop ([293ca6a4](yeoman/generator-angular/commit/293ca6a4a365fdfe2f72fb406bd2f4d8f5b3b797)) 14 | 15 | 16 | 17 | ### 0.9.0-1 (2014-06-10) 18 | 19 | 20 | #### Bug Fixes 21 | 22 | * **gen:** 23 | * update wiredep ignore path ([a9c4e354](yeoman/generator-angular/commit/a9c4e3541b50171868f700a0817a592e203e5410)) 24 | * remove font files ([f27566d5](yeoman/generator-angular/commit/f27566d50c56af8a9f8fa357565fc9810c5a8671)) 25 | 26 | 27 | #### Features 28 | 29 | * **app:** move bower_components to root folder ([396a2c04](yeoman/generator-angular/commit/396a2c04b3aeaaafddf9f68287208cee7e9e74e9)) 30 | 31 | 32 | #### Breaking Changes 33 | 34 | * bower_components is now in the /project_root directory 35 | ([396a2c04](yeoman/generator-angular/commit/396a2c04b3aeaaafddf9f68287208cee7e9e74e9)) 36 | 37 | 38 | 39 | ### 0.9.0-0 (2014-06-05) 40 | 41 | 42 | #### Bug Fixes 43 | 44 | * **Gruntfile:** fix usemin bug when using images in css ([fac3d108](yeoman/generator-angular/commit/fac3d1082a2c2120b9f92b86747c26b1421bd942)) 45 | * **app:** 46 | * app is installed at appPath location ([947b872c](yeoman/generator-angular/commit/947b872c57eaaa3c0829d63ce31dcd355d452a82), closes [#578](yeoman/generator-angular/issues/578)) 47 | * app-suffix should populate to sub-generators ([02654419](yeoman/generator-angular/commit/026544191b4526b43517aad89c4f8a02c0271814), closes [#572](yeoman/generator-angular/issues/572)) 48 | * fix Bootstrap font issues ([0a66f54d](yeoman/generator-angular/commit/0a66f54d14f1ae6533e21153ee9e19b1da6626bc), closes [#552](yeoman/generator-angular/issues/552), [#638](yeoman/generator-angular/issues/638), [#645](yeoman/generator-angular/issues/645), [#661](yeoman/generator-angular/issues/661), [#662](yeoman/generator-angular/issues/662), [#665](yeoman/generator-angular/issues/665), [#667](yeoman/generator-angular/issues/667)) 49 | * prevent faulty bowerInstall ignorePath ([fa2e36b8](yeoman/generator-angular/commit/fa2e36b8874cc21c74dc0a740d6ece580c4f0f1f)) 50 | * Remove redundant bootstrap-sass import ([229e58ae](yeoman/generator-angular/commit/229e58aeca71a077f71ac60ae4eebd3b04b30889)) 51 | * **build:** 52 | * update karma.conf.js file location in Gruntfile ([29b2d4d3](yeoman/generator-angular/commit/29b2d4d3db549183e101719290e01488a8e7d10e), closes [#706](yeoman/generator-angular/issues/706)) 53 | * use conservativeCollapse for htmlmin ([06a34d08](yeoman/generator-angular/commit/06a34d0815c3cc31d191f31ee2ef8ecd637142bc)) 54 | * clean subfolders of dist as well ([9db87bf6](yeoman/generator-angular/commit/9db87bf6f61252db604e9ae4e9b13360f8b96eef)) 55 | * change livereload to use connect options ([0f549060](yeoman/generator-angular/commit/0f5490600c1b4bb91a19958986aea63700035ac2), closes [#569](yeoman/generator-angular/issues/569), [#674](yeoman/generator-angular/issues/674)) 56 | * grunt-newer requires a src attribute ([6165b810](yeoman/generator-angular/commit/6165b8101f11ef37811305e6e5dd269da52a3ef2), closes [#620](yeoman/generator-angular/issues/620)) 57 | * add src property to jshint task ([4668e702](yeoman/generator-angular/commit/4668e7028c803da8ae4cdfadce5d7ec99f51843b), closes [#620](yeoman/generator-angular/issues/620)) 58 | * **dep:** update and correct Bower dependencies ([9b592ca4](yeoman/generator-angular/commit/9b592ca4ff72f1c6f515fe63ee1088ac53049afc)) 59 | * **docs:** add info about route generator uri option ([fc4bdc5f](yeoman/generator-angular/commit/fc4bdc5fa46677d381aaabacbd1c76f38153cdba), closes [#650](yeoman/generator-angular/issues/650)) 60 | * **gen:** 61 | * update gen-karma and use its new options ([0f768f1d](yeoman/generator-angular/commit/0f768f1d7515b3d884555a8c5c8e3f01d117cf18), closes [#629](yeoman/generator-angular/issues/629)) 62 | * skip adding route to app file ([7a768583](yeoman/generator-angular/commit/7a7685833baf7be7d18c8fc9afedf76098ff64ba), closes [#694](yeoman/generator-angular/issues/694)) 63 | * fix more appPath, other changes ([36317404](yeoman/generator-angular/commit/36317404bee8edece2247ffc99b2f97e2a34ada5)) 64 | * move test into root folder ([53035aa1](yeoman/generator-angular/commit/53035aa18a26393f72769222f82fc7d0f315e46f)) 65 | * update color logging ([6aba417e](yeoman/generator-angular/commit/6aba417e3d7f00e5560142972a56d8211af7a499)) 66 | * move images to common generator ([cf3b6352](yeoman/generator-angular/commit/cf3b63525bb74e7faed36f45af02fc1d276ad7de)) 67 | * consolidate template files ([22f2f2c3](yeoman/generator-angular/commit/22f2f2c3abf3df58a37daec95e6c0e62b9120057)) 68 | * do not use console to display messages ([9f9831f5](yeoman/generator-angular/commit/9f9831f58e849a33d34e62c6f9bedec4d9896616)) 69 | * **misc:** correct typo in readme ([7200ffcf](yeoman/generator-angular/commit/7200ffcf62827a732cd079eb39e22484eeabc139)) 70 | * **test:** 71 | * remove console.log statement ([096efbae](yeoman/generator-angular/commit/096efbae4bb3cddf0eff6e484734d6b8e6867389)) 72 | * remove old Karma testrunner ([bb5b5859](yeoman/generator-angular/commit/bb5b58592100e62588f705a1978f5f40a9d4c141)) 73 | * add test for testing loading ([f9085968](yeoman/generator-angular/commit/f90859684f3cb211508bf05f8d0ca21c9547f5f6)) 74 | * add test for eventual appPath option ([dd155b1f](yeoman/generator-angular/commit/dd155b1fea1a5dd87107e3439398c717a5ece8b5), closes [#630](yeoman/generator-angular/issues/630)) 75 | * **tests:** 76 | * DRY up more code and update test folders ([ea33f7c1](yeoman/generator-angular/commit/ea33f7c169cf2f4b382d3cf34e1b9a463605478e)) 77 | * style and generator updates ([f8b31572](yeoman/generator-angular/commit/f8b31572c1e4a5700d9c81083899eac44ce14f96)) 78 | 79 | 80 | #### Features 81 | 82 | * **app:** 83 | * add ngAnimate and ngTouch options ([0659621b](yeoman/generator-angular/commit/0659621bc7f810a0f128f71d6873550cb01d22f6), closes [#510](yeoman/generator-angular/issues/510)) 84 | * add a second route if ngRoute is chosen ([0d045f52](yeoman/generator-angular/commit/0d045f523880a55fe75cd237972249902c3e0166)) 85 | * specify uri while generating routes ([d3cea019](yeoman/generator-angular/commit/d3cea019117d975194c36c46c0489ea5e97b81dd), closes [#639](yeoman/generator-angular/issues/639)) 86 | * **build:** 87 | * replace grunt-bower-install with grunt-wiredep ([60ef8d18](yeoman/generator-angular/commit/60ef8d18716a549b4204a471903bea9e87be70e8)) 88 | * replace grunt-rev with grunt-filerev ([149f1625](yeoman/generator-angular/commit/149f1625587dbf7ec68050262d1de17ce671e6e2), closes [#564](yeoman/generator-angular/issues/564)) 89 | * open browser when runnning `serve:dist` ([e9239e72](yeoman/generator-angular/commit/e9239e72d489448c71842df26ee3645f483b56e7)) 90 | * **gen:** 91 | * allow --appPath option for all generators ([d3dd42e3](yeoman/generator-angular/commit/d3dd42e3bae58f74b634920992a08bb2f3e28848)) 92 | * add grunt-ngdoc comments ([11edb9b3](yeoman/generator-angular/commit/11edb9b3841f561b6d1afeed1721f4df11fea0cb)) 93 | 94 | 95 | 96 | ## 0.8.0 (2014-03-27) 97 | 98 | 99 | #### Bug Fixes 100 | 101 | * **app:** 102 | * correct adding scripts path to index.html ([5533ad86](http://github.com/yeoman/generator-angular/commit/5533ad86676dab3e165c4a298f7e6428759e7c18)) 103 | * change "Twitter Bootstrap" to "Bootstrap" ([55a79718](http://github.com/yeoman/generator-angular/commit/55a797182cea37501bcdb1622ebb3cf4b578534b)) 104 | * change the script src to lowercase ([c884c91d](http://github.com/yeoman/generator-angular/commit/c884c91d1dba8e47d27a80857ad33bdd33ca7a7f), closes [#557](http://github.com/yeoman/generator-angular/issues/557)) 105 | * **build:** 106 | * don't copy the bower_components folder in build ([4c53ea97](http://github.com/yeoman/generator-angular/commit/4c53ea975d3a776c416e078389a2657ec4e56ac0), closes [#590](http://github.com/yeoman/generator-angular/issues/590)) 107 | * rewrite relative CSS URLs ([996eff82](http://github.com/yeoman/generator-angular/commit/996eff82b0bd11976daf997c69e12dcdcd643683)) 108 | * **generator:** 109 | * require compass only when enabled ([d4630c33](http://github.com/yeoman/generator-angular/commit/d4630c3307df2f55d21753c3e8ed1fe6d232b44b)) 110 | * list coffee dep only when selected ([c9a69807](http://github.com/yeoman/generator-angular/commit/c9a69807ee18517f973161d3902421b2bee4782e)) 111 | * add closing template tag ([3522514f](http://github.com/yeoman/generator-angular/commit/3522514f999c791e2114483cd8a39a172c794a74)) 112 | * add closing template tag ([0f57d2c4](http://github.com/yeoman/generator-angular/commit/0f57d2c4b8a9686d836faeee08ee7caa7f05a507)) 113 | * **template:** remove IE edge header ([01738116](http://github.com/yeoman/generator-angular/commit/017381168132c8d560a3976c0b97b15a4f120727)) 114 | * **test:** update assertFile syntax ([51e46455](http://github.com/yeoman/generator-angular/commit/51e4645524684e7220ccece1800899d2b87a45e6), closes [#554](http://github.com/yeoman/generator-angular/issues/554)) 115 | 116 | 117 | #### Features 118 | 119 | * **app:** 120 | * add glyphicon to test bootstrap fonts ([953a93b6](http://github.com/yeoman/generator-angular/commit/953a93b6dbbfc25f1b5f536e5ddaeeb8b1a24759)) 121 | * remove minsafe options ([c24e2509](http://github.com/yeoman/generator-angular/commit/c24e25097acb109240f687ace7c214b095d3ee77), closes [#452](http://github.com/yeoman/generator-angular/issues/452)) 122 | * **build:** use bowerInstall on `watch` task ([6fbebb05](http://github.com/yeoman/generator-angular/commit/6fbebb057962edc8daf421c858f82f33abe66125)) 123 | * **deps:** 124 | * upgrade AngularJS version ([6c540961](http://github.com/yeoman/generator-angular/commit/6c5409613b30dc37d845cb8aa040760f885f34af)) 125 | * use official Sass version of Bootstrap ([66829f45](http://github.com/yeoman/generator-angular/commit/66829f453ec5fe48dbf4e75f5bc312bb06bc9ace), closes [#607](http://github.com/yeoman/generator-angular/issues/607)) 126 | * upgrade AngularJS + addons to 1.2.14 ([b4d026f3](http://github.com/yeoman/generator-angular/commit/b4d026f350ba1e8ce087fff66d476c72dd505b60)) 127 | * upgrade to grunt-bower-install 1.0 ([6a167895](http://github.com/yeoman/generator-angular/commit/6a1678953bce069b4ac79f68e0959e80cbdbaa3f)) 128 | * upgrade to Angular 1.2.10 ([023da9d2](http://github.com/yeoman/generator-angular/commit/023da9d2327f90e3128e1e7aecf73d0bc1e2660d)) 129 | 130 | 131 | #### Breaking Changes 132 | 133 | * bower_components is no longer copied into the /dist 134 | folder. 135 | ([4c53ea97](http://github.com/yeoman/generator-angular/commit/4c53ea975d3a776c416e078389a2657ec4e56ac0)) 136 | * Removes the --minsafe from the generator. See the 137 | readme for more information about this change 138 | ([c24e2509](http://github.com/yeoman/generator-angular/commit/c24e25097acb109240f687ace7c214b095d3ee77)) 139 | 140 | 141 | 142 | ### v0.7.1 (2013-12-22) 143 | 144 | 145 | #### Bug Fixes 146 | 147 | * **Gruntfile:** correct attribute quoting ([ca765509](http://github.com/yeoman/generator-angular/commit/ca765509b4bf3d827ac40206ea9bb84936b806cc), closes [#521](http://github.com/yeoman/generator-angular/issues/521)) 148 | 149 | 150 | #### Features 151 | 152 | * **app:** upgrade to AngularJS 1.2.6 ([2f7fa90c](http://github.com/yeoman/generator-angular/commit/2f7fa90cc698edb565926fcf6cce77c52f5785ae)) 153 | 154 | 155 | ## v0.7.0 (2013-12-20) 156 | 157 | 158 | #### Bug Fixes 159 | 160 | * **app:** 161 | * copy view files to dist folder ([8a52a265](http://github.com/yeoman/generator-angular/commit/8a52a265aa15a0f589109d6cd1dac4ae7dc5a3e9)) 162 | * only copy CSS if Compass is not installed ([7e586745](http://github.com/yeoman/generator-angular/commit/7e58674585e138c0f2eb81f46ef2cc4f1b9a3bf8)) 163 | * services use classified names ([56a71a83](http://github.com/yeoman/generator-angular/commit/56a71a83cdf90f81bb37b422ba4d40e75d28e1fe), closes [#484](http://github.com/yeoman/generator-angular/issues/484)) 164 | * reload JS files in watch ([d20f5bd2](http://github.com/yeoman/generator-angular/commit/d20f5bd20ba95d47447f8acceee491a0a0ba9724)) 165 | * **build:** deselecting ngRoute does remove route stuff ([a358c1ae](http://github.com/yeoman/generator-angular/commit/a358c1ae69bff6a7708ea0a77248698f931f2e4d), closes [#486](http://github.com/yeoman/generator-angular/issues/486)) 166 | * **deps:** hard-pin angular 1.2.5 ([49c7f980](http://github.com/yeoman/generator-angular/commit/49c7f9802c6d7e9347c73ffe018c36b750342cb1)) 167 | * **gen:** fix bower install prompt during project gen ([706f1336](http://github.com/yeoman/generator-angular/commit/706f1336852923e409d669ae6fc6faeda7bbb017), closes [#505](http://github.com/yeoman/generator-angular/issues/505)) 168 | 169 | 170 | #### Features 171 | 172 | * **app:** 173 | * add jasmine browser global to test jshintrc ([11b6ed42](http://github.com/yeoman/generator-angular/commit/11b6ed42b5e941f25cc305eb5c4e8ba49586cf64)) 174 | * use lowercase file names ([23e5d772](http://github.com/yeoman/generator-angular/commit/23e5d7724e7e02e4b974f4e804f35eca33a53aea), closes [#463](http://github.com/yeoman/generator-angular/issues/463)) 175 | * use htmlmin for smaller HTML files ([2b85a52a](http://github.com/yeoman/generator-angular/commit/2b85a52a054ac8cf1ab86ce1cd3de7819d30ea52), closes [#469](http://github.com/yeoman/generator-angular/issues/469)) 176 | * use grunt-bower-install for dep management ([ba7b5051](http://github.com/yeoman/generator-angular/commit/ba7b505117307059a6d013d838c8aeff6db0e452), closes [#497](http://github.com/yeoman/generator-angular/issues/497)) 177 | * **gen:** 178 | * additional work for compass support ([11cb9943](http://github.com/yeoman/generator-angular/commit/11cb99437271b6e8f6cdaee8fd5fc9cda7a20d1d)) 179 | * add Compass support to the initialization process ([7fac1194](http://github.com/yeoman/generator-angular/commit/7fac1194179df3181f52258b0aa7333799fec253)) 180 | 181 | 182 | #### Breaking Changes 183 | 184 | * Deselecting ngRoute adds controller and ng-include to index.html 185 | ([a358c1ae](http://github.com/yeoman/generator-angular/commit/a358c1ae69bff6a7708ea0a77248698f931f2e4d)) 186 | * `--minsafe` flag is now deprecated. ([f0bb8da2](http://github.com/yeoman/generator-angular/commit/f0bb8da2d67c3f627bf775e2d4f53340b5c980c4), closes [#452](http://github.com/yeoman/generator-angular/issues/452)) 187 | * `grunt server` is now deprecated. Use `grunt serve` instead 188 | ([ef056319](http://github.com/yeoman/generator-angular/commit/ef0563192a9e3fc834ae97e7ec68470bcfdf56eb)) 189 | 190 | 191 | ## v0.6.0 (2013-12-05) 192 | 193 | #### Breaking Changes 194 | 195 | * `grunt server` is being deprecated 196 | ([ef056319](http://github.com/yeoman/generator-angular/commit/ef0563192a9e3fc834ae97e7ec68470bcfdf56eb)) 197 | 198 | #### Bug Fixes 199 | 200 | * **app:** 201 | * use test-specifc jshintrc ([c00c091b](http://github.com/yeoman/generator-angular/commit/c00c091bdca2b55685d81a2b84b002d73aacbdcc)) 202 | * add webapp upstream features and better coffee ([c23acebb](http://github.com/yeoman/generator-angular/commit/c23acebbd8fabd391bfeee0d424f26e59f756a03)) 203 | * use grunt-newer for styles and jshint ([b1eeb68a](http://github.com/yeoman/generator-angular/commit/b1eeb68a8290aee930887fc473034ee7f8e2ccc3)) 204 | * standardize comments and comment out uglify:dist ([d5d3e458](http://github.com/yeoman/generator-angular/commit/d5d3e458e70d054707c70d058454fdd3d94070fe), closes [#455](http://github.com/yeoman/generator-angular/issues/455)) 205 | * only include sass if sass is selected ([597b8b5c](http://github.com/yeoman/generator-angular/commit/597b8b5cfab77b78e7f6091140beda2eeee0ed54), closes [#449](http://github.com/yeoman/generator-angular/issues/449)) 206 | 207 | * **deps:** upgrade dependencies ([3a57216f](http://github.com/yeoman/generator-angular/commit/3a57216ff9e3192db3804634f360253e9fcce69d)) 208 | 209 | * **gen:** 210 | * script paths use forward slashes ([40aa61dc](http://github.com/yeoman/generator-angular/commit/40aa61dcc1bf31918bea3d2ce9a84c93554aa64a), closes [#410](http://github.com/yeoman/generator-angular/issues/410)) 211 | * remove extra "App" from service spec files ([4053f11f](http://github.com/yeoman/generator-angular/commit/4053f11f800280569f5b7396ad015f0a6bcc7b49)) 212 | * options should have descriptions ([da001832](http://github.com/yeoman/generator-angular/commit/da001832dbdb268b3bf38f359c72b40c401273e4)) 213 | 214 | * **template:** remove redundant closing tag ([d1e560e0](http://github.com/yeoman/generator-angular/commit/d1e560e0675ecb70e6c4b59cf4de9df461434a31), closes [#441](http://github.com/yeoman/generator-angular/issues/441)) 215 | * **bootstrap:** some plugins have ordering dependencies ([3da4a130](http://github.com/yeoman/generator-angular/commit/3da4a1301e0b744c7a6054fafff26fff16b6442b)) 216 | * **docs:** Add coffeescript=false to readme ([abd7dc38](http://github.com/yeoman/generator-angular/commit/abd7dc38be0cf511307c784f30d59c9fdcaea3e2)) 217 | * **styles:** update path to icon images ([8daad4f2](http://github.com/yeoman/generator-angular/commit/8daad4f2de9dbde4fcc810527da7c9607e1db8d4)) 218 | 219 | #### Features 220 | 221 | * **app:** 222 | * imagemin handles gifs ([9341eb9b](http://github.com/yeoman/generator-angular/commit/9341eb9b710b95c95407dc54ed4af6aa4a496426)) 223 | * run unit tests when test scripts are changed ([94af0b51](http://github.com/yeoman/generator-angular/commit/94af0b510982b05c5a1939966e96aeccce087500)) 224 | * reload grunt server when gruntfile is updated ([50c6abb9](http://github.com/yeoman/generator-angular/commit/50c6abb9cce09a149253ceb8496feca813a71136)) 225 | * update to angular 1.2.0 ([77082c6b](http://github.com/yeoman/generator-angular/commit/77082c6b8d1dda76579f1970a270dffc359f027f)) 226 | * upgrade to Bootstrap 3.0.1 ([59f4b1ba](http://github.com/yeoman/generator-angular/commit/59f4b1ba73842b758174ad44a7da60af4f4db63f)) 227 | 228 | * **build:** 229 | * compile only changed coffeescript files in watch task ([4196e379](http://github.com/yeoman/generator-angular/commit/4196e37912993ae37812fa19d9378d8b8d2cc9da), closes [#425](http://github.com/yeoman/generator-angular/issues/425)) 230 | * deprecate server in favor of serve ([ef056319](http://github.com/yeoman/generator-angular/commit/ef0563192a9e3fc834ae97e7ec68470bcfdf56eb)) 231 | 232 | * **gen:** 233 | * add image file as example ([b161c298](http://github.com/yeoman/generator-angular/commit/b161c2982d86df1bb3de44cd9fa8aee05fc66ff3)) 234 | * allow app names to have custom suffix ([09f0f7b3](http://github.com/yeoman/generator-angular/commit/09f0f7b3a8c3264b7527bc9fed8c709becec99eb)) 235 | * add option to not add to index ([486ee146](http://github.com/yeoman/generator-angular/commit/486ee14660ac51b7cfcb4b7de50135833954f193)) 236 | 237 | 238 | 239 | ### v0.5.1 (2013-10-22) 240 | 241 | 242 | #### Bug Fixes 243 | 244 | * **app:** test setup in default configuration ([2bebccbd](http://github.com/yeoman/generator-angular/commit/2bebccbdd15d177805440b6d1ec84cc38a2b4678)) 245 | 246 | 247 | ## v0.5.0 (2013-10-17) 248 | 249 | 250 | #### Bug Fixes 251 | 252 | * **app:** 253 | * serve files from correct place ([fe2bad04](http://github.com/yeoman/generator-angular/commit/fe2bad0417b3138fa2788c17abcf7eb5be5f3e91)) 254 | * include bootstrap images for css/scss ([e88dba43](http://github.com/yeoman/generator-angular/commit/e88dba43f2e714d69bca366cade453f49a24b62c), closes [#196](http://github.com/yeoman/generator-angular/issues/196)) 255 | * allow normal javascript to be created ([c8190b55](http://github.com/yeoman/generator-angular/commit/c8190b55284e8c1570cc8fafdc8723250f43829b), closes [#329](http://github.com/yeoman/generator-angular/issues/329), [#316](http://github.com/yeoman/generator-angular/issues/316)) 256 | * conditional include of jquery ([bc1e68e3](http://github.com/yeoman/generator-angular/commit/bc1e68e30450edc16145b934487f6df5eaaddcd8), closes [#362](http://github.com/yeoman/generator-angular/issues/362)) 257 | * **build:** 258 | * remove references to global yeomanConfig ([a0f16e26](http://github.com/yeoman/generator-angular/commit/a0f16e265729586802121c0fe3111f974e5145ec)) 259 | * update to grunt-contrib-connect 0.5.0 ([67c0ebf0](http://github.com/yeoman/generator-angular/commit/67c0ebf081889658a33bc690c530c3c8bc8a2c12)) 260 | * update to grunt-contrib-connect 0.4.0 ([368ad7f9](http://github.com/yeoman/generator-angular/commit/368ad7f9a16be0ee67e5182be581669017788f16)) 261 | * **docs:** fixed typo in readme ([a967907c](http://github.com/yeoman/generator-angular/commit/a967907cf523bac752b3fa9ea6363767d8855162)) 262 | * **generator:** add app modules dependency to app ([a45b71c9](http://github.com/yeoman/generator-angular/commit/a45b71c95c18deb85ff7a1538c0b0744e4faa508), closes [#230](http://github.com/yeoman/generator-angular/issues/230)) 263 | * **templates:** 264 | * Gruntfile indentation ([6f7d17e2](http://github.com/yeoman/generator-angular/commit/6f7d17e2a0f1f7f9f8cac3157beb07b82e8cf400)) 265 | * take out semicolons in coffeescript ([e38124ee](http://github.com/yeoman/generator-angular/commit/e38124eeb369b7741adc263f1763c618a918ee65)) 266 | * correct coffee provider template ([86aefe5d](http://github.com/yeoman/generator-angular/commit/86aefe5da49abe82e054666641f8ee4bdc8d555e)) 267 | * value generator should use value template ([67d0c5ad](http://github.com/yeoman/generator-angular/commit/67d0c5ad5cbc58a2dfcfd8f3db1f45be21afe357)) 268 | * **test:** update tests to match service files ([c30464c3](http://github.com/yeoman/generator-angular/commit/c30464c3a5216169026c23a6fea23d273bd0b948), closes [#338](http://github.com/yeoman/generator-angular/issues/338), [#354](http://github.com/yeoman/generator-angular/issues/354)) 269 | * **views:** correct path for sub views ([0568e744](http://github.com/yeoman/generator-angular/commit/0568e74446c5a8e28d2cea1a9a9a5886be190d7d), closes [#359](http://github.com/yeoman/generator-angular/issues/359)) 270 | 271 | 272 | ## v0.4.0 (2013-08-21) 273 | 274 | 275 | #### Bug Fixes 276 | 277 | * **cli:** fix typo in angular:view generator usage ([d62c2e34](http://github.com/yeoman/generator-angular/commit/d62c2e348bcc61a6794ca23df02b6cce3c79d993)) 278 | * **coffee:** 279 | * remove extraneous commas and returns ([6df875cd](http://github.com/yeoman/generator-angular/commit/6df875cd7167aa4a4e9f98a82d2f7fba98a20b0b)) 280 | * remove the semi-colon from the coffee script templates ([cd46aa88](http://github.com/yeoman/generator-angular/commit/cd46aa88953e60d81dfef64b999f751dc4468ab7)) 281 | * **docs:** 282 | * add decorator generator description ([85f07648](http://github.com/yeoman/generator-angular/commit/85f076485ffabf790fe0b7d55b7e3def3a041a6d)) 283 | * add contributing info to contributing file ([2461aad0](http://github.com/yeoman/generator-angular/commit/2461aad08afe186995d737a1d3dd595c20ec3fb3)) 284 | * **readme:** Remove `yo` installation step ([21f00e50](http://github.com/yeoman/generator-angular/commit/21f00e50571d272d19aea1431177f2d7157ee7be)) 285 | * **templates:** 286 | * removed grunt-karma from deps ([19a796f7](http://github.com/yeoman/generator-angular/commit/19a796f71925b6b33232d8a9a8b4f712de80ec40)) 287 | * classify services registered with .service ([8e1d6fdf](http://github.com/yeoman/generator-angular/commit/8e1d6fdf0d3ef23cf0670512295e03cc0f4516d6)) 288 | * new scope for directive spec ([2753c990](http://github.com/yeoman/generator-angular/commit/2753c990dbdc8efc7a5f245868cd10f15080c140)) 289 | * **test:** Add correct paths to generated files ([1d6f3fbf](http://github.com/yeoman/generator-angular/commit/1d6f3fbfcc315316a44b468418918afaad871f57)) 290 | * **wording:** clarify compass/scss feature prompt ([5521fd73](http://github.com/yeoman/generator-angular/commit/5521fd73d396763568b5e7c08043a82a4e8864a9)) 291 | 292 | 293 | #### Features 294 | 295 | * **build:** 296 | * generate karma 0.10 config ([e1cb2067](http://github.com/yeoman/generator-angular/commit/e1cb206710f54c8bea6ed8870566ac4c3e248b40)) 297 | * add autoprefixer support ([c4dfd61d](http://github.com/yeoman/generator-angular/commit/c4dfd61d860f86a97026d1e5188ab78a87f4e6a1), closes [#317](http://github.com/yeoman/generator-angular/issues/317)) 298 | * switch to use load-grunt-tasks ([4e030c78](http://github.com/yeoman/generator-angular/commit/4e030c78387ec2a60581ff6346b707c98ddb2508)) 299 | * show elapsed time for grunt tasks ([cacdd0fb](http://github.com/yeoman/generator-angular/commit/cacdd0fb5815355f6e35343c53e876352e622180)) 300 | * **coffee:** generate source maps for coffeescript ([38a872b3](http://github.com/yeoman/generator-angular/commit/38a872b31e9ccef1aac76bec330c3490303abdac)) 301 | * **gen:** Change ga.js to analytics.js ([17ae9e63](http://github.com/yeoman/generator-angular/commit/17ae9e63b2d11d271b36282bb34567b716099cb9)) 302 | 303 | 304 | ## v0.3.1 (2013-07-24) 305 | 306 | 307 | #* **Bug Fixes:** 308 | 309 | * **app:** 310 | * order of script inclusions ([9919b2d0](http://github.com/yeoman/generator-angular/commit/9919b2d0bb749cbe5e795608c2b93c3504e3298b), closes [#278](http://github.com/yeoman/generator-angular/issues/278)) 311 | * copy glyphicons for sass ([2c458009](http://github.com/yeoman/generator-angular/commit/2c4580096572678de6212c8592fb553c10b3a4c0), closes [#269](http://github.com/yeoman/generator-angular/issues/269)) 312 | * add jQuery \ into index.html template ([3766b4ff](http://github.com/yeoman/generator-angular/commit/3766b4ffe1b91a647a34577ae529d11c994e3a1d)) 313 | * **docs:** 314 | * fix section explaining generating services ([8b4787c6](http://github.com/yeoman/generator-angular/commit/8b4787c649b918cb2baf78369e86c86156bca2ec)) 315 | * Add explicit instructions for installing yo ([8404c068](http://github.com/yeoman/generator-angular/commit/8404c0687ab582e15b1f46f96da4f7812d641912)) 316 | 317 | 318 | #* **Features:** 319 | 320 | * **app:** 321 | * generate Travis config ([38a4ce9b](http://github.com/yeoman/generator-angular/commit/38a4ce9baa207c49c79b2f3128c2c3637164c011)) 322 | * use checkboxes for module selection ([65fe9d25](http://github.com/yeoman/generator-angular/commit/65fe9d25fdc1f9fa9c24c4858915c2b63b4531cb)) 323 | * add jshintrc for testing folder ([8727288b](http://github.com/yeoman/generator-angular/commit/8727288bcefdb255f3c24cf80ab1c7868b86d044)) 324 | * **build:** add support for svg optimization ([03d63c69](http://github.com/yeoman/generator-angular/commit/03d63c69e8006e563baee0cc4a4ba459e7c13ccd)) 325 | 326 | 327 | ## 0.3.0 (2013-06-26) 328 | 329 | #* **Features:** 330 | 331 | * **decorator:** 332 | * Add decorator template files ([c9f80b3d](http://github.com/yeoman/generator-angular/commit/c9f80b3d)) 333 | * Define creation of decorator at decorator/index.js and added USAGE File ([4c53c1ad](http://github.com/yeoman/generator-angular/commit/4c53c1ad)) 334 | * Add prompt if file already exists ([7d9b862c](http://github.com/yeoman/generator-angular/commit/7d9b862c)) 335 | 336 | * **build:** 337 | * Replace regard with contrib-watch ([edf00565](http://github.com/yeoman/generator-angular/commit/edf00565)) 338 | 339 | #* **Bug Fixes:** 340 | 341 | * **build:** 342 | * bad concatenation of main.css ([4c7e4b29](http://github.com/yeoman/generator-angular/commit/4c7e4b29)) 343 | * Bumped yeoman-generator version for new prompt ([9e899bb2](http://github.com/yeoman/generator-angular/commit/9e899bb2)) 344 | * don't override generated css files ([dd6a0cb1](http://github.com/yeoman/generator-angular/commit/dd6a0cb1)) 345 | * use Usemin for all CSS. ([e6c2fa52](http://github.com/yeoman/generator-angular/commit/e6c2fa52)) 346 | * dropped nospawn option from watch ([02f61f82](http://github.com/yeoman/generator-angular/commit/02f61f82)) 347 | * add svg files to the copy task ([4b897ac8](http://github.com/yeoman/generator-angular/commit/4b897ac8)) 348 | * updated generated dependencies ([cab7c423](http://github.com/yeoman/generator-angular/commit/cab7c423)) 349 | * add httpFontsPath to Gruntfile ([b00deb1a](http://github.com/yeoman/generator-angular/commit/b00deb1a)) 350 | * coffeescript build was empty ([54edc9de](http://github.com/yeoman/generator-angular/commit/54edc9de)) 351 | * add compass task only if compass-flavored bootstrap is selected ([4408413e](http://github.com/yeoman/generator-angular/commit/4408413e)) 352 | 353 | * **app:** 354 | * Bootstrap Compass no prompt on Bootstrap no ([e73ffc49](http://github.com/yeoman/generator-angular/commit/e73ffc49)) 355 | * Use boolean prompts ([da89e70d](http://github.com/yeoman/generator-angular/commit/da89e70d)) 356 | * components to bower_components ([01cee4ba](http://github.com/yeoman/generator-angular/commit/01cee4ba)) 357 | 358 | * **coffee:** syntax for minsafe directives ([62677ec0](http://github.com/yeoman/generator-angular/commit/62677ec0)) 359 | 360 | * **decorator:** 361 | 362 | * removed second dot in warning message ([6a89f8e5](http://github.com/yeoman/generator-angular/commit/6a89f8e5)) 363 | * use [] instead of new Array() to initialize prompts (jsHint) ([360222a6](http://github.com/yeoman/generator-angular/commit/360222a6)) 364 | 365 | * **test:** Updated tests for new prompt ([64e57571](http://github.com/yeoman/generator-angular/commit/64e57571)) 366 | 367 | * **cli:** fix typo in angular:constant generator usage ([6cbb80fd](http://github.com/yeoman/generator-angular/commit/6cbb80fd)) 368 | 369 | 370 | ## v0.2.2 (2013-04-20) 371 | 372 | #* **Features:** 373 | * **build:** Integrate grunt-rev into build process (87bab71) 374 | 375 | * **app:** 376 | 377 | * automatically install dependencies (9f95630) 378 | * add coffee option to Karma generator (e81b624) 379 | 380 | * **misc:** add Grunt support to automate releases and changelogs (9daa50a) 381 | 382 | #* **Bug Fixes:** 383 | * **build:** 384 | 385 | * remove all files except git related on clean (21a0f43) 386 | 387 | * fix Bower error caused by incorrect templates. (0ab5448) 388 | 389 | * Moved duplicate grunt options into own section (3869ca8) 390 | 391 | * grunt-bower-hooks was renamed (3bbaacd) 392 | 393 | * Watch SVG files. Fixes generator-webapp#41 (45fe8ab) 394 | 395 | * display correct message when running npm/bower (3498aa1) 396 | 397 | * add Bootstrap reference when not using Compass (d123897) 398 | 399 | * add SVG files to Grunt rev task. (3c8daab) 400 | 401 | * Changed to shallow copy fonts (1f6b864) 402 | 403 | * Ignore test subfolder (a07627b) 404 | 405 | * finify bootstrap img (263ce61) 406 | 407 | * **coffee:** 408 | 409 | * Fix compiling coffeescript files (71daa7f) 410 | 411 | * fix loading coffeescript tests (9692a21) 412 | 413 | * fix coffeescript directive test (aa2a9c0) 414 | 415 | * rewrite app.coffee file when called with --coffee (0f5256d) 416 | 417 | * **app:** 418 | 419 | * Remove `process.cwd()` from CS detection (3a707f4) 420 | 421 | * use this.env.options.appPath (404c752) 422 | 423 | * use `installDependencies()` method (8369d9a) 424 | 425 | * invoke karma:app with `skip-install` option if defined (7e47dc2) 426 | 427 | * tag closing inconsistency (ref #177) (51bd8d8) 428 | 429 | * **test:** 430 | 431 | * Use $scope in tests instead of {} (58603bd) 432 | 433 | * add Node 0.10 to travis file (60b1ea7) 434 | 435 | * **gen:** 436 | 437 | * Fix controller spec generation (3bb58eb) 438 | 439 | * remove trailing comma in gruntfile. (32afa5a) 440 | 441 | * **readme:** 442 | 443 | * add note to readme about making a node_modules dir until global generators are supported (73a2450) 444 | 445 | * add a note about running commands from the root app folder (f986c77) 446 | 447 | * switched to global generators (18ef336) 448 | 449 | * add note to readme about commit message conventions (d125dd2) 450 | 451 | * Improve readme (8262b93) 452 | 453 | * added documentation of route adding (7c5e03c) 454 | 455 | * Corrected file extension in example (a1149ea) 456 | 457 | * **tests:** skip install on tests (5035d94) 458 | 459 | 460 | ## v0.2.1 (2013-04-07) 461 | 462 | #* **Features:** 463 | * **build:** Integrate grunt-rev into build process (87bab71) 464 | 465 | * **app:** automatically install dependencies (9f95630) 466 | 467 | * **misc:** add Grunt support to automate releases and changelogs (9daa50a) 468 | 469 | 470 | 471 | #* **Bug Fixes:** 472 | * **build:** 473 | 474 | * remove all files except git related on clean (21a0f43) 475 | 476 | * fix Bower error caused by incorrect templates. (0ab5448) 477 | 478 | * Moved duplicate grunt options into own section (3869ca8) 479 | 480 | * grunt-bower-hooks was renamed (3bbaacd) 481 | 482 | * Watch SVG files. Fixes generator-webapp#41 (45fe8ab) 483 | 484 | * **coffee:** 485 | 486 | * Fix compiling coffeescript files (71daa7f) 487 | 488 | * fix loading coffeescript tests (9692a21) 489 | 490 | * fix coffeescript directive test (aa2a9c0) 491 | 492 | * rewrite app.coffee file when called with --coffee (0f5256d) 493 | 494 | * **app:** 495 | 496 | * Remove `process.cwd()` from CS detection (3a707f4) 497 | 498 | * **test:** 499 | 500 | * Use $scope in tests instead of {} (58603bd) 501 | 502 | * **gen:** 503 | 504 | * Fix controller spec generation (3bb58eb) 505 | 506 | * **readme:** 507 | 508 | * add note to readme about making a node_modules dir until global generators are supported (73a2450) 509 | 510 | * add a note about running commands from the root app folder (f986c77) 511 | -------------------------------------------------------------------------------- /Gruntfile.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | var semver = require('semver'); 3 | 4 | module.exports = function (grunt) { 5 | require('load-grunt-tasks')(grunt); 6 | 7 | grunt.initConfig({ 8 | pkg: require('./package.json'), 9 | jshint: { 10 | all: { 11 | options: { 12 | jshintrc: './.jshintrc' 13 | }, 14 | src: [ 15 | '**/index.js', 16 | '*.js', 17 | '!test/**/*.js', 18 | '!node_modules/**/*.js' 19 | ] 20 | } 21 | }, 22 | changelog: { 23 | options: { 24 | dest: 'CHANGELOG.md', 25 | versionFile: 'package.json' 26 | } 27 | }, 28 | release: { 29 | options: { 30 | bump: false, // we have our own bump 31 | file: 'package.json', 32 | commitMessage: 'chore(release): Release version <%= version %>', 33 | tagName: 'v<%= version %>' 34 | } 35 | }, 36 | stage: { 37 | options: { 38 | files: ['CHANGELOG.md'] 39 | } 40 | } 41 | }); 42 | 43 | grunt.registerTask('default', ['jshint']); 44 | 45 | grunt.registerTask('bump', 'Bump manifest version', function (type) { 46 | var options = this.options({ 47 | file: grunt.config('pkgFile') || 'package.json' 48 | }); 49 | 50 | function setup(file, type) { 51 | var pkg = grunt.file.readJSON(file); 52 | var newVersion = pkg.version = semver.inc(pkg.version, type || 'patch'); 53 | return { 54 | file: file, 55 | pkg: pkg, 56 | newVersion: newVersion 57 | }; 58 | } 59 | 60 | var config = setup(options.file, type); 61 | grunt.file.write( 62 | config.file, 63 | JSON.stringify(config.pkg, null, ' ') + '\n' 64 | ); 65 | grunt.log.ok('Version bumped to ' + config.newVersion); 66 | }); 67 | 68 | grunt.registerTask('stage', 'Git adds files', function () { 69 | var files = this.options().files; 70 | grunt.util.spawn({ 71 | cmd: process.platform === 'win32' ? 'git.cmd' : 'git', 72 | args: ['add'].concat(files) 73 | }, grunt.task.current.async()); 74 | }); 75 | 76 | // grunt-release will only commit the package.json file by default. Until 77 | // https://github.com/geddski/grunt-release/pull/43/files lands, it should 78 | // be patched to do the same so it commits the changelog as well. 79 | grunt.registerTask('publish', function (type) { 80 | grunt.task.run([ 81 | 'default', 82 | 'bump' + (type ? ':' + type : ''), 83 | 'changelog', 84 | 'stage', 85 | 'release' 86 | ]); 87 | }); 88 | }; 89 | -------------------------------------------------------------------------------- /app/USAGE: -------------------------------------------------------------------------------- 1 | Description: 2 | Creates a default AngularJS app 3 | 4 | Example: 5 | yo angular-php [--coffee] 6 | 7 | This will create: 8 | Gruntfile.js 9 | bower.json 10 | 11 | app/index.html 12 | app/scripts/your-app-name-here.js 13 | app/scripts/controllers/main.js 14 | app/bower_components/angular/angular.js 15 | app/styles/main.css 16 | app/views/main.html 17 | 18 | test/lib/angular-mocks.js 19 | test/spec/controllers/main.js 20 | -------------------------------------------------------------------------------- /app/index.js: -------------------------------------------------------------------------------- 1 | 'use strict'; 2 | var fs = require('fs'); 3 | var path = require('path'); 4 | var util = require('util'); 5 | var angularUtils = require('../util.js'); 6 | var yeoman = require('yeoman-generator'); 7 | var yosay = require('yosay'); 8 | var wiredep = require('wiredep'); 9 | var chalk = require('chalk'); 10 | 11 | var Generator = module.exports = function Generator(args, options) { 12 | yeoman.generators.Base.apply(this, arguments); 13 | this.argument('appname', { type: String, required: false }); 14 | this.appname = this.appname || path.basename(process.cwd()); 15 | this.appname = this._.camelize(this._.slugify(this._.humanize(this.appname))); 16 | 17 | this.option('app-suffix', { 18 | desc: 'Allow a custom suffix to be added to the module name', 19 | type: String, 20 | required: 'false' 21 | }); 22 | this.env.options['app-suffix'] = this.options['app-suffix']; 23 | this.scriptAppName = this.appname + angularUtils.appName(this); 24 | 25 | args = ['main']; 26 | 27 | if (typeof this.env.options.appPath === 'undefined') { 28 | this.option('appPath', { 29 | desc: 'Generate CoffeeScript instead of JavaScript' 30 | }); 31 | 32 | this.env.options.appPath = this.options.appPath; 33 | 34 | if (!this.env.options.appPath) { 35 | try { 36 | this.env.options.appPath = require(path.join(process.cwd(), 'bower.json')).appPath; 37 | } catch (e) {} 38 | } 39 | this.env.options.appPath = this.env.options.appPath || 'app'; 40 | this.options.appPath = this.env.options.appPath; 41 | } 42 | 43 | this.appPath = this.env.options.appPath; 44 | 45 | if (typeof this.env.options.coffee === 'undefined') { 46 | this.option('coffee', { 47 | desc: 'Generate CoffeeScript instead of JavaScript' 48 | }); 49 | 50 | // attempt to detect if user is using CS or not 51 | // if cml arg provided, use that; else look for the existence of cs 52 | if (!this.options.coffee && 53 | this.expandFiles(path.join(this.appPath, '/scripts/**/*.coffee'), {}).length > 0) { 54 | this.options.coffee = true; 55 | } 56 | 57 | this.env.options.coffee = this.options.coffee; 58 | } 59 | 60 | this.hookFor('angular-php:common', { 61 | args: args 62 | }); 63 | 64 | this.hookFor('angular-php:main', { 65 | args: args 66 | }); 67 | 68 | this.hookFor('angular-php:controller', { 69 | args: args 70 | }); 71 | 72 | this.on('end', function () { 73 | 74 | var enabledComponents = []; 75 | 76 | if (this.animateModule) { 77 | enabledComponents.push('angular-animate/angular-animate.js'); 78 | } 79 | 80 | if (this.cookiesModule) { 81 | enabledComponents.push('angular-cookies/angular-cookies.js'); 82 | } 83 | 84 | if (this.resourceModule) { 85 | enabledComponents.push('angular-resource/angular-resource.js'); 86 | } 87 | 88 | if (this.routeModule) { 89 | enabledComponents.push('angular-route/angular-route.js'); 90 | } 91 | 92 | if (this.sanitizeModule) { 93 | enabledComponents.push('angular-sanitize/angular-sanitize.js'); 94 | } 95 | 96 | if (this.touchModule) { 97 | enabledComponents.push('angular-touch/angular-touch.js'); 98 | } 99 | 100 | enabledComponents = [ 101 | 'angular/angular.js', 102 | 'angular-mocks/angular-mocks.js' 103 | ].concat(enabledComponents).join(','); 104 | 105 | var jsExt = this.options.coffee ? 'coffee' : 'js'; 106 | 107 | this.invoke('karma:app', { 108 | options: { 109 | 'skip-install': this.options['skip-install'], 110 | 'base-path': '../', 111 | 'coffee': this.options.coffee, 112 | 'travis': true, 113 | 'bower-components': enabledComponents, 114 | 'app-files': 'app/scripts/**/*.' + jsExt, 115 | 'test-files': [ 116 | 'test/mock/**/*.' + jsExt, 117 | 'test/spec/**/*.' + jsExt 118 | ].join(','), 119 | 'bower-components-path': 'bower_components' 120 | } 121 | }); 122 | 123 | this.installDependencies({ 124 | skipInstall: this.options['skip-install'], 125 | skipMessage: this.options['skip-message'], 126 | callback: function() { 127 | this._injectDependencies(); 128 | this._installPhpDependencies(); 129 | }.bind(this) 130 | }); 131 | 132 | if (this.env.options.ngRoute) { 133 | this.invoke('angular-php:route', { 134 | args: ['about'] 135 | }); 136 | } 137 | }); 138 | 139 | this.pkg = require('../package.json'); 140 | this.sourceRoot(path.join(__dirname, '../templates/common')); 141 | }; 142 | 143 | util.inherits(Generator, yeoman.generators.Base); 144 | 145 | Generator.prototype.welcome = function welcome() { 146 | if (!this.options['skip-welcome-message']) { 147 | this.log(yosay()); 148 | this.log( 149 | chalk.magenta( 150 | 'Out of the box I include Bootstrap and some AngularJS recommended modules.' + 151 | '\n' 152 | ) 153 | ); 154 | } 155 | 156 | if (this.options.minsafe) { 157 | this.log.error( 158 | 'The --minsafe flag has been removed. For more information, see' + 159 | '\nhttps://github.com/yeoman/generator-angular#minification-safe.' + 160 | '\n' 161 | ); 162 | } 163 | }; 164 | 165 | Generator.prototype.askForCompass = function askForCompass() { 166 | var cb = this.async(); 167 | 168 | this.prompt([{ 169 | type: 'confirm', 170 | name: 'compass', 171 | message: 'Would you like to use Sass (with Compass)?', 172 | default: true 173 | }], function (props) { 174 | this.compass = props.compass; 175 | 176 | cb(); 177 | }.bind(this)); 178 | }; 179 | 180 | Generator.prototype.askForBootstrap = function askForBootstrap() { 181 | var compass = this.compass; 182 | var cb = this.async(); 183 | 184 | this.prompt([{ 185 | type: 'confirm', 186 | name: 'bootstrap', 187 | message: 'Would you like to include Bootstrap?', 188 | default: true 189 | }, { 190 | type: 'confirm', 191 | name: 'compassBootstrap', 192 | message: 'Would you like to use the Sass version of Bootstrap?', 193 | default: true, 194 | when: function (props) { 195 | return props.bootstrap && compass; 196 | } 197 | }], function (props) { 198 | this.bootstrap = props.bootstrap; 199 | this.compassBootstrap = props.compassBootstrap; 200 | 201 | cb(); 202 | }.bind(this)); 203 | }; 204 | 205 | Generator.prototype.askForModules = function askForModules() { 206 | var cb = this.async(); 207 | 208 | var prompts = [{ 209 | type: 'checkbox', 210 | name: 'modules', 211 | message: 'Which modules would you like to include?', 212 | choices: [ 213 | { 214 | value: 'animateModule', 215 | name: 'angular-animate.js', 216 | checked: true 217 | }, { 218 | value: 'cookiesModule', 219 | name: 'angular-cookies.js', 220 | checked: true 221 | }, { 222 | value: 'resourceModule', 223 | name: 'angular-resource.js', 224 | checked: true 225 | }, { 226 | value: 'routeModule', 227 | name: 'angular-route.js', 228 | checked: true 229 | }, { 230 | value: 'sanitizeModule', 231 | name: 'angular-sanitize.js', 232 | checked: true 233 | }, { 234 | value: 'touchModule', 235 | name: 'angular-touch.js', 236 | checked: true 237 | } 238 | ] 239 | }]; 240 | 241 | this.prompt(prompts, function (props) { 242 | var hasMod = function (mod) { return props.modules.indexOf(mod) !== -1; }; 243 | this.animateModule = hasMod('animateModule'); 244 | this.cookiesModule = hasMod('cookiesModule'); 245 | this.resourceModule = hasMod('resourceModule'); 246 | this.routeModule = hasMod('routeModule'); 247 | this.sanitizeModule = hasMod('sanitizeModule'); 248 | this.touchModule = hasMod('touchModule'); 249 | 250 | var angMods = []; 251 | 252 | if (this.animateModule) { 253 | angMods.push("'ngAnimate'"); 254 | } 255 | 256 | if (this.cookiesModule) { 257 | angMods.push("'ngCookies'"); 258 | } 259 | 260 | if (this.resourceModule) { 261 | angMods.push("'ngResource'"); 262 | } 263 | 264 | if (this.routeModule) { 265 | angMods.push("'ngRoute'"); 266 | this.env.options.ngRoute = true; 267 | } 268 | 269 | if (this.sanitizeModule) { 270 | angMods.push("'ngSanitize'"); 271 | } 272 | 273 | if (this.touchModule) { 274 | angMods.push("'ngTouch'"); 275 | } 276 | 277 | if (angMods.length) { 278 | this.env.options.angularDeps = '\n ' + angMods.join(',\n ') + '\n '; 279 | } 280 | 281 | cb(); 282 | }.bind(this)); 283 | }; 284 | 285 | Generator.prototype.readIndex = function readIndex() { 286 | this.ngRoute = this.env.options.ngRoute; 287 | this.indexFile = this.engine(this.read('app/index.html'), this); 288 | }; 289 | 290 | Generator.prototype.bootstrapFiles = function bootstrapFiles() { 291 | var cssFile = 'styles/main.' + (this.compass ? 's' : '') + 'css'; 292 | this.copy( 293 | path.join('app', cssFile), 294 | path.join(this.appPath, cssFile) 295 | ); 296 | }; 297 | 298 | Generator.prototype.appJs = function appJs() { 299 | this.indexFile = this.appendFiles({ 300 | html: this.indexFile, 301 | fileType: 'js', 302 | optimizedPath: 'scripts/scripts.js', 303 | sourceFileList: ['scripts/app.js', 'scripts/controllers/main.js'], 304 | searchPath: ['.tmp', this.appPath] 305 | }); 306 | }; 307 | 308 | Generator.prototype.createIndexHtml = function createIndexHtml() { 309 | this.indexFile = this.indexFile.replace(/'/g, "'"); 310 | this.write(path.join(this.appPath, 'index.html'), this.indexFile); 311 | }; 312 | 313 | Generator.prototype.packageFiles = function packageFiles() { 314 | this.coffee = this.env.options.coffee; 315 | this.template('root/_bower.json', 'bower.json'); 316 | this.template('root/_bowerrc', '.bowerrc'); 317 | this.template('root/_package.json', 'package.json'); 318 | this.template('root/_Gruntfile.js', 'Gruntfile.js'); 319 | }; 320 | 321 | Generator.prototype._injectDependencies = function _injectDependencies() { 322 | if (this.options['skip-install']) { 323 | this.log( 324 | 'After running `npm install & bower install`, inject your front end dependencies' + 325 | '\ninto your source code by running:' + 326 | '\n' + 327 | '\n' + chalk.yellow.bold('grunt wiredep') 328 | ); 329 | } else { 330 | wiredep({ 331 | directory: 'bower_components', 332 | bowerJson: JSON.parse(fs.readFileSync('./bower.json')), 333 | ignorePath: new RegExp('^(' + this.appPath + '|..)/'), 334 | src: 'app/index.html', 335 | fileTypes: { 336 | html: { 337 | replace: { 338 | css: '' 339 | } 340 | } 341 | } 342 | }); 343 | } 344 | }; 345 | 346 | Generator.prototype.phpFiles = function () { 347 | this.sourceRoot(path.join(__dirname, 'templates')); 348 | this.template('api/composer.json', 'app/api/composer.json'); 349 | this.template('api/phpunit.xml', 'app/api/phpunit.xml'); 350 | this.copy('api/index.php', 'app/api/index.php'); 351 | this.copy('api/Makefile', 'app/api/Makefile'); 352 | this.copy('api/_gitignore', 'app/api/.gitignore'); 353 | this.copy('api/.htaccess', 'app/api/.htaccess'); 354 | this.directory('api/config', 'app/api/config'); 355 | this.directory('api/src', 'app/api/src'); 356 | this.directory('api/tests', 'app/api/tests'); 357 | }; 358 | 359 | Generator.prototype._installPhpDependencies = function _installPhpDependencies() { 360 | console.log( 361 | 'Now running `make install --directory app/api`' + 362 | ' to install the required Composer dependencies.' + 363 | ' If this fails, try running the command yourself.' 364 | ); 365 | this.spawnCommand('make', ['install', '--directory', 'app/api']); 366 | }; 367 | -------------------------------------------------------------------------------- /app/templates/api/.htaccess: -------------------------------------------------------------------------------- 1 | 2 | RewriteEngine On 3 | RewriteRule ^ index.php [L] 4 | 5 | -------------------------------------------------------------------------------- /app/templates/api/Makefile: -------------------------------------------------------------------------------- 1 | .PHONY: update clean 2 | 3 | all: 4 | 5 | 6 | # ============================================================================== 7 | # Dependencies 8 | # ============================================================================== 9 | 10 | install: vendor 11 | # ┌─────────────────────────────┐ 12 | # │ Dependencies are up-to-date │ 13 | # └─────────────────────────────┘ 14 | 15 | vendor: composer.phar composer.json Makefile 16 | [ -e composer.lock ] && php -d memory_limit=-1 composer.phar update || php -d memory_limit=-1 composer.phar install 17 | touch vendor 18 | 19 | composer.phar: 20 | curl -s http://getcomposer.org/installer | php 21 | # ┌──────────────────────────────────────┐ 22 | # │ Downloaded Composer in composer.phar │ 23 | # └──────────────────────────────────────┘ 24 | 25 | update: composer.phar composer.json Makefile 26 | [ -e composer.lock ] && php -d memory_limit=-1 composer.phar update || php -d memory_limit=-1 composer.phar install 27 | # ┌────────────────────────────────────────────┐ 28 | # │ Updated Composer dependencies successfully │ 29 | # └────────────────────────────────────────────┘ 30 | 31 | 32 | # ============================================================================== 33 | # Testing 34 | # ============================================================================== 35 | 36 | test: install 37 | make lint && \ 38 | vendor/bin/phpunit --coverage-html build/logs/coverage --coverage-text=build/logs/coverage.txt && \ 39 | echo && \ 40 | echo ======== Code coverage ======== && \ 41 | cat build/logs/coverage.txt | grep -A3 Summary | tail -n 3 && \ 42 | echo =============================== 43 | 44 | lint: install 45 | vendor/bin/phpcs -p --standard=PSR1 config src tests index.php | tee /tmp/phpcs.log \ 46 | && vendor/bin/phpcs -p --standard=PSR2 config src tests index.php | tee -a /tmp/phpcs.log \ 47 | && echo " TOTAL $$(grep ERROR /tmp/phpcs.log | wc -l) ERRORS" \ 48 | && echo " $$(grep WARNING /tmp/phpcs.log | wc -l) WARNINGS" \ 49 | && echo \ 50 | && rm /tmp/phpcs.log 51 | 52 | # ============================================================================== 53 | # Cleaning 54 | # ============================================================================== 55 | 56 | clean: 57 | [ ! -d vendor ] || rm -Rf vendor 58 | [ ! -e composer.lock ] || rm -f composer.lock 59 | [ ! -e composer.phar ] || rm -f composer.phar 60 | [ ! -d tests/_files ] || rm -Rf tests/_files 61 | [ ! -e tests/_files.tar.gz ] || rm -Rf tests/_files.tar.gz 62 | # ┌─────────┐ 63 | # │ Cleaned │ 64 | # └─────────┘ 65 | -------------------------------------------------------------------------------- /app/templates/api/_gitignore: -------------------------------------------------------------------------------- 1 | vendor 2 | composer.phar 3 | composer.lock 4 | -------------------------------------------------------------------------------- /app/templates/api/composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "<%= _.slugify(appname) %>", 3 | "type": "project", 4 | "autoload": { 5 | "psr-0": { 6 | "Api": "src/", 7 | "Test": "tests/" 8 | } 9 | }, 10 | "repositories": [ 11 | ], 12 | "require": { 13 | "php": ">=5.4", 14 | "slim/slim": "2.5.*" 15 | }, 16 | "require-dev": { 17 | "phpunit/phpunit": "4.1.*", 18 | "squizlabs/php_codesniffer": "2.1.*" 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /app/templates/api/config/.gitignore: -------------------------------------------------------------------------------- 1 | local.php 2 | *.local.php 3 | -------------------------------------------------------------------------------- /app/templates/api/config/README.md: -------------------------------------------------------------------------------- 1 | About this directory: 2 | ===================== 3 | 4 | By default, this application is configured to load all configs in 5 | `./config/autoload/{,*.}{global,local}.php`. Doing this provides a 6 | location for a developer to drop in configuration override files provided by 7 | modules, as well as cleanly provide individual, application-wide config files 8 | for things like database connections, etc. 9 | 10 | - ./config/autoload/{,*}.global.php files are included to the Git repository. 11 | - ./config/autoload/{,*}.local.php files are excluded from the Git repository 12 | as they contain all sensitive information (password, etc). It is recommended 13 | to include to your Git repository an example of the same file, with the 14 | .dist extension. 15 | 16 | Example 17 | ------- 18 | 19 | - application.global.php contains all non-sensitive, application-wide settings 20 | - database.global.php contains all non-sensitive database settings 21 | - database.local.php contains all sensitive database settings (excluded from Git) 22 | - database.local.php.dist a skeleton of database.local.php with all sensitive information 23 | replaced by * characters. 24 | -------------------------------------------------------------------------------- /app/templates/api/config/application.config.php: -------------------------------------------------------------------------------- 1 | array( 4 | 'html5-boilerplate' => array( 5 | 'name' => 'HTML5 Boilerplate', 6 | 'description' => 'HTML5 Boilerplate is a professional front-end template' 7 | . ' for building fast, robust, and adaptable web apps or sites.', 8 | ), 9 | 'angular' => array( 10 | 'name' => 'Angular', 11 | 'description' => 'AngularJS is a toolset for building the framework most' 12 | . ' suited to your application development.', 13 | ), 14 | 'karma' => array( 15 | 'name' => 'Karma', 16 | 'description' => 'Spectacular Test Runner for JavaScript.', 17 | ), 18 | ), 19 | ); 20 | -------------------------------------------------------------------------------- /app/templates/api/index.php: -------------------------------------------------------------------------------- 1 | run(); 25 | 26 | } catch (\Exception $e) { 27 | if (isset($app)) { 28 | $app->handleException($e); 29 | } else { 30 | http_response_code(500); 31 | header('Content-Type: application/json'); 32 | echo json_encode(array( 33 | 'status' => 500, 34 | 'statusText' => 'Internal Server Error', 35 | 'description' => $e->getMessage(), 36 | )); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /app/templates/api/phpunit.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | ./tests 6 | 7 | 8 | 9 | 10 | config 11 | src 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /app/templates/api/src/Api/Application.php: -------------------------------------------------------------------------------- 1 | configDirectory) || !is_dir($this->configDirectory)) { 19 | throw new Exception('Config directory is missing: ' . $this->configDirectory, 500); 20 | } 21 | foreach (preg_grep('/\\.php$/', scandir($this->configDirectory)) as $filename) { 22 | $config = array_replace_recursive($config, include $this->configDirectory . '/' . $filename); 23 | } 24 | return $config; 25 | } 26 | 27 | public function __construct(array $userSettings = array(), $configDirectory = 'config') 28 | { 29 | // Slim initialization 30 | parent::__construct($userSettings); 31 | $this->config('debug', false); 32 | $this->notFound(function () { 33 | $this->handleNotFound(); 34 | }); 35 | $this->error(function ($e) { 36 | $this->handleException($e); 37 | }); 38 | 39 | // Config 40 | $this->configDirectory = __DIR__ . '/../../' . $configDirectory; 41 | $this->config = $this->initConfig(); 42 | 43 | // /features 44 | $this->get('/features', function () { 45 | $features = new Features($this->config['features']); 46 | $this->response->headers->set('Content-Type', 'application/json'); 47 | $this->response->setBody(json_encode($features->getFeatures())); 48 | }); 49 | 50 | $this->get('/features/:id', function ($id) { 51 | $features = new Features($this->config['features']); 52 | $feature = $features->getFeature($id); 53 | if ($feature === null) { 54 | return $this->notFound(); 55 | } 56 | $this->response->headers->set('Content-Type', 'application/json'); 57 | $this->response->setBody(json_encode($feature)); 58 | }); 59 | } 60 | 61 | public function handleNotFound() 62 | { 63 | throw new Exception( 64 | 'Resource ' . $this->request->getResourceUri() . ' using ' 65 | . $this->request->getMethod() . ' method does not exist.', 66 | 404 67 | ); 68 | } 69 | 70 | public function handleException(Exception $e) 71 | { 72 | $status = $e->getCode(); 73 | $statusText = \Slim\Http\Response::getMessageForCode($status); 74 | if ($statusText === null) { 75 | $status = 500; 76 | $statusText = 'Internal Server Error'; 77 | } 78 | 79 | $this->response->setStatus($status); 80 | $this->response->headers->set('Content-Type', 'application/json'); 81 | $this->response->setBody(json_encode(array( 82 | 'status' => $status, 83 | 'statusText' => preg_replace('/^[0-9]+ (.*)$/', '$1', $statusText), 84 | 'description' => $e->getMessage(), 85 | ))); 86 | } 87 | 88 | /** 89 | * @return \Slim\Http\Response 90 | */ 91 | public function invoke() 92 | { 93 | foreach ($this->middleware as $middleware) { 94 | $middleware->call(); 95 | } 96 | $this->response()->finalize(); 97 | return $this->response(); 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /app/templates/api/src/Api/Model/Features.php: -------------------------------------------------------------------------------- 1 | features = $features; 17 | } 18 | 19 | public function getFeatures() 20 | { 21 | $features = array(); 22 | foreach ($this->features as $id => $feature) { 23 | $features[] = array( 24 | 'id' => $id, 25 | 'name' => $feature['name'], 26 | 'href' => $this->getHref($id), 27 | ); 28 | } 29 | return $features; 30 | } 31 | 32 | public function getFeature($id) 33 | { 34 | if (!array_key_exists($id, $this->features)) { 35 | return null; 36 | } 37 | return array_merge( 38 | array('id' => $id), 39 | $this->features[$id], 40 | array('href' => $this->getHref($id)) 41 | ); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /app/templates/api/tests/Test/Functional/ApplicationTest.php: -------------------------------------------------------------------------------- 1 | get('/api/test/http-exception', function () { 28 | throw new Exception('HTTP exception', 406); 29 | }); 30 | 31 | Environment::mock(array( 32 | 'PATH_INFO' => '/api/test/http-exception', 33 | )); 34 | $response = $app->invoke(); 35 | $this->assertEquals(json_encode(array( 36 | 'status' => 406, 37 | 'statusText' => 'Not Acceptable', 38 | 'description' => 'HTTP exception', 39 | )), $response->getBody()); 40 | $this->assertEquals(406, $response->getStatus()); 41 | } 42 | 43 | public function testUndefinedExceptionGenerates500() 44 | { 45 | $app = new Application(); 46 | $app->get('/api/test/undefined-exception', function () { 47 | throw new Exception('Undefined exception'); 48 | }); 49 | 50 | Environment::mock(array( 51 | 'PATH_INFO' => '/api/test/undefined-exception', 52 | )); 53 | $response = $app->invoke(); 54 | $this->assertEquals(json_encode(array( 55 | 'status' => 500, 56 | 'statusText' => 'Internal Server Error', 57 | 'description' => 'Undefined exception', 58 | )), $response->getBody()); 59 | $this->assertEquals(500, $response->getStatus()); 60 | } 61 | 62 | public function testUnkownHttpStatusExceptionGenerates500() 63 | { 64 | $app = new Application(); 65 | $app->get('/api/test/undefined-exception', function () { 66 | throw new Exception('Exception with unknown HTTP status', 999); 67 | }); 68 | 69 | Environment::mock(array( 70 | 'PATH_INFO' => '/api/test/undefined-exception', 71 | )); 72 | $response = $app->invoke(); 73 | $this->assertEquals(json_encode(array( 74 | 'status' => 500, 75 | 'statusText' => 'Internal Server Error', 76 | 'description' => 'Exception with unknown HTTP status', 77 | )), $response->getBody()); 78 | $this->assertEquals(500, $response->getStatus()); 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /app/templates/api/tests/Test/Functional/FeaturesTest.php: -------------------------------------------------------------------------------- 1 | app = new Application(); 16 | } 17 | 18 | public function testIndex() 19 | { 20 | Environment::mock(array( 21 | 'PATH_INFO' => '/features', 22 | )); 23 | 24 | $expected = array(); 25 | foreach ($this->app->config['features'] as $id => $feature) { 26 | $expected[] = array( 27 | 'id' => $id, 28 | 'name' => $feature['name'], 29 | 'href' => './api/features/' . $id, 30 | ); 31 | } 32 | 33 | $response = $this->app->invoke(); 34 | $this->assertEquals(json_encode($expected), $response->getBody()); 35 | $this->assertEquals(200, $response->getStatus()); 36 | } 37 | 38 | public function testGet() 39 | { 40 | $this->assertNotEquals(0, count($this->app->config['features'])); 41 | foreach ($this->app->config['features'] as $id => $feature) { 42 | $app = new Application(); 43 | Environment::mock(array( 44 | 'PATH_INFO' => '/features/' . $id, 45 | )); 46 | $response = $app->invoke(); 47 | $this->assertEquals( 48 | json_encode(array_merge(array('id' => $id), $feature, array('href' => './api/features/' . $id))), 49 | $response->getBody() 50 | ); 51 | $this->assertEquals(200, $response->getStatus()); 52 | } 53 | } 54 | 55 | public function testUnknownFeatureGets404() 56 | { 57 | Environment::mock(array( 58 | 'PATH_INFO' => '/features/unknown', 59 | )); 60 | $response = $this->app->invoke(); 61 | $this->assertEquals(json_encode(array( 62 | "status" => 404, 63 | "statusText" => "Not Found", 64 | "description" => "Resource /features/unknown using GET method does not exist.", 65 | )), $response->getBody()); 66 | $this->assertEquals(404, $response->getStatus()); 67 | } 68 | } 69 | -------------------------------------------------------------------------------- /app/templates/api/tests/Test/Unit/FeaturesTest.php: -------------------------------------------------------------------------------- 1 | array('name' => 'feature 1', 'description' => 'description 1'), 13 | 'f2' => array('name' => 'feature 2', 'description' => 'description 2'), 14 | ); 15 | $features = new Features($allFeatures); 16 | $this->assertEquals(array( 17 | array('id' => 'f1', 'name' => 'feature 1', 'href' => './api/features/f1'), 18 | array('id' => 'f2', 'name' => 'feature 2', 'href' => './api/features/f2'), 19 | ), $features->getFeatures()); 20 | } 21 | 22 | public function testGetFeatureReturnsExpectedFeature() 23 | { 24 | $allFeatures = array( 25 | 'f1' => array('name' => 'feature 1', 'description' => 'description 1'), 26 | 'f2' => array('name' => 'feature 2', 'description' => 'description 2'), 27 | ); 28 | $features = new Features($allFeatures); 29 | $this->assertEquals( 30 | array( 31 | 'id' => 'f1', 32 | 'name' => 'feature 1', 33 | 'description' => 'description 1', 34 | 'href' => './api/features/f1', 35 | ), 36 | $features->getFeature('f1') 37 | ); 38 | $this->assertEquals( 39 | array( 40 | 'id' => 'f2', 41 | 'name' => 'feature 2', 42 | 'description' => 'description 2', 43 | 'href' => './api/features/f2', 44 | ), 45 | $features->getFeature('f2') 46 | ); 47 | } 48 | 49 | public function testGetUnknownFeatureReturnsNull() 50 | { 51 | $allFeatures = array( 52 | 'f1' => array('name' => 'feature 1', 'description' => 'description 1'), 53 | 'f2' => array('name' => 'feature 2', 'description' => 'description 2'), 54 | ); 55 | $features = new Features($allFeatures); 56 | $this->assertEquals(null, $features->getFeature('f3')); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /app/templates/api/tests/bootstrap.php: -------------------------------------------------------------------------------- 1 | (): 22 | 23 | 24 | 25 |