diff --git a/Gruntfile.coffee b/Gruntfile.coffee index 5f19456..0564bb9 100644 --- a/Gruntfile.coffee +++ b/Gruntfile.coffee @@ -6,64 +6,50 @@ module.exports = (grunt) -> grunt.initConfig # Metadata. pkg: grunt.file.readJSON 'package.json' - banner: '/*! <%= pkg.title || pkg.name %> - v<%= pkg.version %> - ' + - '<%= grunt.template.today("yyyy-mm-dd") %>\n' + - '<%= pkg.homepage ? "* " + pkg.homepage + "\\n" : "" %>' + - '* Copyright (c) <%= grunt.template.today("yyyy") %> <%= pkg.author.name %>;' + - ' Licensed <%= _.pluck(pkg.licenses, "type").join(", ") %> */\n' meta: src: 'src/' test: 'test/' target: 'dist/' + banner: '/*! <%= pkg.title || pkg.name %> - v<%= pkg.version %> - ' + + '<%= grunt.template.today("yyyy-mm-dd") %>\n' + + '<%= pkg.homepage ? "* " + pkg.homepage + "\\n" : "" %>' + + '* Copyright (c) <%= grunt.template.today("yyyy") %>' + + ' <%= pkg.author.name %>;' + + ' Licensed <%= _.pluck(pkg.licenses, "type").join(", ") %> */\n' clean: target: src: ['<%= meta.target %>*js'] - coffeelint: src: - files: src: ['<%= meta.src %>**/*.coffee'] - options: max_line_length: level: 'warn' + coffeelint: + src: + files: src: ['<%= meta.src %>**/*.coffee'] + options: max_line_length: level: 'warn' + test: + files: src: ['<%= meta.src %>**/*.coffee'] + options: max_line_length: level: 'warn' coffee: src: options: bare: true files: '<%= meta.target %>radians.js': [ '<%= meta.src %>**/*.coffee' ] - mochacli: - options: - require: ['should'] - compilers: ['coffee:coffee-script'] - reporter: 'spec' - test: ['test/*.coffee'] + karma: + unit: configFile: 'config/karma-unit.coffee' + e2e: configFile: 'config/karma-e2e.coffee' + unit_ci: + configFile: 'config/karma-unit.coffee' + singleRun: true + e2e_ci: + configFile: 'config/karma-e2e.coffee' + singleRun: true + browsers: ['PhantomJS'] - # Task configuration. - # concat: - # options: - # banner: '<%= banner %>' - # stripBanners: true - # dist: - # src: ['lib/<%= pkg.name %>.js'] - # dest: 'dist/<%= pkg.name %>.js' - # uglify: - # options: - # banner: '<%= banner %>' - # dist: - # src: '<%= concat.dist.dest %>' - # dest: 'dist/<%= pkg.name %>.min.js' - # watch: - # gruntfile: - # files: '<%= jshint.gruntfile.src %>' - # tasks: ['jshint:gruntfile'] - # lib_test: - # files: '<%= jshint.lib_test.src %>' - # tasks: ['jshint:lib_test', 'qunit'] - - # These plugins provide necessary tasks. grunt.loadNpmTasks 'grunt-contrib-clean' grunt.loadNpmTasks 'grunt-contrib-coffee' grunt.loadNpmTasks 'grunt-coffeelint' grunt.loadNpmTasks 'grunt-contrib-watch' - grunt.loadNpmTasks 'grunt-mocha-cli' + grunt.loadNpmTasks 'grunt-karma' grunt.loadNpmTasks 'grunt-contrib-jshint' - grunt.registerTask 'test', ['mochacli'] + grunt.registerTask 'test', ['karma'] grunt.registerTask 'lint', ['coffeelint'] grunt.registerTask 'build', ['clean', 'lint', 'coffee'] grunt.registerTask 'default', ['lint' , 'test', 'build', 'jshint'] diff --git a/bower.json b/bower.json index c0b0c20..a752868 100644 --- a/bower.json +++ b/bower.json @@ -6,5 +6,6 @@ , "devDependencies": { "angular-mocks": "~1.0.5" , "angular-scenario": "~1.0.5" + , "expect": "~0.2.0" } } diff --git a/config/karma-e2e.coffee b/config/karma-e2e.coffee new file mode 100644 index 0000000..61fb1e5 --- /dev/null +++ b/config/karma-e2e.coffee @@ -0,0 +1,40 @@ +basePath = '..' + +files = +[ ANGULAR_SCENARIO +, ANGULAR_SCENARIO_ADAPTER +, 'src/**/*.coffee' +, 'test/e2e/**/*.coffee' +, { pattern: 'examples/simple.html' + , watched: false + , included: false + , served: true } +, { pattern: 'components/angular/angular.js' + , watched: false + , included: false + , served: true } +, { pattern: 'dist/radians.js' + , watched: false + , included: false + , served: true } +] + +exclude = [] + +reporters = ['progress'] + +port = 9876 + +runnerPort = 9100 + +colors = true + +logLevel = LOG_INFO + +autoWatch = true + +browsers = ['Chrome'] + +captureTimeout = 60000 + +singleRun = false diff --git a/config/karma-unit.coffee b/config/karma-unit.coffee new file mode 100644 index 0000000..430f1a9 --- /dev/null +++ b/config/karma-unit.coffee @@ -0,0 +1,30 @@ +basePath = '..' + +files = +[ MOCHA +, MOCHA_ADAPTER +, 'components/expect/expect.js' +, 'components/angular/angular.js' +, 'src/**/*.coffee' +, 'test/unit/*.coffee' +] + +exclude = [] + +reporters = ['progress'] + +port = 9876 + +runnerPort = 9100 + +colors = true + +logLevel = LOG_INFO + +autoWatch = true + +browsers = ['Chrome'] + +captureTimeout = 60000 + +singleRun = false diff --git a/examples/.gitignore b/examples/.gitignore deleted file mode 100644 index 44be31f..0000000 --- a/examples/.gitignore +++ /dev/null @@ -1 +0,0 @@ -components diff --git a/examples/simple.html b/examples/simple.html index 5edc073..8a59298 100644 --- a/examples/simple.html +++ b/examples/simple.html @@ -2,26 +2,33 @@ Simple + +
-
+ +
-
+
-
{{ model }}
+
{{ model }}
+
+ The other controller +
diff --git a/package.json b/package.json index 35b8b9b..ec451a7 100644 --- a/package.json +++ b/package.json @@ -27,6 +27,8 @@ "grunt-contrib-watch": "~0.4.4", "grunt-contrib-jshint": "~0.6.0", "grunt-coffeelint": "0.0.6", - "coffee-script": "~1.6.3" + "coffee-script": "~1.6.3", + "karma": "~0.8.5", + "grunt-karma": "~0.4.4" } } diff --git a/src/radians/contenteditable.coffee b/src/radians/contenteditable.coffee index c09542f..23c4fe2 100644 --- a/src/radians/contenteditable.coffee +++ b/src/radians/contenteditable.coffee @@ -3,23 +3,14 @@ angular.module('radians.contenteditable', []) require: 'ngModel', link: (scope, elm, attrs, ctrl) -> # view -> model - elm.bind 'blur', -> - console.log elm - console.log "blur()" + view_to_model = -> scope.$apply -> ctrl.$setViewValue elm.html() - - elm.bind 'input', (e) -> - console.log 'input', e - t = elm.html() - console.log 'elm contents', t - scope.$apply -> - ctrl.$setViewValue t + + elm.bind 'blur', view_to_model + elm.bind 'input', view_to_model + elm.bind 'change', view_to_model # model -> view - ctrl.$render = (v) -> - console.log @ - console.log "model: #{@$modelValue}, view: #{@$viewValue}" - console.log "$render()", v - elm.html ctrl.$viewValue + ctrl.$render = -> elm.html ctrl.$viewValue ) diff --git a/test/e2e/scenarios.coffee b/test/e2e/scenarios.coffee new file mode 100644 index 0000000..93bb114 --- /dev/null +++ b/test/e2e/scenarios.coffee @@ -0,0 +1,78 @@ +angular.scenario.dsl 'contenteditable', -> + (name) -> + @name = name + enter: (value) -> + @addFutureAction "contenteditable '#{@name}' enter '#{value}'" + , ($window, $document, done) -> + elmt = $document.elements @name + elmt.text value + elmt.trigger 'input' + done() + html: (args...) -> + futureName = + if args.length == 0 + "contenteditable '#{@name}' html" + else + "contenteditable '#{@name}' set html to '#{args[0]}'" + @addFutureAction futureName + , ($window, $document, done) -> + elmt = $document.elements @name + elmt.html args + elmt.trigger 'change' + done(null, elmt.html(args)) + +angular.scenario.dsl 'scope', -> + (ctrl, arg = null) -> + futureName = + if !arg? + "scope in Controller '#{ctrl}'" + else if typeof arg == 'function' + "executing 'scope.$apply(#{arg})' in Controller '#{ctrl}'" + else + "scope variable '#{arg}' in Controller '#{ctrl}'" + @addFutureAction futureName + , ($window, $document, done) -> + elmt = $window.$ "[ng-controller='#{ctrl}']" + return done("No Controller #{ctrl}") unless elmt? + sc = elmt.scope() + return done(null, sc) unless arg? + if typeof arg == 'string' + parts = arg.split '.' + for p in parts + sc = sc[p] + done(null, sc) + else if typeof arg == 'function' + sc.$apply -> arg(sc) + done() + else + done "don't understand argument #{arg}" + +describe 'radians', -> + describe 'contenteditable', -> + describe 'simple application', -> + beforeEach -> + browser().navigateTo 'base/examples/simple.html' + + it 'should update the model from the view (simple text)', -> + contenteditable('#input').enter('abc') + expect(element('#input').html()).toBe 'abc' + expect(scope('Ctrl', 'model')).toBe 'abc' + expect(element('#output').html()).toBe 'abc' + + it 'should update the model from the view (text with spans)', -> + contenteditable('#input').html('abc red') + expect(scope('Ctrl', 'model')).toBe 'abc red' + expect(element('#input span').html()).toBe 'red' + expect(element('#output').html()).toBe 'abc <span style="color:red">red</span>' + + it 'should update the view from the model', -> + expect(scope('Ctrl', 'model')).toBe 'Initial stuff with bold and italic yay' + scope('Ctrl', ($scope) -> $scope.model = 'oops') + expect(scope('Ctrl', 'model')).toBe 'oops' + expect(element('#input').html()).toBe 'oops' + scope('Ctrl', ($scope) -> $scope.model = 'a red b') + expect(element('#input').html()).toBe 'a red b' + expect(element('#input span').html()).toBe 'red' + + ## Why doesn't it work on this one??!! + # expect(element('#output').html()).toBe 'oops' diff --git a/test/test.coffee b/test/test.coffee deleted file mode 100644 index e459f8c..0000000 --- a/test/test.coffee +++ /dev/null @@ -1,5 +0,0 @@ -describe 'radians', -> - describe 'contenteditable', -> - it 'is nice', -> - console.log 'ohai' - 1.should.equal 1 diff --git a/test/unit/test.coffee b/test/unit/test.coffee new file mode 100644 index 0000000..15c02e5 --- /dev/null +++ b/test/unit/test.coffee @@ -0,0 +1,3 @@ +describe 'radians', -> + describe 'contenteditable', -> + it 'passes', ->