jasmine-runner 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,18 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ .DS_Store
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in jasmine-runner.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 Renato Neves
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,29 @@
1
+ # Jasmine::Runner
2
+
3
+ TODO: Write a gem description
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'jasmine-runner'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install jasmine-runner
18
+
19
+ ## Usage
20
+
21
+ TODO: Write usage instructions here
22
+
23
+ ## Contributing
24
+
25
+ 1. Fork it
26
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
27
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
28
+ 4. Push to the branch (`git push origin my-new-feature`)
29
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,36 @@
1
+ var jsApiReporter;
2
+
3
+ jasmineRunner = function(reporters) {
4
+ var jasmineEnv = jasmine.getEnv();
5
+
6
+ jsApiReporter = new jasmine.JsApiReporter();
7
+ jasmineEnv.addReporter(jsApiReporter);
8
+
9
+ if (reporters) {
10
+ for(var i in reporters) {
11
+ jasmineEnv.addReporter(reporters[i])
12
+ }
13
+ } else {
14
+ var htmlReporter = new jasmine.HtmlReporter();
15
+ jasmineEnv.addReporter(htmlReporter);
16
+
17
+ jasmineEnv.specFilter = function(spec) {
18
+ return htmlReporter.specFilter(spec);
19
+ };
20
+ }
21
+
22
+ var currentWindowOnload = window.onload;
23
+
24
+ window.onload = function() {
25
+ if (currentWindowOnload) {
26
+ currentWindowOnload();
27
+ }
28
+ execJasmine();
29
+ };
30
+
31
+ function execJasmine() {
32
+ jasmineEnv.execute();
33
+ }
34
+
35
+ return jasmineEnv;
36
+ }
@@ -0,0 +1,136 @@
1
+ (function() {
2
+ if (! jasmine) {
3
+ throw new Exception("jasmine library does not exist in global namespace!");
4
+ }
5
+
6
+ /**
7
+ * Basic reporter that outputs spec results to for the Teamcity build system
8
+ *
9
+ * Usage:
10
+ *
11
+ * jasmine.getEnv().addReporter(new jasmine.TeamcityReporter());
12
+ * jasmine.getEnv().execute();
13
+ */
14
+ var TeamcityReporter = function() {
15
+ this.started = false;
16
+ this.finished = false;
17
+ };
18
+
19
+ TeamcityReporter.prototype = {
20
+ reportRunnerResults: function(runner) { },
21
+
22
+ reportRunnerStarting: function(runner) { },
23
+
24
+ reportSpecResults: function(spec) { },
25
+
26
+ reportSpecStarting: function(spec) { },
27
+
28
+ reportSuiteResults: function(suite) {
29
+ var results = suite.results();
30
+ var path = [];
31
+ while(suite) {
32
+ path.unshift(suite.description);
33
+ suite = suite.parentSuite;
34
+ }
35
+ var description = path.join(' ');
36
+
37
+ this.log("##teamcity[testSuiteStarted name='" + this.escapeTeamcityString(description) + "']");
38
+
39
+ var outerThis = this;
40
+ var eachSpecFn = function(spec){
41
+ if (spec.description) {
42
+ outerThis.log("##teamcity[testStarted name='" + outerThis.escapeTeamcityString(spec.description) + "' captureStandardOutput='true']");
43
+ var specResultFn = function(result){
44
+ if (!result.passed_) {
45
+ outerThis.log("##teamcity[testFailed name='" + outerThis.escapeTeamcityString(spec.description) + "' message='|[FAILED|]' details='" + outerThis.escapeTeamcityString(result.trace.stack) + "']");
46
+ }
47
+ };
48
+
49
+ for (var j = 0, jlen = spec.items_.length; j < jlen; j++) {
50
+ specResultFn(spec.items_[j]);
51
+ }
52
+ outerThis.log("##teamcity[testFinished name='" + outerThis.escapeTeamcityString(spec.description) + "']");
53
+ }
54
+ };
55
+ for (var i = 0, ilen = results.items_.length; i < ilen; i++) {
56
+ eachSpecFn(results.items_[i]);
57
+ }
58
+
59
+ this.log("##teamcity[testSuiteFinished name='" + outerThis.escapeTeamcityString(description) + "']");
60
+ },
61
+
62
+ log: function(str) {
63
+ var console = jasmine.getGlobal().console;
64
+ if (console && console.log) {
65
+ console.log(str);
66
+ }
67
+ },
68
+
69
+ hasGroupedConsole: function() {
70
+ var console = jasmine.getGlobal().console;
71
+ return console && console.info && console.warn && console.group && console.groupEnd && console.groupCollapsed;
72
+ },
73
+
74
+ escapeTeamcityString: function(message) {
75
+ if(!message) {
76
+ return "";
77
+ }
78
+
79
+ return message.replace(/\|/g, "||")
80
+ .replace(/\'/g, "|'")
81
+ .replace(/\n/g, "|n")
82
+ .replace(/\r/g, "|r")
83
+ .replace(/\u0085/g, "|x")
84
+ .replace(/\u2028/g, "|l")
85
+ .replace(/\u2029/g, "|p")
86
+ .replace(/\[/g, "|[")
87
+ .replace(/]/g, "|]");
88
+ }
89
+ };
90
+
91
+ function suiteResults(suite) {
92
+ console.group(suite.description);
93
+ var specs = suite.specs();
94
+ for (var i in specs) {
95
+ if (specs.hasOwnProperty(i)) {
96
+ specResults(specs[i]);
97
+ }
98
+ }
99
+ var suites = suite.suites();
100
+ for (var j in suites) {
101
+ if (suites.hasOwnProperty(j)) {
102
+ suiteResults(suites[j]);
103
+ }
104
+ }
105
+ console.groupEnd();
106
+ }
107
+
108
+ function specResults(spec) {
109
+ var results = spec.results();
110
+ if (results.passed() && console.groupCollapsed) {
111
+ console.groupCollapsed(spec.description);
112
+ } else {
113
+ console.group(spec.description);
114
+ }
115
+ var items = results.getItems();
116
+ for (var k in items) {
117
+ if (items.hasOwnProperty(k)) {
118
+ itemResults(items[k]);
119
+ }
120
+ }
121
+ console.groupEnd();
122
+ }
123
+
124
+ function itemResults(item) {
125
+ if (item.passed && !item.passed()) {
126
+ console.warn({actual:item.actual,expected: item.expected});
127
+ item.trace.message = item.matcherName;
128
+ console.error(item.trace);
129
+ } else {
130
+ console.info('Passed');
131
+ }
132
+ }
133
+
134
+ // export public
135
+ jasmine.TeamcityReporter = TeamcityReporter;
136
+ })();
@@ -0,0 +1,6 @@
1
+ module Jasmine
2
+ module Runner
3
+ class ApplicationController < ActionController::Base
4
+ end
5
+ end
6
+ end
@@ -0,0 +1,21 @@
1
+ module Jasmine
2
+ module Runner
3
+ class ReportersController < ApplicationController
4
+
5
+ before_filter :prepare_config
6
+
7
+ def index
8
+ end
9
+
10
+ def teamcity
11
+ end
12
+
13
+ private
14
+
15
+ def prepare_config
16
+ @config = Jasmine::Runner.config
17
+ end
18
+
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,7 @@
1
+ <% content_for :head do %>
2
+
3
+ <script>
4
+ jasmineRunner();
5
+ </script>
6
+
7
+ <% end %>
@@ -0,0 +1,11 @@
1
+ <% content_for :head do %>
2
+
3
+ <script type="text/javascript" src="/assets/reporters/jasmine.teamcity_reporter.js"></script>
4
+
5
+ <script>
6
+ var htmlReporter = new jasmine.HtmlReporter();
7
+ var teamcityReporter = new jasmine.TeamcityReporter();
8
+ jasmineRunner([htmlReporter, teamcityReporter]);
9
+ </script>
10
+
11
+ <% end %>
@@ -0,0 +1,30 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <meta charset="utf-8">
5
+ <title>Jasmine Specs Suite</title>
6
+
7
+ <% @config.css_files.each do |filename| %>
8
+ <link rel="stylesheet" href="/assets/<%= filename %>" type="text/css">
9
+ <% end %>
10
+
11
+ <% @config.js_files.each do |filename| %>
12
+ <script type="text/javascript" src="/assets/<%= filename %>"></script>
13
+ <% end %>
14
+
15
+ <% @config.src_files.each do |filename| %>
16
+ <script type="text/javascript" src="/<%= filename %>"></script>
17
+ <% end %>
18
+
19
+ <% @config.spec_files.each do |filename| %>
20
+ <script type="text/javascript" src="/assets/<%= filename %>"></script>
21
+ <% end %>
22
+
23
+ <script type="text/javascript" src="/assets/jasmine_runner.js"></script>
24
+
25
+ <%= yield :head %>
26
+ </head>
27
+
28
+ <body>
29
+ </body>
30
+ </html>
data/config/routes.rb ADDED
@@ -0,0 +1,8 @@
1
+ Jasmine::Runner::Engine.routes.draw do
2
+ resources :reporters, :only => [:index] do
3
+ collection do
4
+ get 'teamcity'
5
+ end
6
+ end
7
+ root :to => "reporters#index"
8
+ end
@@ -0,0 +1,19 @@
1
+ # -*- encoding: utf-8 -*-
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'jasmine/runner/version'
5
+
6
+ Gem::Specification.new do |gem|
7
+ gem.name = "jasmine-runner"
8
+ gem.version = Jasmine::Runner::VERSION
9
+ gem.authors = ["Renato Neves"]
10
+ gem.email = ["renato.neves@coffeebeantech.com"]
11
+ gem.description = %q{Run Jasmine specs using the Rails 3 Asset Pipeline and headlessly with PhantomJS}
12
+ gem.summary = %q{Run Jasmine specs with support to Rails 3 Asset Pipeline, PhantomJS and Teamcity CI}
13
+ gem.homepage = ""
14
+
15
+ gem.files = `git ls-files`.split($/)
16
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
17
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
18
+ gem.require_paths = ["lib"]
19
+ end
@@ -0,0 +1,17 @@
1
+ require "jasmine/runner/version"
2
+ require "jasmine/runner/engine"
3
+ require "jasmine/runner/server"
4
+ require "jasmine/runner/config"
5
+ require "jasmine/runner/phantom"
6
+
7
+ module Jasmine
8
+ module Runner
9
+ mattr_accessor :config
10
+ @@config = Config.new
11
+
12
+ # Enable to change configurations using some initializer
13
+ def self.setup
14
+ yield self.config
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,95 @@
1
+ require 'yaml'
2
+
3
+ module Jasmine
4
+ module Runner
5
+ class Config
6
+
7
+ attr_accessor :mount
8
+ attr_accessor :mount_at
9
+ attr_accessor :phantom_path
10
+ attr_accessor :port
11
+ attr_accessor :js_files
12
+ attr_accessor :css_files
13
+ attr_accessor :spec_files
14
+ attr_accessor :src_files
15
+ attr_accessor :spec_dir
16
+ attr_accessor :core_dir
17
+ attr_accessor :src_dir
18
+
19
+ def initialize
20
+ @mount = true
21
+ @mount_at = 'jasmine'
22
+ @phantom_path = 'phantomjs' # considered in PATH
23
+ end
24
+
25
+ # Server port.
26
+ def port
27
+ @port ||= jasmine_config.port
28
+ end
29
+
30
+ # Paths for the Jasmine core Javascript files to be included automatically in the reports.
31
+ # Paths should be relative to core_dir.
32
+ def js_files
33
+ @js_files ||= Jasmine::Core.js_files
34
+ end
35
+
36
+ # Paths for the Jasmine core CSS files to be included automatically in the reports.
37
+ # Paths should be relative to core_dir.
38
+ def css_files
39
+ @css_files ||= Jasmine::Core.css_files
40
+ end
41
+
42
+ # Paths for the spec files (tests) to be included automatically in the reports.
43
+ # Paths should be relative to src_dir.
44
+ def spec_files
45
+ @spec_files ||= get_js_files(spec_dir)
46
+ end
47
+
48
+ # Paths for the Javascript source code to be tested to be included automatically in the reports
49
+ # Paths should be relative to spec_dir.
50
+ def src_files
51
+ @src_files ||= jasmine_yaml_config['src_files']
52
+ end
53
+
54
+ # Dir path where the specs can be found.
55
+ # This path is added to the Rails assets paths in the initializer.
56
+ def spec_dir
57
+ # @spec_dir ||= File.join(src_dir, 'spec', 'javascripts')
58
+ @spec_dir ||= jasmine_config.spec_dir
59
+ end
60
+
61
+ # Dir path where the Jasmine core files can be found.
62
+ # This path is added to the Rails assets paths in the initializer.
63
+ def core_dir
64
+ @core_dir ||= Jasmine::Core.path
65
+ end
66
+
67
+ # Project path.
68
+ def src_dir
69
+ @src_dir ||= Rails.root
70
+ end
71
+
72
+ private
73
+
74
+ def get_js_files(dir)
75
+ Dir.glob("#{dir}/**/*.js").collect do |path|
76
+ path.gsub!(/#{dir}\//, '')
77
+ end
78
+ end
79
+
80
+ def load_configuration_from_yaml
81
+ filepath = File.join(spec_dir, 'support', 'jasmine.yml')
82
+ YAML.load_file(filepath) if File.exist?(filepath)
83
+ end
84
+
85
+ def jasmine_yaml_config
86
+ @jasmine_yaml_config ||= load_configuration_from_yaml
87
+ end
88
+
89
+ def jasmine_config
90
+ @jasmine_config ||= Jasmine.load_configuration_from_yaml && Jasmine.config
91
+ end
92
+
93
+ end
94
+ end
95
+ end
@@ -0,0 +1,23 @@
1
+ module Jasmine
2
+ module Runner
3
+ class Engine < Rails::Engine
4
+
5
+ isolate_namespace Jasmine::Runner
6
+
7
+ # Add Jasmine Core dir and specs dir to the assets paths,
8
+ # so the files can be relative to "/assets/" path
9
+ initializer :assets, :group => :all do |app|
10
+ app.config.assets.paths << Jasmine::Runner.config.core_dir
11
+ app.config.assets.paths << Jasmine::Runner.config.spec_dir
12
+ end
13
+
14
+ # Mount the engine into the application
15
+ config.after_initialize do |app|
16
+ app.routes.prepend do
17
+ mount Jasmine::Runner::Engine => Jasmine::Runner.config.mount_at
18
+ end if Jasmine::Runner.config.mount
19
+ end
20
+
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,25 @@
1
+ module Jasmine
2
+ module Runner
3
+ class Phantom
4
+
5
+ attr_reader :phantom_path
6
+
7
+ def initialize
8
+ @phantom_path = Jasmine::Runner.config.phantom_path
9
+ end
10
+
11
+ def command(server_url)
12
+ command = []
13
+ command << phantom_path
14
+ command << path
15
+ command << server_url
16
+ command.join(' ')
17
+ end
18
+
19
+ def path
20
+ File.join File.dirname(__FILE__), 'phantom', 'jasmine_runner.js'
21
+ end
22
+
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,34 @@
1
+ var system = require('system');
2
+
3
+ var page = require('webpage').create()
4
+ page.onConsoleMessage = function(msg) {
5
+ console.log(msg);
6
+ };
7
+
8
+ function hasFinished(page) {
9
+ return page.evaluate(function(){
10
+ return jsApiReporter.finished;
11
+ });
12
+ };
13
+
14
+ function waitForFinish(page, onFinish) {
15
+ if (hasFinished(page)) {
16
+ onFinish()
17
+ } else {
18
+ setTimeout(
19
+ function() {waitForFinish(page, onFinish)},
20
+ 1000
21
+ );
22
+ }
23
+ };
24
+
25
+ page.open(system.args[1], function(status) {
26
+ if (status == 'success') {
27
+ waitForFinish(page, function() {
28
+ phantom.exit();
29
+ });
30
+ } else {
31
+ console.log('Unable to connect to Jasmine server at ' + system.args[1]);
32
+ phantom.exit();
33
+ }
34
+ });
@@ -0,0 +1,24 @@
1
+ module Jasmine
2
+ module Runner
3
+ module Reporters
4
+ class Teamcity
5
+
6
+ delegate :start, :port, :to => :@server
7
+
8
+ def initialize
9
+ @server = Jasmine::Runner::Server.new
10
+ @phantom = Jasmine::Runner::Phantom.new
11
+ end
12
+
13
+ def url
14
+ "http://localhost:#{port}/jasmine/reporters/teamcity"
15
+ end
16
+
17
+ def command
18
+ @phantom.command(url)
19
+ end
20
+
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,24 @@
1
+ module Jasmine
2
+ module Runner
3
+ class Server
4
+ attr_reader :port
5
+
6
+ def initialize
7
+ @port = Jasmine::Runner.config.port
8
+ end
9
+
10
+ # Inits the own Rails application on the configured port
11
+ def start
12
+ server = Jasmine::Server.new(port, Rails.application.to_app)
13
+
14
+ t = Thread.new do
15
+ server.start
16
+ end
17
+ t.abort_on_exception = true
18
+
19
+ Jasmine::wait_for_listener(port, "jasmine server")
20
+ end
21
+
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,5 @@
1
+ module Jasmine
2
+ module Runner
3
+ VERSION = "0.0.1"
4
+ end
5
+ end
@@ -0,0 +1,12 @@
1
+ namespace :jasmine do
2
+ namespace :phantom do
3
+ desc "Run specs using PhantomJS for Teamcity CI"
4
+ task :teamcity => 'jasmine:require' do
5
+ require 'jasmine/runner/reporters/teamcity'
6
+
7
+ reporter = Jasmine::Runner::Reporters::Teamcity.new
8
+ reporter.start
9
+ sh(reporter.command)
10
+ end
11
+ end
12
+ end
metadata ADDED
@@ -0,0 +1,70 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: jasmine-runner
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Renato Neves
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-04-05 00:00:00.000000000 Z
13
+ dependencies: []
14
+ description: Run Jasmine specs using the Rails 3 Asset Pipeline and headlessly with
15
+ PhantomJS
16
+ email:
17
+ - renato.neves@coffeebeantech.com
18
+ executables: []
19
+ extensions: []
20
+ extra_rdoc_files: []
21
+ files:
22
+ - .gitignore
23
+ - Gemfile
24
+ - LICENSE.txt
25
+ - README.md
26
+ - Rakefile
27
+ - app/assets/javascripts/jasmine_runner.js
28
+ - app/assets/javascripts/reporters/jasmine.teamcity_reporter.js
29
+ - app/controllers/jasmine/runner/application_controller.rb
30
+ - app/controllers/jasmine/runner/reporters_controller.rb
31
+ - app/views/jasmine/runner/reporters/index.html.erb
32
+ - app/views/jasmine/runner/reporters/teamcity.html.erb
33
+ - app/views/layouts/jasmine/runner/application.html.erb
34
+ - config/routes.rb
35
+ - jasmine-runner.gemspec
36
+ - lib/jasmine-runner.rb
37
+ - lib/jasmine/runner/config.rb
38
+ - lib/jasmine/runner/engine.rb
39
+ - lib/jasmine/runner/phantom.rb
40
+ - lib/jasmine/runner/phantom/jasmine_runner.js
41
+ - lib/jasmine/runner/reporters/teamcity.rb
42
+ - lib/jasmine/runner/server.rb
43
+ - lib/jasmine/runner/version.rb
44
+ - lib/tasks/teamcity.rake
45
+ homepage: ''
46
+ licenses: []
47
+ post_install_message:
48
+ rdoc_options: []
49
+ require_paths:
50
+ - lib
51
+ required_ruby_version: !ruby/object:Gem::Requirement
52
+ none: false
53
+ requirements:
54
+ - - ! '>='
55
+ - !ruby/object:Gem::Version
56
+ version: '0'
57
+ required_rubygems_version: !ruby/object:Gem::Requirement
58
+ none: false
59
+ requirements:
60
+ - - ! '>='
61
+ - !ruby/object:Gem::Version
62
+ version: '0'
63
+ requirements: []
64
+ rubyforge_project:
65
+ rubygems_version: 1.8.16
66
+ signing_key:
67
+ specification_version: 3
68
+ summary: Run Jasmine specs with support to Rails 3 Asset Pipeline, PhantomJS and Teamcity
69
+ CI
70
+ test_files: []