jasmine-runner 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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: []