Skip to content

Commit

Permalink
WIP - Run jasmine specs
Browse files Browse the repository at this point in the history
  • Loading branch information
ohrite committed Aug 19, 2022
1 parent f5158dd commit f411c81
Show file tree
Hide file tree
Showing 30 changed files with 451 additions and 11 deletions.
2 changes: 1 addition & 1 deletion app/channels/application_cable/channel.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
module ApplicationCable
class Channel < ActionCable::Channel::Base
class Channel
end
end
29 changes: 29 additions & 0 deletions app/channels/hotwire/jasmine/suites_channel.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
module Hotwire
module Jasmine
class SuitesChannel < ActionCable::Channel::Base
def jasmine_started(data)
Hotwire::Jasmine::SuiteFinder.find(data['suiteId']).jasmine_started(data)
end

def jasmine_suite_started(data)
Hotwire::Jasmine::SuiteFinder.find(data['suiteId']).jasmine_suite_started(data)
end

def jasmine_spec_started(data)
Hotwire::Jasmine::SuiteFinder.find(data['suiteId']).jasmine_spec_started(data)
end

def jasmine_spec_done(data)
Hotwire::Jasmine::SuiteFinder.find(data['suiteId']).jasmine_spec_done(data)
end

def jasmine_suite_done(data)
Hotwire::Jasmine::SuiteFinder.find(data['suiteId']).jasmine_suite_done(data)
end

def jasmine_done(data)
Hotwire::Jasmine::SuiteFinder.find(data['suiteId']).jasmine_done(data)
end
end
end
end
1 change: 1 addition & 0 deletions app/controllers/hotwire/jasmine/application_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
class Hotwire::Jasmine::ApplicationController < ActionController::Base; end
11 changes: 11 additions & 0 deletions app/controllers/hotwire/jasmine/suites_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
class Hotwire::Jasmine::SuitesController < Hotwire::Jasmine::ApplicationController
def index
@suites = Hotwire::Jasmine::SuiteFinder.resolve
end

def show
@suite = Hotwire::Jasmine::SuiteFinder.find(params[:id])
rescue KeyError
raise ActiveRecord::RecordNotFound, params[:id]
end
end
3 changes: 3 additions & 0 deletions app/javascript/hotwire/jasmine/application.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
// Configure your import map in config/importmap.rb. Read more: https://github.com/rails/importmap-rails
import "@hotwired/turbo-rails"
import "hotwire/jasmine/controllers"
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { Controller } from '@hotwired/stimulus'
import { createConsumer } from '@rails/actioncable'
const consumer = createConsumer()

export default class extends Controller {
connect() {
this.channel = consumer.subscriptions.create({channel: 'Hotwire::Jasmine::SuitesChannel'})
}

disconnect() {
this.channel.disconnect()
}

post({type, detail}) {
this.channel.perform(type.replaceAll(':', '_'), detail)
}
}
9 changes: 9 additions & 0 deletions app/javascript/hotwire/jasmine/controllers/application.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { Application } from '@hotwired/stimulus'

const application = Application.start()

// Configure Stimulus development experience
application.debug = false
window.Stimulus = application

export { application }
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { Controller } from '@hotwired/stimulus'

export default class extends Controller {
receive({data: {type, detail}}) {
const event = new CustomEvent(type, {detail, bubbles: true})
this.element.dispatchEvent(event)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { Controller } from '@hotwired/stimulus'

export default class extends Controller {
post(event) {
const {type, detail} = event
window.parent.postMessage({type, detail}, "*")
}
}
7 changes: 7 additions & 0 deletions app/javascript/hotwire/jasmine/controllers/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
// Import and register all your controllers from the importmap under controllers/*

import { application } from "hotwire/jasmine/controllers/application"

// Eager load all controllers defined in the import map under controllers/**/*_controller
import { eagerLoadControllersFrom } from "@hotwired/stimulus-loading"
eagerLoadControllersFrom("hotwire/jasmine/controllers", application)
74 changes: 74 additions & 0 deletions app/javascript/hotwire/jasmine/controllers/suite_controller.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
import { Controller } from '@hotwired/stimulus'
import jasmineRequire from 'jasmine-core/lib/jasmine-core/jasmine.js'

export default class extends Controller {
static values = {id: String}

initialize() {
this.jasmine = jasmineRequire.core(jasmineRequire);
}

async connect() {
const { jasmine, idValue } = this;
const global = jasmine.getGlobal();
global.jasmine = jasmine;
const env = jasmine.getEnv();
const jasmineInterface = jasmineRequire.interface(jasmine, env);

env.addReporter(this);

for (const property in jasmineInterface) {
global[property] = jasmineInterface[property];
}

try {
await import(idValue);
await env.execute();
} finally {
env.clearReporters();
for (const property in jasmineInterface) {
delete global[property];
}
}
}

jasmineStarted({order, ...detail}) {
const { idValue } = this;
this.stack = [];
const event = new CustomEvent('jasmine:started', {detail: {suiteId: idValue, ...detail}, bubbles: true});
this.element.dispatchEvent(event);
}

suiteStarted({order, ...detail}) {
const { idValue, stack } = this;
stack.push(detail)
const event = new CustomEvent('jasmine:suite:started', {detail: {suiteId: idValue, ...detail}, bubbles: true});
this.element.dispatchEvent(event);
}

specStarted({order, ...detail}) {
const { idValue, stack } = this;
const event = new CustomEvent('jasmine:spec:started', {detail: {suiteId: idValue, stack, ...detail}, bubbles: true});
this.element.dispatchEvent(event);
}

specDone({order, ...detail}) {
const { idValue, stack } = this;
const event = new CustomEvent('jasmine:spec:done', {detail: {suiteId: idValue, stack, ...detail}, bubbles: true});
this.element.dispatchEvent(event);
}

suiteDone({order, ...detail}) {
const { idValue, stack } = this;
stack.pop();
const event = new CustomEvent('jasmine:suite:done', {detail: {suiteId: idValue, ...detail}, bubbles: true});
this.element.dispatchEvent(event);
}

jasmineDone({order, ...detail}) {
const { idValue } = this;
this.stack = null;
const event = new CustomEvent('jasmine:done', {detail: {suiteId: idValue, ...detail}, bubbles: true});
this.element.dispatchEvent(event);
}
}
11 changes: 11 additions & 0 deletions app/views/hotwire/jasmine/suites/_suite.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<div class='jasmine_html-reporter'>
<div class='jasmine-banner'>
<a class='jasmine-title' href='http://jasmine.github.io/' target='_blank'></a>
<span class='jasmine-version'></span>
</div>
<ul class='jasmine-symbol-summary'></ul>
<div class='jasmine-alert'></div>
<div class='jasmine-results'>
<div class='jasmine-failures'></div>
</div>
</div>
8 changes: 8 additions & 0 deletions app/views/hotwire/jasmine/suites/index.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<%= turbo_stream_from 'hotwire_jasmine' %>
<%= turbo_frame_tag 'hotwire_jasmine' do %>
<%= render partial: 'suite', locals: {suites: @suites} %>
<% end %>

<% @suites.each do |suite| %>
<%= content_tag(:iframe, nil, id: suite.id.parameterize, style: 'display: none;', loading: :eager, src: hotwire_jasmine_suite_path(suite.id), data: {controller: 'actioncable-reporter iframe-client', action: 'message@window->iframe-client#receive jasmine:started->actioncable-reporter#post jasmine:suite:started->actioncable-reporter#post jasmine:spec:started->actioncable-reporter#post jasmine:spec:done->actioncable-reporter#post jasmine:suite:done->actioncable-reporter#post jasmine:done->actioncable-reporter#post'}) %>
<% end %>
1 change: 1 addition & 0 deletions app/views/hotwire/jasmine/suites/show.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<%= content_tag(:template, nil, data: {controller: 'suite iframe-host', suite_id_value: @suite.id, action: 'jasmine:started->iframe-host#post jasmine:suite:started->iframe-host#post jasmine:spec:started->iframe-host#post jasmine:spec:done->iframe-host#post jasmine:suite:done->iframe-host#post jasmine:done->iframe-host#post'}) %>
20 changes: 20 additions & 0 deletions app/views/layouts/hotwire/jasmine/application.html.erb
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<!DOCTYPE html>
<html lang="<%= I18n.locale %>">
<head>
<title>Jasmine</title>
<meta name="viewport" content="width=device-width,initial-scale=1">
<%= csrf_meta_tags %>
<%= csp_meta_tag %>
<%= javascript_inline_importmap_tag(JSON.pretty_generate(JSON.parse(Rails.application.importmap.to_json(resolver: self)).deep_merge('imports' => Hotwire::Jasmine::SuiteFinder.resolve.map(&:to_h).reduce(:+)))) %>
<%= javascript_importmap_module_preload_tags %>
<%= javascript_module_preload_tag(Hotwire::Jasmine::SuiteFinder.resolve.map(&:to_h).reduce(:+).values) %>
<%= javascript_importmap_shim_nonce_configuration_tag %>
<%= javascript_importmap_shim_tag %>
<%= javascript_import_module_tag('hotwire/jasmine/application') %>
<%= action_cable_meta_tag %>
<%= stylesheet_link_tag 'https://ga.jspm.io/npm:[email protected]/lib/jasmine-core/jasmine.css' %>
</head>
<body>
<%= yield %>
</body>
</html>
1 change: 1 addition & 0 deletions config/application.rb
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
module Retrospectives
class Application < Rails::Application
config.load_defaults 7.0
config.autoload_paths << config.root.join('lib')
config.generators do |g|
g.helper false
g.assets false
Expand Down
13 changes: 9 additions & 4 deletions config/importmap.rb
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
# Pin npm packages by running ./bin/importmap

pin '@hotwired/stimulus', to: 'https://ga.jspm.io/npm:@hotwired/[email protected]/dist/stimulus.js'
pin '@hotwired/stimulus', to: 'stimulus.min.js', preload: true
pin '@hotwired/stimulus-loading', to: 'stimulus-loading.js', preload: true
pin '@hotwired/turbo-rails', to: 'turbo.min.js', preload: true
pin 'application'
pin 'canvas-confetti', to: 'https://ga.jspm.io/npm:[email protected]/dist/confetti.module.mjs'
pin 'hotkeys-js', to: 'https://ga.jspm.io/npm:[email protected]/dist/hotkeys.esm.js'
pin 'stimulus-dropdown', to: 'https://ga.jspm.io/npm:[email protected]/dist/stimulus-dropdown.es.js'
pin 'stimulus-clipboard', to: 'https://ga.jspm.io/npm:[email protected]/dist/stimulus-clipboard.es.js'
Expand All @@ -13,7 +14,11 @@
pin 'stimulus-timeago', to: 'https://ga.jspm.io/npm:[email protected]/dist/stimulus-timeago.es.js'
pin 'stimulus-use', to: 'https://ga.jspm.io/npm:[email protected]/dist/index.js'
pin 'tailwindcss-stimulus-components', to: 'https://ga.jspm.io/npm:[email protected]/dist/tailwindcss-stimulus-components.modern.js'

pin 'application', preload: true
pin_all_from 'app/javascript/controllers', under: 'controllers'
pin 'canvas-confetti', to: 'https://ga.jspm.io/npm:[email protected]/dist/confetti.module.mjs'
pin_all_from 'spec/javascript', to: 'spec/javascript'

pin_all_from 'app/javascript/hotwire/jasmine/controllers', under: 'hotwire/jasmine/controllers'
pin 'hotwire/jasmine/application', preload: true
pin 'jasmine-core/lib/jasmine-core/jasmine.js', to: 'https://ga.jspm.io/npm:[email protected]/lib/jasmine-core/jasmine.js'
pin 'process', to: 'https://ga.jspm.io/npm:@jspm/[email protected]/nodelibs/browser/process-production.js'
pin '@rails/actioncable', to: 'https://ga.jspm.io/npm:@rails/[email protected]/app/assets/javascripts/actioncable.esm.js'
6 changes: 1 addition & 5 deletions config/initializers/assets.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,4 @@

# Add additional assets to the asset load path.
# Rails.application.config.assets.paths << Emoji.images_path

# Precompile additional assets.
# application.js, application.css, and all non-JS/CSS in the app/assets
# folder are already added.
# Rails.application.config.assets.precompile += %w( admin.js admin.css )
Rails.application.config.assets.paths << 'spec/javascript'
7 changes: 7 additions & 0 deletions config/initializers/hotwire_jasmine.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
require 'hotwire/jasmine'

Hotwire::Jasmine.configure do |config|
config.paths << Rails.root.join('spec/javascript')
end

Rails.application.config.hotwire_jasmine_store = ActiveSupport::Cache.lookup_store(:file_store, Rails.root.join('tmp/hotwire/stimulus'))
11 changes: 11 additions & 0 deletions config/routes.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,15 @@
Rails.application.routes.draw do
namespace :hotwire do
namespace :jasmine do
resources :suites, only: [:index, :show], id: /.+/ do
resources :specs, only: [:update]
end
end
end

mount Rack::File.new(Rails.root.join('spec/javascript')) => '/spec/javascript'
mount Rack::File.new(Rails.root.join('spec/fixtures/jasmine')) => '/spec/fixtures/jasmine'

devise_for :users, controllers: {omniauth_callbacks: 'users/omniauth_callbacks'}

resources :boards do
Expand Down
14 changes: 14 additions & 0 deletions lib/hotwire/jasmine.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
require 'hotwire/jasmine/configuration'
require 'hotwire/jasmine/suite'

module Hotwire
module Jasmine
def self.configuration
Hotwire::Jasmine::Configuration.instance
end

def self.configure(&block)
yield(configuration) if block
end
end
end
13 changes: 13 additions & 0 deletions lib/hotwire/jasmine/configuration.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
module Hotwire
module Jasmine
class Configuration
include Singleton

attr_accessor :paths

def initialize(paths: [])
@paths = Array(paths)
end
end
end
end
69 changes: 69 additions & 0 deletions lib/hotwire/jasmine/suite.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
require 'hotwire/jasmine/suite_finder'

module Hotwire
module Jasmine
class Suite
attr_reader :path

def initialize(path:)
@path = path
end

def id
path.dirname.join(basename).to_s
end

def to_h
{id => "/#{path}"}
end

def done?
data['done']
end

def data
Rails.application.config.hotwire_jasmine_store.fetch(id) { cache_defaults }
end

def jasmine_started(result)
Rails.application.config.hotwire_jasmine_store.delete(id)
suite = data
suite['totalSpecsDefined'] = result['totalSpecsDefined']
Rails.application.config.hotwire_jasmine_store.write(id, suite)
end

def jasmine_suite_started(_)
end

def jasmine_spec_started(_)
end

def jasmine_spec_done(result, *args)
suite = data
suite[result['status']] ||= []
suite[result['status']].push(result)
Rails.application.config.hotwire_jasmine_store.write(id, suite)
end

def jasmine_suite_done(_)
end

def jasmine_done(_)
suite = Rails.application.config.hotwire_jasmine_store.fetch(id) { {'done' => false} }
Rails.application.config.hotwire_jasmine_store.write(id, suite.merge('done' => true))
end

private

def cache_defaults
{'done' => false, 'totalSpecsDefined' => 0}
end

def basename
return path.basename('.js') if path.extname.eql?('.js')

path.basename
end
end
end
end
Loading

0 comments on commit f411c81

Please sign in to comment.