AngularJS: STOMP client with SockJS
authorgustavo <gu.martinm@gmail.com>
Thu, 31 Mar 2016 00:45:35 +0000 (02:45 +0200)
committergustavo <gu.martinm@gmail.com>
Thu, 31 Mar 2016 00:47:22 +0000 (02:47 +0200)
22 files changed:
angularjs/stomp/README.md [new file with mode: 0644]
angularjs/stomp/bower.json [new file with mode: 0644]
angularjs/stomp/gulpfile.js [new file with mode: 0644]
angularjs/stomp/karma.conf.js [new file with mode: 0644]
angularjs/stomp/package.json [new file with mode: 0644]
angularjs/stomp/src/stomp/app/app.module.js [new file with mode: 0644]
angularjs/stomp/src/stomp/app/core/core.module.js [new file with mode: 0644]
angularjs/stomp/src/stomp/app/users/users-child.controller.js [new file with mode: 0644]
angularjs/stomp/src/stomp/app/users/users-child.controller.spec.js [new file with mode: 0644]
angularjs/stomp/src/stomp/app/users/users-second-child.controller.js [new file with mode: 0644]
angularjs/stomp/src/stomp/app/users/users-second-child.controller.spec.js [new file with mode: 0644]
angularjs/stomp/src/stomp/app/users/users.constants.js [new file with mode: 0644]
angularjs/stomp/src/stomp/app/users/users.controller.js [new file with mode: 0644]
angularjs/stomp/src/stomp/app/users/users.controller.spec.js [new file with mode: 0644]
angularjs/stomp/src/stomp/app/users/users.html [new file with mode: 0644]
angularjs/stomp/src/stomp/app/users/users.module.js [new file with mode: 0644]
angularjs/stomp/src/stomp/app/users/users.route.js [new file with mode: 0644]
angularjs/stomp/src/stomp/app/users/users.route.spec.js [new file with mode: 0644]
angularjs/stomp/src/stomp/index.html [new file with mode: 0644]
angularjs/stomp/src/stomp/stubs/cars/cars.service.js [new file with mode: 0644]
angularjs/stomp/src/stomp/stubs/stubs.config.js [new file with mode: 0644]
angularjs/stomp/src/stomp/stubs/stubs.module.js [new file with mode: 0644]

diff --git a/angularjs/stomp/README.md b/angularjs/stomp/README.md
new file mode 100644 (file)
index 0000000..351aa83
--- /dev/null
@@ -0,0 +1,3 @@
+* npm link gulp-my-tasks
+* npm install
+* protractor doesn't work with node v4.0.0. Fall back to v0.12.7 when using protractor
diff --git a/angularjs/stomp/bower.json b/angularjs/stomp/bower.json
new file mode 100644 (file)
index 0000000..b76cac9
--- /dev/null
@@ -0,0 +1,51 @@
+{
+  "name": "stomp",
+  "description": "STOMP client example",
+  "version": "0.0.1",
+  "keywords": [
+    "stomp"
+  ],
+  "appPath": "app",
+  "private": "true",
+  "ignore": [
+    "src/",
+    "test/",
+    "package.json",
+    "gulpfile.js",
+    "karma.conf.js",
+    "server.js"
+  ],
+  "dependencies": {
+    "bootstrap": "~3.3.6",
+    "font-awesome": "~4.5.0",
+    "oclazyload": "~1.0.9",
+    "angular-animate": "~1.5.3",
+    "angular-bootstrap": "~1.2.5",
+    "angular-translate": "~2.11.0",
+    "angular-ui-router": "~0.2.18",
+    "angular": "~1.5.3",
+    "sockjs": "0.3.4",
+    "stomp-websocket": "~2.3.0"
+
+  },
+  "devDependencies": {
+    "angular-mocks": "~1.5.3",
+    "marked": "~0.3.5"
+  },
+  "overrides": {
+    "bootstrap": {
+      "main": [
+        "dist/css/bootstrap.css",
+        "dist/js/bootstrap.js"
+      ]
+    },
+    "font-awesome": {
+      "main": [
+        "css/font-awesome.css"
+      ]
+    }
+  },
+  "resolutions": {
+    "angular": "~1.5.3"
+  }
+}
diff --git a/angularjs/stomp/gulpfile.js b/angularjs/stomp/gulpfile.js
new file mode 100644 (file)
index 0000000..43e4efa
--- /dev/null
@@ -0,0 +1,3 @@
+var gulp = require('gulp');
+var args = require('gulp-my-tasks')(gulp);
+
diff --git a/angularjs/stomp/karma.conf.js b/angularjs/stomp/karma.conf.js
new file mode 100644 (file)
index 0000000..15ca427
--- /dev/null
@@ -0,0 +1,118 @@
+// Karma configuration
+// http://karma-runner.github.io/0.12/config/configuration-file.html
+// Generated on 2015-08-16 using
+// generator-karma 1.0.0
+
+module.exports = function(config) {
+  'use strict';
+
+  config.set({
+    // enable / disable watching file and executing tests whenever any file changes
+    autoWatch: true,
+
+    // base path, that will be used to resolve files and exclude
+    basePath: '',
+
+    // testing framework to use (jasmine/mocha/qunit/...)
+    // as well as any additional frameworks (requirejs/chai/sinon/...)
+    frameworks: [
+      'jasmine'
+    ],
+
+    // list of files / patterns to load in the browser
+    files: [
+      //bower:js
+      'bower_components/jquery/dist/jquery.js',
+      'bower_components/bootstrap/dist/js/bootstrap.js',
+      'bower_components/angular/angular.js',
+      'bower_components/oclazyload/dist/ocLazyLoad.js',
+      'bower_components/angular-animate/angular-animate.js',
+      'bower_components/angular-bootstrap/ui-bootstrap-tpls.js',
+      'bower_components/angular-translate/angular-translate.js',
+      'bower_components/angular-ui-router/release/angular-ui-router.js',
+      'bower_components/angular-mocks/angular-mocks.js',
+      'bower_components/marked/lib/marked.js',
+      //endbower
+      'src/showcase/app/**/*.module.js',
+      'src/showcase/app/**/*.js',
+      '.tmp/templates.js'
+    ],
+
+    // list of files / patterns to exclude
+    exclude: [
+    ],
+
+    // web server port
+    port: 8080,
+
+    // Start these browsers, currently available:
+    // - Chrome
+    // - ChromeCanary
+    // - Firefox
+    // - Opera
+    // - Safari (only Mac)
+    // - PhantomJS
+    // - IE (only Windows)
+    browsers: [
+      'PhantomJS'
+    ],
+
+    // Which plugins to enable
+    plugins: [
+      'karma-phantomjs-launcher',
+      'karma-jasmine',
+      'karma-coverage',
+      'karma-junit-reporter'
+    ],
+
+    // command line argument override the configuration from the config file
+    reporters: ['progress', 'junit', 'coverage'],
+
+    junitReporter: {
+      // results will be saved as $outputDir/$browserName.xml
+      outputDir: 'report',
+      // if included, results will be saved as $outputDir/$browserName/$outputFile
+      outputFile: 'test-results.xml'
+      // suite will become the package name attribute in xml testsuite element
+      // suite: ''
+    },
+
+    preprocessors: {
+      'src/showcase/app/**/!(*.spec)+(.js)': ['coverage']
+    },
+
+    coverageReporter: {
+      // specify a common output directory
+      dir: 'report/coverage',
+      reporters: [
+        // reporters not supporting the `file` property
+        {type: 'html', subdir: 'report-html'},
+        {type: 'lcov', subdir: 'report-lcov'},
+        // reporters supporting the `file` property, use `subdir` to directly
+        // output them in the `dir` directory
+        {type: 'cobertura', subdir: '.', file: 'cobertura.txt'},
+        {type: 'lcovonly', subdir: '.', file: 'report-lcovonly.txt'},
+        {type: 'teamcity', subdir: '.', file: 'teamcity.txt'},
+        {type: 'text', subdir: '.', file: 'text.txt'},
+        {type: 'text-summary'}
+      ]
+    },
+
+    // Continuous Integration mode
+    // if true, it capture browsers, run tests and exit
+    singleRun: false,
+
+    colors: true,
+
+    // level of logging
+    // possible values: LOG_DISABLE || LOG_ERROR || LOG_WARN || LOG_INFO || LOG_DEBUG
+    logLevel: config.LOG_INFO
+
+    // Uncomment the following lines if you are using grunt's server to run the tests
+    // proxies: {
+    //   '/': 'http://localhost:9000/'
+    // },
+    // URL root prevent conflicts with the site root
+    // urlRoot: '_karma_'
+  });
+};
diff --git a/angularjs/stomp/package.json b/angularjs/stomp/package.json
new file mode 100644 (file)
index 0000000..74e4570
--- /dev/null
@@ -0,0 +1,20 @@
+{
+  "name": "stomp",
+  "version": "0.0.1",
+  "description": "STOMP client example",
+  "author": {
+    "name": "Gustavo Martin Morcuende",
+    "email": "noemail@noemail.invalid",
+    "url": "http://gumartinm.name"
+  },
+  "homepage": "http://gumartinm.name",
+  "license": "Apache-2.0",
+  "devDependencies": {
+    "gulp": "~3.9.1",
+    "gulp-my-tasks": "~0.0.1"
+  },
+  "scripts": {
+    "test": "gulp test",
+    "postinstall": "bower install --force-latest"
+  }
+}
diff --git a/angularjs/stomp/src/stomp/app/app.module.js b/angularjs/stomp/src/stomp/app/app.module.js
new file mode 100644 (file)
index 0000000..cb17c0b
--- /dev/null
@@ -0,0 +1,27 @@
+(function () {
+
+  'use strict';
+
+  /**
+   * @ngdoc overview
+   * @name app
+   *
+   * @requires app.core
+   * @requires app.welcome
+   * @requires app.cars
+   *
+   * @description
+   * # app
+   *
+   * ## Main module for the current application
+   * There are several sub-modules included with the app module.
+   */
+  angular.module('app', [
+    /* Shared modules */
+    'app.core',
+
+    /* Feature areas */
+    'app.users'
+  ]);
+
+}());
diff --git a/angularjs/stomp/src/stomp/app/core/core.module.js b/angularjs/stomp/src/stomp/app/core/core.module.js
new file mode 100644 (file)
index 0000000..5a15d2b
--- /dev/null
@@ -0,0 +1,25 @@
+(function() {
+  'use strict';
+
+  /**
+   * @ngdoc overview
+   * @name app.core
+   *
+   * @requires ui.router
+   * @requires ui.bootstrap
+   * @requires ui.bootstrap.modal
+   *
+   * @description
+   * # app.core
+   *
+   * ## core module for the current application
+   * Shared modules across the whole application will be located in the app.core module.
+   */
+  angular.module('app.core', [
+    /* 3rd-party modules */
+    'ui.router',
+    'ui.bootstrap',
+    'ui.bootstrap.modal'
+  ]);
+
+})();
diff --git a/angularjs/stomp/src/stomp/app/users/users-child.controller.js b/angularjs/stomp/src/stomp/app/users/users-child.controller.js
new file mode 100644 (file)
index 0000000..bb1836c
--- /dev/null
@@ -0,0 +1,78 @@
+(function () {
+  'use strict';
+
+  angular
+    .module('app.users')
+    .controller('UsersChildController', UsersChildController);
+
+  /**
+   * @ngdoc controller
+   * @name app.users.controller:UsersChildController
+   *
+   * @requires $rootScope
+   * @requires $scope
+   *
+   * <p>
+   * <br>
+   * {@link https://docs.angularjs.org/api/ng/service/$rootScope $rootScope}
+   * {@link https://docs.angularjs.org/api/ng/type/$rootScope.Scope $scope}
+   * </p>
+   *
+   * @description
+   * UsersChildController controller.
+   */
+  /* @ngInject */
+  function UsersChildController($rootScope, $scope, USERS) {
+    var vm = this;
+
+    var emitFact = {
+      title: 'Snake and Scarlett',
+      fact: 'it is canon'
+    };
+    var scopeBroadcastToSecondChild = {
+      name: 'UsersChild To UsersSecondChild',
+      lastName: 'scope broadcasting to UsersSecondChild from UserChild',
+      city: 'UserChild'
+    };
+    var rootScopeBroadcastToSecondChild = {
+      name: 'UsersChild To UsersSecondChild',
+      lastName: 'rootscope broadcasting to UsersSecondChild from UserChild',
+      city: 'UserChild'
+    };
+
+    // This is the right way for accessing to a parent controller from a child one when using the "Controller as" way.
+    // Problem: we need to name our controllers with something different to the "vm standard", otherwise
+    // here we wouldn't be able to access to the parent controller because it would have the same name as our child
+    // controller (vm). So, we need different names for parent and child controllers.
+    vm.valueForChildControllers = $scope.usersController.toBeCalledFromChildControllers();
+
+    vm.getEmit = function () {
+      $scope.$emit(USERS.SCOPE.EMIT_FACT, emitFact);
+    };
+    vm.broadcastToSencondChild = function () {
+      // $scope.$broadcast will never be seen by controllers in the same level as this controller. :(
+      $scope.$broadcast(USERS.SCOPE.BROADCAST_TO_SENCONDCHILD, scopeBroadcastToSecondChild);
+      // The only way is either using $rootScope or creating a new controllers hierarchy where
+      // UsersSecondChildController would be in a lower level than UsersChildController.
+      $rootScope.$broadcast(USERS.ROOTSCOPE.BROADCAST_TO_SENCONDCHILD, rootScopeBroadcastToSecondChild);
+    };
+    vm.usersChildOnScopeBroadcast = function (events, broadcastUser) {
+      vm.broadcastUser = broadcastUser;
+      console.log('usersChildOnScopeBroadcast, events.name: ' + events.name);
+    };
+
+    // NEVER USE $rootScope.$on IN CONTROLLER BECAUSE IT IS NOT DESTROYED EVEN IF CONTROLLER WAS DESTROYED!!!
+    // YOU WILL END UP HAVING AS MANY EVENT LISTENERS AS TIMES THIS CONTROLLER IS CREATED!!!!
+    // $rootScope.$on(USERS.ROOTSCOPE.BROADCAST, usersChildOnRootBroadcast);
+
+    // LISTENING FOR EVENTS IN $scope IS THE RIGHT THING BECAUSE THESE EVENT LISTENERS ARE DESTROYED
+    // AT THE SAME TIME AS THIS CONTROLLER :)
+    $scope.$on(USERS.ROOTSCOPE.BROADCAST, vm.usersChildOnScopeBroadcast);
+
+    // function usersChildOnRootBroadcast(events, broadcastUser) {
+    //   vm.broadcastUser = broadcastUser;
+    //   console.log('usersChildOnRootBroadcast, events.name: ' + events.name);
+    // }
+
+  }
+})();
diff --git a/angularjs/stomp/src/stomp/app/users/users-child.controller.spec.js b/angularjs/stomp/src/stomp/app/users/users-child.controller.spec.js
new file mode 100644 (file)
index 0000000..2b5faeb
--- /dev/null
@@ -0,0 +1,97 @@
+describe('app.users', function() {
+  'use strict';
+
+  var valueForChildControllers = {
+    variable: 'This is a variable from UsersController',
+    value: 'Hello child controller'
+  };
+  var usersController = {
+    toBeCalledFromChildControllers: function() {
+      return valueForChildControllers;
+    }
+  };
+  var $rootScope;
+  var $scope;
+  var USERS;
+  var UsersChildController;
+
+  beforeEach(function() {
+    module('app.users');
+
+    inject(function($controller, _$rootScope_, _USERS_) {
+      $rootScope = _$rootScope_;
+      USERS = _USERS_;
+      $scope = $rootScope.$new();
+
+      $scope.usersController = usersController;
+      spyOn($scope, '$emit');
+      spyOn($rootScope, '$broadcast');
+      jasmine.createSpy($scope, '$scope.$broadcast');
+      spyOn($scope.usersController, 'toBeCalledFromChildControllers')
+        .and.callThrough();
+      UsersChildController = $controller('UsersChildController', {
+        $rootScope: $rootScope,
+        $scope: $scope,
+        USERS: _USERS_
+      });
+    });
+  });
+
+  describe('UsersChildController', function () {
+
+    it('should be created successfully', function () {
+      expect(UsersChildController).toBeDefined();
+
+      expect($scope.usersController.toBeCalledFromChildControllers).toHaveBeenCalled();
+      expect(UsersChildController.valueForChildControllers).toEqual(valueForChildControllers);
+    });
+
+    it('should be called $scope.$emit', function () {
+      var emitFact = {
+        title: 'Snake and Scarlett',
+        fact: 'it is canon'
+      };
+
+      UsersChildController.getEmit();
+
+      expect($scope.$emit).toHaveBeenCalledWith(USERS.SCOPE.EMIT_FACT, emitFact);
+    });
+
+    it('should be assigned broadcastUser', function () {
+      var rootScopeBroadcastUser = {
+        name: 'Snake',
+        lastName: 'Eyes',
+        city: 'classified'
+      };
+      var event = {
+        name: USERS.ROOTSCOPE.BROADCAST
+      };
+
+      UsersChildController.usersChildOnScopeBroadcast(event, rootScopeBroadcastUser);
+
+      expect(UsersChildController.broadcastUser).toEqual(rootScopeBroadcastUser);
+    });
+
+    it('should be called $rootScope.$broadcast', function () {
+      var scopeBroadcastToSecondChild = {
+        name: 'UsersChild To UsersSecondChild',
+        lastName: 'scope broadcasting to UsersSecondChild from UserChild',
+        city: 'UserChild'
+      };
+      var rootScopeBroadcastToSecondChild = {
+        name: 'UsersChild To UsersSecondChild',
+        lastName: 'rootscope broadcasting to UsersSecondChild from UserChild',
+        city: 'UserChild'
+      };
+
+      UsersChildController.broadcastToSencondChild();
+
+      expect($rootScope.$broadcast).toHaveBeenCalledWith(
+        USERS.ROOTSCOPE.BROADCAST_TO_SENCONDCHILD, rootScopeBroadcastToSecondChild);
+      expect($scope.$broadcast).toHaveBeenCalledWith(
+        USERS.SCOPE.BROADCAST_TO_SENCONDCHILD, scopeBroadcastToSecondChild);
+    });
+
+  });
+
+});
diff --git a/angularjs/stomp/src/stomp/app/users/users-second-child.controller.js b/angularjs/stomp/src/stomp/app/users/users-second-child.controller.js
new file mode 100644 (file)
index 0000000..c4bb43d
--- /dev/null
@@ -0,0 +1,42 @@
+(function () {
+  'use strict';
+
+  angular
+    .module('app.users')
+    .controller('UsersSecondChildController', UsersSecondChildController);
+
+  /**
+   * @ngdoc controller
+   * @name app.users.controller:UsersSecondChildController
+   *
+   * @requires $scope
+   *
+   * <p>
+   * <br>
+   * {@link https://docs.angularjs.org/api/ng/type/$rootScope.Scope $scope}
+   * </p>
+   *
+   * @description
+   * UsersSecondChildController controller.
+   */
+  /* @ngInject */
+  function UsersSecondChildController($scope, USERS) {
+    var vm = this;
+
+    vm.usersSecondChildOnRootScopeBroadcast = function (events, rootScopeBroadcastUser) {
+      vm.rootScopeBroadcastUser = rootScopeBroadcastUser;
+      console.log('usersSecondChildOnRootScopeBroadcast, events.name: ' + events.name);
+    };
+    vm.usersSecondChildOnScopeBroadcast = function (events, scopeBroadcastUser) {
+      vm.scopeBroadcastUser = scopeBroadcastUser;
+      // You will never see this message because listening for $scope.$broadcast sent by
+      // controllers in the same level does not work.
+      console.log('usersSecondChildOnScopeBroadcast, events.name: ' + events.name);
+    };
+
+    $scope.$on(USERS.ROOTSCOPE.BROADCAST_TO_SENCONDCHILD, vm.usersSecondChildOnRootScopeBroadcast);
+
+    $scope.$on(USERS.SCOPE.BROADCAST_TO_SENCONDCHILD, vm.usersSecondChildOnScopeBroadcast);
+
+  }
+})();
diff --git a/angularjs/stomp/src/stomp/app/users/users-second-child.controller.spec.js b/angularjs/stomp/src/stomp/app/users/users-second-child.controller.spec.js
new file mode 100644 (file)
index 0000000..0b6f18d
--- /dev/null
@@ -0,0 +1,63 @@
+describe('app.users', function() {
+  'use strict';
+
+  var $rootScope;
+  var $scope;
+  var USERS;
+  var UsersSecondChildController;
+
+  beforeEach(function() {
+    module('app.users');
+
+    inject(function($controller, _$rootScope_, _USERS_) {
+      $rootScope = _$rootScope_;
+      USERS = _USERS_;
+      $scope = $rootScope.$new();
+
+      spyOn($scope, '$emit');
+      UsersSecondChildController = $controller('UsersSecondChildController', {
+        $rootScope: $rootScope,
+        $scope: $scope,
+        USERS: _USERS_
+      });
+    });
+  });
+
+  describe('UsersSecondChildController', function () {
+
+    it('should be created successfully', function () {
+      expect(UsersSecondChildController).toBeDefined();
+    });
+
+    it('should be assigned rootScopeBroadcastUser', function () {
+      var rootScopeBroadcastUser = {
+        name: 'UsersChild To UsersSecondChild',
+        lastName: 'rootscope broadcasting to UsersSecondChild from UserChild',
+        city: 'UserChild'
+      };
+      var event = {
+        name: USERS.ROOTSCOPE.BROADCAST_TO_SENCONDCHILD
+      };
+
+      UsersSecondChildController.usersSecondChildOnRootScopeBroadcast(event, rootScopeBroadcastUser);
+
+      expect(UsersSecondChildController.rootScopeBroadcastUser).toEqual(rootScopeBroadcastUser);
+    });
+
+    it('should be assigned broadcastUser', function () {
+      var scopeBroadcastUser = {
+        name: 'UsersChild To UsersSecondChild',
+        lastName: 'rootscope broadcasting to UsersSecondChild from UserChild',
+        city: 'UserChild'
+      };
+      var event = {
+        name: USERS.SCOPE.BROADCAST_TO_SENCONDCHILD
+      };
+
+      UsersSecondChildController.usersSecondChildOnScopeBroadcast(event, scopeBroadcastUser);
+
+      expect(UsersSecondChildController.scopeBroadcastUser).toEqual(scopeBroadcastUser);
+    });
+  });
+
+});
diff --git a/angularjs/stomp/src/stomp/app/users/users.constants.js b/angularjs/stomp/src/stomp/app/users/users.constants.js
new file mode 100644 (file)
index 0000000..4947956
--- /dev/null
@@ -0,0 +1,17 @@
+(function () {
+  'use strict';
+
+  angular
+    .module('app.users')
+    .constant('USERS', {
+      ROOTSCOPE: {
+        BROADCAST: 'USERS_ROOTSCOPE_BROADCAST',
+        BROADCAST_TO_SENCONDCHILD: 'USERS_ROOTSCOPE_BROADCAST_TO_SENCONDCHILD'
+      },
+      SCOPE: {
+        EMIT_FACT: 'USERS_SCOPE_EMIT_FACT',
+        BROADCAST_TO_SENCONDCHILD: 'USERS_SCOPE_BROADCAST_TO_SENCONDCHILD'
+      }
+    });
+
+})();
diff --git a/angularjs/stomp/src/stomp/app/users/users.controller.js b/angularjs/stomp/src/stomp/app/users/users.controller.js
new file mode 100644 (file)
index 0000000..7a8723b
--- /dev/null
@@ -0,0 +1,59 @@
+(function () {
+  'use strict';
+
+  angular
+    .module('app.users')
+    .controller('UsersController', UsersController);
+
+  /**
+   * @ngdoc controller
+   * @name app.users.controller:UsersController
+   *
+   * @requires $rootScope
+   * @requires $scope
+   *
+   * <p>
+   * <br>
+   * {@link https://docs.angularjs.org/api/ng/service/$rootScope $rootScope}
+   * {@link https://docs.angularjs.org/api/ng/type/$rootScope.Scope $scope}
+   * </p>
+   *
+   * @description
+   * UsersController controller.
+   */
+  /* @ngInject */
+  function UsersController($rootScope, $scope, USERS) {
+    var vm = this;
+    var rootScopeBroadcastUser = {
+      name: 'Snake',
+      lastName: 'Eyes',
+      city: 'classified'
+    };
+    var scopeBroadcastUser = {
+      name: 'Shana',
+      lastName: 'M. O\'Hara',
+      city: 'Atlanta'
+    };
+    var valueForChildControllers = {
+      variable: 'This is a variable from UsersController',
+      value: 'Hello child controller'
+    };
+
+    vm.getRootScopeBroadcast = function () {
+      $rootScope.$broadcast(USERS.ROOTSCOPE.BROADCAST, rootScopeBroadcastUser);
+    };
+    vm.getScopeBroadcast = function () {
+      $scope.$broadcast(USERS.ROOTSCOPE.BROADCAST, scopeBroadcastUser);
+    };
+    vm.usersOnEmitFact = function (events, emitFact) {
+      vm.emitFact = emitFact;
+      console.log('usersOnEmitFact, events.name: ' + events.name);
+    };
+    vm.toBeCalledFromChildControllers = function () {
+      return valueForChildControllers;
+    };
+
+    $scope.$on(USERS.SCOPE.EMIT_FACT, vm.usersOnEmitFact);
+  }
+
+})();
diff --git a/angularjs/stomp/src/stomp/app/users/users.controller.spec.js b/angularjs/stomp/src/stomp/app/users/users.controller.spec.js
new file mode 100644 (file)
index 0000000..6919a11
--- /dev/null
@@ -0,0 +1,72 @@
+describe('app.users', function() {
+  'use strict';
+
+  var $rootScope;
+  var $scope;
+  var USERS;
+  var UsersController;
+
+  beforeEach(function() {
+    module('app.users');
+
+    inject(function($controller, _$rootScope_, _USERS_) {
+      $rootScope = _$rootScope_;
+      USERS = _USERS_;
+      $scope = $rootScope.$new();
+
+      spyOn($rootScope, '$broadcast');
+      jasmine.createSpy($scope, '$scope.$broadcast');
+      UsersController = $controller('UsersController', {
+        $rootScope: $rootScope,
+        $scope: $scope,
+        USERS: _USERS_
+      });
+    });
+  });
+
+  describe('UsersController', function () {
+
+    it('should be created successfully', function () {
+      expect(UsersController).toBeDefined();
+    });
+
+    it('should be called $rootScope.$broadcast', function () {
+      var rootScopeBroadcastUser = {
+        name: 'Snake',
+        lastName: 'Eyes',
+        city: 'classified'
+      };
+
+      UsersController.getRootScopeBroadcast();
+
+      expect($rootScope.$broadcast).toHaveBeenCalledWith(USERS.ROOTSCOPE.BROADCAST, rootScopeBroadcastUser);
+    });
+
+    it('should be called $scope.$broadcast', function () {
+      var scopeBroadcastUser = {
+        name: 'Shana',
+        lastName: 'M. O\'Hara',
+        city: 'Atlanta'
+      };
+
+      UsersController.getScopeBroadcast();
+
+      expect($scope.$broadcast).toHaveBeenCalledWith(USERS.ROOTSCOPE.BROADCAST, scopeBroadcastUser);
+    });
+
+    it('should be assigned emitFact', function () {
+      var emitFact = {
+        title: 'Snake and Scarlett',
+        fact: 'it is canon'
+      };
+      var event = {
+        name: 'USERS_SCOPE_EMIT_FACT'
+      };
+
+      UsersController.usersOnEmitFact(event, emitFact);
+
+      expect(UsersController.emitFact).toEqual(emitFact);
+    });
+  });
+
+});
diff --git a/angularjs/stomp/src/stomp/app/users/users.html b/angularjs/stomp/src/stomp/app/users/users.html
new file mode 100644 (file)
index 0000000..fba9854
--- /dev/null
@@ -0,0 +1,48 @@
+<!DOCTYPE html>
+<div class="container" ng-controller="UsersController as usersController">
+  <div>title = {{usersController.emitFact.title}}</div>
+  <div>fact = {{usersController.emitFact.fact}}</div>
+  <button type="button" class="btn btn-primary" ng-click="usersController.getRootScopeBroadcast()">
+    $rootScope.$broadcast
+  </button>
+
+  <button type="button" class="btn btn-primary" ng-click="usersController.getScopeBroadcast()">
+    $scope.$broadcast
+  </button>
+
+  <div class="container" ng-controller="UsersChildController as usersChildController">
+    <div>name = {{usersChildController.broadcastUser.name}}</div>
+    <div>lastname = {{usersChildController.broadcastUser.lastName}}</div>
+    <div>city = {{usersChildController.broadcastUser.city}}</div>
+
+    <button type="button" class="btn btn-primary" ng-click="usersChildController.getEmit()">
+      $scope.$emit fact
+    </button>
+    <br>
+    <button type="button" class="btn btn-primary" ng-click="usersChildController.broadcastToSencondChild()">
+      $scope.$broadcast and $rootScope.$broadcast to second child
+    </button>
+    <br><br>
+    <label>controller as, retrieving value from parent controller:</label>
+    <br>
+    <div>valueForChildControllers.variable = {{usersChildController.valueForChildControllers.variable}}</div>
+    <div>valueForChildControllers.value = {{usersChildController.valueForChildControllers.value}}</div>
+  </div>
+  <div class="container" ng-controller="UsersSecondChildController as usersSecondChildController">
+    <br>
+    <label>secondchild $scope.$on listening for $rootScope.$broadcast from UsersChildController:</label>
+    <br>
+    <div>name = {{usersSecondChildController.rootScopeBroadcastUser.name}}</div>
+    <div>lastname = {{usersSecondChildController.rootScopeBroadcastUser.lastName}}</div>
+    <div>city = {{usersSecondChildController.rootScopeBroadcastUser.city}}</div>
+
+    <br>
+    <label>secondchild $scope.$on listening for $scope.$broadcast from UsersChildController, same level never works:</label>
+    <br>
+    <div>name = {{usersSecondChildController.scopeBroadcastUser.name}}</div>
+    <div>lastname = {{usersSecondChildController.scopeBroadcastUser.lastName}}</div>
+    <div>city = {{usersSecondChildController.scopeBroadcastUser.city}}</div>
+
+  </div>
+
+</div>
diff --git a/angularjs/stomp/src/stomp/app/users/users.module.js b/angularjs/stomp/src/stomp/app/users/users.module.js
new file mode 100644 (file)
index 0000000..0ea1180
--- /dev/null
@@ -0,0 +1,20 @@
+(function() {
+  'use strict';
+
+  /**
+   * @ngdoc overview
+   * @name app.users
+   *
+   * @requires app.core
+   *
+   * @description
+   * # app.users
+   *
+   * ## Module users.
+   * Module in charge of dealing with users.
+   */
+  angular.module('app.users', [
+    'app.core'
+  ]);
+
+})();
diff --git a/angularjs/stomp/src/stomp/app/users/users.route.js b/angularjs/stomp/src/stomp/app/users/users.route.js
new file mode 100644 (file)
index 0000000..62ca965
--- /dev/null
@@ -0,0 +1,37 @@
+(function() {
+  'use strict';
+
+  angular
+    .module('app.users')
+    .config(route);
+
+  /**
+   * @ngdoc service
+   * @name app.users.route
+   *
+   * @requires $stateProvider
+   * @requires $urlRouterProvider
+   *
+   * <p>
+   * <br>
+   * {@link http://angular-ui.github.io/ui-router/site/#/api/ui.router.state.$stateProvider $stateProvider} <br>
+   * {@link http://angular-ui.github.io/ui-router/site/#/api/ui.router.router.$urlRouterProvider $urlRouterProvider}
+   * </p>
+   *
+   *
+   * @description
+   * Router configuration for users application.
+   */
+  /* @ngInject */
+  function route($stateProvider, $urlRouterProvider) {
+    var state = 'users';
+    var config = {
+      abstract: false,
+      url: '/users',
+      templateUrl: 'app/users/users.html'
+    };
+
+    $urlRouterProvider.otherwise(state);
+    $stateProvider.state(state, config);
+  }
+}());
diff --git a/angularjs/stomp/src/stomp/app/users/users.route.spec.js b/angularjs/stomp/src/stomp/app/users/users.route.spec.js
new file mode 100644 (file)
index 0000000..0131620
--- /dev/null
@@ -0,0 +1,24 @@
+describe('app.users', function() {
+  'use strict';
+
+  describe('state', function() {
+    var view = {
+      users: 'app/users/users.html'
+    };
+    var $state;
+
+    beforeEach(function() {
+      module('app.users');
+
+      inject(function(_$state_) {
+        $state = _$state_;
+      });
+    });
+
+    it('should map /users route to users View template', function() {
+      expect($state.get('users').templateUrl).toEqual(view.users);
+    });
+
+  });
+
+});
diff --git a/angularjs/stomp/src/stomp/index.html b/angularjs/stomp/src/stomp/index.html
new file mode 100644 (file)
index 0000000..68ba700
--- /dev/null
@@ -0,0 +1,123 @@
+<!DOCTYPE html>
+<html lang="en">
+
+  <head>
+    <meta charset="utf-8" />
+    <title>STOMP client with SockJS</title>
+    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1" />
+
+
+    <!--
+    * Using wiredep for filling up index.html file with bower dependencies (no devDependencies) by means of tags:
+    bower:css/bower:js/
+
+    * Using gulp-inject for filling up index.html file with the required files for this application by means of tags:
+    inject:css/inject:js/inject:templates:js
+
+    * Using gulp-useref for combining css and js files by means of the found tags in index.html file:
+    build:css/build:js/build:remove
+    -->
+
+    <!-- Vendor styles -->
+    <!-- build:css(.) styles/lib.min.css -->
+    <!-- bower:css -->
+    <link rel="stylesheet" href="/bower_components/bootstrap/dist/css/bootstrap.css" />
+    <link rel="stylesheet" href="/bower_components/font-awesome/css/font-awesome.css" />
+    <!-- endbower -->
+    <!-- endbuild -->
+
+    <!-- Custom styles -->
+    <!-- build:css(.tmp) styles/app.min.css -->
+    <!-- inject:css -->
+    <!-- endinject -->
+    <!-- endbuild -->
+
+
+
+    <!-- Vendor JavaScript -->
+    <!-- build:js(.) js/lib.min.js -->
+    <!-- bower:js -->
+    <script src="/bower_components/jquery/dist/jquery.js"></script>
+    <script src="/bower_components/bootstrap/dist/js/bootstrap.js"></script>
+    <script src="/bower_components/angular/angular.js"></script>
+    <script src="/bower_components/oclazyload/dist/ocLazyLoad.js"></script>
+    <script src="/bower_components/angular-animate/angular-animate.js"></script>
+    <script src="/bower_components/angular-bootstrap/ui-bootstrap-tpls.js"></script>
+    <script src="/bower_components/angular-translate/angular-translate.js"></script>
+    <script src="/bower_components/angular-ui-router/release/angular-ui-router.js"></script>
+    <script src="/bower_components/sockjs/sockjs.js"></script>
+    <script src="/bower_components/stomp-websocket/lib/stomp.min.js"></script>
+    <!-- endbower -->
+    <!-- endbuild -->
+
+
+    <!-- Custom JavaScript -->
+    <!-- build:js(.) js/app.min.js -->
+    <!-- inject:js -->
+    <script src="/src/stomp/app/users/users.module.js"></script>
+    <script src="/src/stomp/app/users/users.route.js"></script>
+    <script src="/src/stomp/app/users/users.controller.js"></script>
+    <script src="/src/stomp/app/users/users.constants.js"></script>
+    <script src="/src/stomp/app/users/users-second-child.controller.js"></script>
+    <script src="/src/stomp/app/users/users-child.controller.js"></script>
+    <script src="/src/stomp/app/core/core.module.js"></script>
+    <script src="/src/stomp/app/app.module.js"></script>
+    <!-- endinject -->
+
+
+    <!-- AngularJS templates -->
+    <!-- inject:templates:js -->
+    <!-- endinject -->
+    <!-- endbuild -->
+  </head>
+
+
+  <body>
+
+    <!-- See: https://docs.angularjs.org/guide/bootstrap -->
+
+    <!-- Automatic initialization. Using strict dependency injection.
+
+         In my case title is not going to be changed from AngularJS, so ng-app is being used in body section
+         instead of html section (documentation recommends html section)
+
+         AngularJS will work with DOM elements under the div section where ng-app is declared.
+         This could be useful when using different frameworks in the same html application where one framework
+         works with some DOM elements and another framework works with other DOM elements.
+    -->
+    <!-- <div ng-app="app" ng-strict-di>
+        When using ng-strict-di we must manually identify dependencies.
+        For example, Welcome controller, if using strict mode, would require
+        Welcome.$inject = ['$location'];
+
+        Instead I am going to use @ngInject because it is cool.
+    -->
+    <div ng-app="app">
+      <div>
+        <ui-view>
+          <i>Hello World!!! You should never see this message if ui-router works as expected.</i>
+        </ui-view>
+      </div>
+    </div>
+
+    <!-- Manual initialization, instead of ng-app. It could be useful in case of loading more
+         than one AngularJS application (what is not usual) In my case I load just one, called 'app'.
+         I will always use strict dependency injection. Better instead, I use @ngInject!!!
+    <script>
+      (function() {
+        'use strict';
+
+        angular
+          .element(document)
+            .ready(function() {
+              angular.bootstrap(document.body, ['app'], {
+                strictDi: true
+              });
+            });
+      })();
+    </script>
+    -->
+
+  </body>
+
+</html>
diff --git a/angularjs/stomp/src/stomp/stubs/cars/cars.service.js b/angularjs/stomp/src/stomp/stubs/cars/cars.service.js
new file mode 100644 (file)
index 0000000..a7b563b
--- /dev/null
@@ -0,0 +1,27 @@
+(function () {
+  'use strict';
+
+  angular
+    .module('app.stubs')
+    .factory('carsStub', carsStub);
+
+  /* @ngInject */
+  function carsStub($httpBackend, API) {
+    return {
+      register: register
+    };
+
+    function register() {
+      $httpBackend.whenGET(API.CARS).respond(getAll);
+
+      function getAll() {
+        return [
+          {id:1, content: 'Car: 1'},
+          {id:2, content: 'Car: 2'},
+          {id:3, content: 'Car: 3'}
+        ];
+      }
+    }
+  }
+
+}());
diff --git a/angularjs/stomp/src/stomp/stubs/stubs.config.js b/angularjs/stomp/src/stomp/stubs/stubs.config.js
new file mode 100644 (file)
index 0000000..5b31132
--- /dev/null
@@ -0,0 +1,14 @@
+(function () {
+
+  'use strict';
+
+  angular
+    .module('app.stubs')
+    .run('register', register);
+
+  /* @ngInject */
+  function register(carsStub) {
+    carsStub.register();
+  }
+
+}());
diff --git a/angularjs/stomp/src/stomp/stubs/stubs.module.js b/angularjs/stomp/src/stomp/stubs/stubs.module.js
new file mode 100644 (file)
index 0000000..e058d3e
--- /dev/null
@@ -0,0 +1,23 @@
+(function () {
+
+  'use strict';
+
+  /**
+   * @ngdoc overview
+   * @name stubs
+   *
+   * @requires app
+   * @requires ngMockE2E
+   *
+   * @description
+   * # stubs
+   *
+   * ## Module stubs.
+   * Module in charge of creating stubs.
+   */
+  angular.module('app.stubs', [
+    'app.core',
+    'ngMockE2E'
+  ]);
+
+}());