You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@whimsical.apache.org by ru...@apache.org on 2017/09/18 17:48:21 UTC
[whimsy] branch agenda_on_vue updated: convert tests from react to
vue
This is an automated email from the ASF dual-hosted git repository.
rubys pushed a commit to branch agenda_on_vue
in repository https://gitbox.apache.org/repos/asf/whimsy.git
The following commit(s) were added to refs/heads/agenda_on_vue by this push:
new f9b06c6 convert tests from react to vue
f9b06c6 is described below
commit f9b06c66859816770ff939f4eb383b42214a20c8
Author: Sam Ruby <ru...@intertwingly.net>
AuthorDate: Mon Sep 18 13:47:36 2017 -0400
convert tests from react to vue
two additional tests now passing
---
www/board/agenda/package.json | 4 +-
www/board/agenda/spec/client_spec.rb | 20 +++--
www/board/agenda/spec/filters_spec.rb | 43 +++++++----
www/board/agenda/spec/forms_spec.rb | 80 ++++++++++++--------
.../agenda/spec/{react_server.rb => vue_server.rb} | 85 +++++++++++++++++-----
www/board/agenda/views/buttons/add-comment.js.rb | 2 +-
6 files changed, 162 insertions(+), 72 deletions(-)
diff --git a/www/board/agenda/package.json b/www/board/agenda/package.json
index 6ea8762..f29dbac 100644
--- a/www/board/agenda/package.json
+++ b/www/board/agenda/package.json
@@ -7,7 +7,9 @@
},
"devDependencies": {
"jsdom": "^11.1.0",
+ "jsdom-global": "^3.0.2",
"jquery": "^3.2.1",
- "vue": "^2.4.4"
+ "vue": "^2.4.4",
+ "vue-server-renderer": "^2.4.4"
}
}
diff --git a/www/board/agenda/spec/client_spec.rb b/www/board/agenda/spec/client_spec.rb
index 35e4b14..2ef240a 100644
--- a/www/board/agenda/spec/client_spec.rb
+++ b/www/board/agenda/spec/client_spec.rb
@@ -5,9 +5,9 @@
#
require_relative 'spec_helper'
-require_relative 'react_server'
+require_relative 'vue_server'
-describe "client", type: :feature, server: :react do
+describe "client", type: :feature, server: :vue do
#
# Agenda model
#
@@ -15,15 +15,21 @@ describe "client", type: :feature, server: :react do
it "should link pages in agenda traversal order" do
@parsed = Agenda.parse 'board_agenda_2015_02_18.txt', :quick
- on_react_server do
+ on_vue_server do
+
agenda = Agenda.load(@parsed)
+ container = document.createElement('div')
- output = _div agenda do |item|
- _item.next item.next.href, class: item.href if item.next
- _item.prev item.prev.href, class: item.href if item.prev
+ class TestClient < Vue
+ def render
+ _div agenda do |item|
+ _item.next item.next.href, class: item.href if item.next
+ _item.prev item.prev.href, class: item.href if item.prev
+ end
+ end
end
- response.end ReactDOMServer.renderToStaticMarkup(output)
+ Vue.renderResponse(TestClient, response)
end
expect(page).not_to have_selector '.Call-to-order.prev'
diff --git a/www/board/agenda/spec/filters_spec.rb b/www/board/agenda/spec/filters_spec.rb
index 6d97a80..31bf6a1 100644
--- a/www/board/agenda/spec/filters_spec.rb
+++ b/www/board/agenda/spec/filters_spec.rb
@@ -1,7 +1,7 @@
require_relative 'spec_helper'
-require_relative 'react_server'
+require_relative 'vue_server'
-describe "filters", type: :feature, server: :react do
+describe "filters", type: :feature, server: :vue do
before :all do
@parsed = Agenda.parse 'board_agenda_2015_02_18.txt', :quick
end
@@ -13,11 +13,16 @@ describe "filters", type: :feature, server: :react do
it "should convert http addresses to links" do
@item = @parsed.find {|item| item['title'] == 'Clerezza'}
- on_react_server do
- container = document.createElement('div')
- ReactDOM.render _Report(item: Agenda.new(@item)), container do
- response.end container.innerHTML
+ on_vue_server do
+ agenda_item = Agenda.new(@item)
+
+ class TestReport < Vue
+ def render
+ _Report item: agenda_item
+ end
end
+
+ Vue.renderResponse TestReport, response
end
expect(page).to have_selector 'a[href="http://s.apache.org/EjO"]'
@@ -31,11 +36,16 @@ describe "filters", type: :feature, server: :react do
it "should convert start time to local time on call to order" do
@item = @parsed.find {|item| item['title'] == 'Call to order'}
- on_react_server do
- container = document.createElement('div')
- ReactDOM.render _Report(item: Agenda.new(@item)), container do
- response.end container.innerHTML
+ on_vue_server do
+ agenda_item = Agenda.new(@item)
+
+ class TestReport < Vue
+ def render
+ _Report item: agenda_item
+ end
end
+
+ Vue.renderResponse TestReport, response
end
expect(page).to have_selector 'span.hilite', text: /Local Time:/
@@ -52,11 +62,16 @@ describe "filters", type: :feature, server: :react do
rubys: {name: "Sam Ruby", member: true, attending: true}
})
- on_react_server do
- container = document.createElement('div')
- ReactDOM.render _Report(item: Agenda.new(@item)), container do
- response.end container.innerHTML
+ on_vue_server do
+ agenda_item = Agenda.new(@item)
+
+ class TestReport < Vue
+ def render
+ _Report item: agenda_item
+ end
end
+
+ Vue.renderResponse TestReport, response
end
expect(page).to have_selector \
diff --git a/www/board/agenda/spec/forms_spec.rb b/www/board/agenda/spec/forms_spec.rb
index 8783a7f..1d66132 100644
--- a/www/board/agenda/spec/forms_spec.rb
+++ b/www/board/agenda/spec/forms_spec.rb
@@ -3,20 +3,22 @@
#
require_relative 'spec_helper'
-require_relative 'react_server'
+require_relative 'vue_server'
-describe "forms", type: :feature, server: :react do
+describe "forms", type: :feature, server: :vue do
#
# Comment form
#
describe "comment form" do
it "has an add-comment form with a disabled Save button" do
- on_react_server do
- server = {pending: {}, initials: 'sr'}
- container = document.createElement('div')
- ReactDOM.render _AddComment(item: {}, server: server), container do
- response.end container.innerHTML
+ on_vue_server do
+ class TestCommentForm < Vue
+ def render
+ _AddComment(item: {}, server: {pending: {}, initials: 'sr'})
+ end
end
+
+ Vue.renderResponse(TestCommentForm, response)
end
expect(page).to have_selector '.modal#comment-form'
@@ -30,17 +32,23 @@ describe "forms", type: :feature, server: :react do
end
it "should enable Save button after input" do
- on_react_server do
+ on_vue_server do
server = {pending: {}, initials: 'sr'}
- container = document.createElement('div')
- ReactDOM.render _AddComment(item: {}, server: server), container do
- node = container.querySelector('#comment-text')
- node.textContent = 'Good job!'
- Simulate.change node, target: {value: 'Good job!'}
- response.end container.innerHTML
+
+ class TestCommentForm < Vue
+ def render
+ _AddComment(item: {}, server: {pending: {}, initials: 'sr'})
+ end
end
+
+ app = Vue.renderApp(TestCommentForm)
+ node = app.querySelector('#comment-text')
+ node.textContent = 'Good job!'
+ app.dispatchEvent(Event.new('input'))
+ response.end app.innerHTML
end
+ puts page.body
expect(page).to have_selector '.modal-footer .btn-warning', text: 'Delete'
expect(page).to have_selector \
'.modal-footer .btn-primary:not([disabled])', text: 'Save'
@@ -54,12 +62,16 @@ describe "forms", type: :feature, server: :react do
it "should indicate when a reflow is needed" do
parsed = Agenda.parse 'board_agenda_2015_02_18.txt', :quick
@item = parsed.find {|item| item['title'] == 'Executive Vice President'}
- on_react_server do
+ on_vue_server do
item = Agenda.new(@item)
- container = document.createElement('div')
- ReactDOM.render _Post(item: item, button: 'edit report'), container do
- response.end container.innerHTML
+
+ class TestPostForm < Vue
+ def render
+ _Post(item: item, button: 'edit report')
+ end
end
+
+ Vue.renderResponse(TestPostForm, response)
end
expect(find('#post-report-text').value).to match(/to answer\nquestions/)
@@ -70,15 +82,21 @@ describe "forms", type: :feature, server: :react do
it "should perform a reflow" do
parsed = Agenda.parse 'board_agenda_2015_02_18.txt', :quick
@item = parsed.find {|item| item['title'] == 'Executive Vice President'}
- on_react_server do
+ on_vue_server do
item = Agenda.new(@item)
- container = document.createElement('div')
- ReactDOM.render _Post(item: item, button: 'edit report'), container do
- Simulate.click container.querySelector('.btn-danger')
- post_report = container.querySelector('#post-report-text')
- post_report.textContent = this.state.report
- response.end container.innerHTML
+
+ class TestPost < Vue
+ def render
+ _Post(item: item, button: 'edit report')
+ end
end
+
+ app = Vue.renderApp(TestPost)
+ button = app.querySelector('.btn-danger')
+ app.dispatchEvent(new Event('click'), button)
+ post_report = app.querySelector('#post-report-text')
+ post_report.textContent = this.state.report
+ response.end app.innerHTML
end
expect(find('#post-report-text').value).to match(/to\nanswer questions/)
@@ -93,13 +111,17 @@ describe "forms", type: :feature, server: :react do
describe "commit form" do
it "should generate a default commit message" do
@parsed = Agenda.parse 'board_agenda_2015_02_18.txt', :quick
- on_react_server do
+ on_vue_server do
Agenda.load(@parsed)
server = {pending: {approved: ['7'], comments: {I: 'Nice report!'}}}
- container = document.createElement('div')
- ReactDOM.render _Commit(item: {}, server: server), container do
- response.end container.innerHTML
+
+ class TestCommit < Vue
+ def render
+ _Commit(item: {}, server: server)
+ end
end
+
+ Vue.renderResponse TestCommit, response
end
expect(page).to have_selector '#commit-text',
diff --git a/www/board/agenda/spec/react_server.rb b/www/board/agenda/spec/vue_server.rb
similarity index 56%
rename from www/board/agenda/spec/react_server.rb
rename to www/board/agenda/spec/vue_server.rb
index d628c4e..16acdf4 100644
--- a/www/board/agenda/spec/react_server.rb
+++ b/www/board/agenda/spec/vue_server.rb
@@ -1,6 +1,6 @@
#
# This class spawns a io.js process to run a HTTP server which accepts
-# POST requests containing React TestUtils scripts and responds with
+# POST requests containing Vue/jsdom scripts and responds with
# HTML results. It provides a Rack interface, enabling this server to
# be run with Capybara/RackTest.
#
@@ -10,9 +10,9 @@ require 'net/http'
require 'stringio'
require 'capybara/rspec'
-require 'ruby2js/filter/react'
+require 'ruby2js/filter/vue'
-class ReactServer
+class VueServer
@@pid = nil
@@port = nil
@@ -36,7 +36,7 @@ class ReactServer
response = new.call('rack.input' => StringIO.new("response.end('hi')"))
return if response.first == '200' and response.last == 'hi'
STDERR.puts response
- raise RuntimeError('Invalid ReactServer response received')
+ raise RuntimeError('Invalid VueServer response received')
rescue Errno::ECONNREFUSED
sleep i * 0.1
end
@@ -71,16 +71,61 @@ class ReactServer
# the server itself
@@server = proc do
- JSDOM = require("jsdom").JSDOM
- global.window = JSDOM.new('<html><body></body></html>').window
- global.document = global.window.document
- global.navigator = global.window.navigator
+ cleanup = require("jsdom-global/register")
- React = require('react')
- ReactDOM = require('react-dom')
- ReactDOMServer = require('react-dom/server');
- TestUtils = require('react-dom/test-utils')
- Simulate = TestUtils.Simulate
+ process.env.VUE_ENV = 'server'
+
+ Vue = require('vue')
+ Vue.config.productionTip = false
+
+ # render a response, using server side rendering
+ def Vue.renderResponse(component, response)
+ renderer = require('vue-server-renderer').createRenderer()
+ app = Vue.new(render: proc {|h| return h(component)})
+
+ renderer.renderToString(app) do |err, html|
+ if err
+ response.end(err.toString() + "\n" + err.stack)
+ else
+ response.end(html)
+ end
+ end
+ end
+
+ # render a element, using client side rendering
+ def Vue.renderElement(component)
+ outer = document.createElement('div')
+ inner = document.createElement('span')
+ outer.appendChild(inner);
+ Vue.new(el: inner, render: proc {|h| return h(component)})
+ return outer.firstChild
+ end
+
+ # render an app, using client side rendering. Convenience methods are
+ # provided to querySelector, extract outerHTML and to dispatch events.
+ def Vue.renderApp(component)
+ outer = document.createElement('div')
+ inner = document.createElement('span')
+ outer.appendChild(inner);
+ app = Vue.new(el: inner, render: proc {|h| return h(component)})
+ inner = outer.firstChild
+
+ def app.outerHTML
+ return inner.outerHTML
+ end
+
+ def app.querySelector(selector)
+ return outer.querySelector(selector)
+ end
+
+ def app.dispatchEvent(event, element=nil)
+ element ||= inner
+ element.dispatchEvent(event)
+ app._watcher.run()
+ end
+
+ return app
+ end
jQuery = require('jquery')
@@ -92,7 +137,7 @@ class ReactServer
end
request.on 'error' do |error|
- console.log "ReactServer error: #{error.message}"
+ console.log "VueServer error: #{error.message}"
end
request.on 'end' do
@@ -110,22 +155,22 @@ class ReactServer
end
end
-shared_context "react_server", server: :react do
+shared_context "vue_server", server: :vue do
#
# administrivia
#
before :all do
- ReactServer.start
+ VueServer.start
Dir.chdir File.expand_path('../../views', __FILE__) do
@_script = Ruby2JS.convert(File.read('app.js.rb'), file: 'app.js.rb')
end
end
before :each do
- @_app, Capybara.app = Capybara.app, ReactServer.new
+ @_app, Capybara.app = Capybara.app, VueServer.new
end
- def on_react_server(&block)
+ def on_vue_server(&block)
locals = {}
instance_variables.each do |ivar|
next if ivar.to_s.start_with? '@_'
@@ -133,7 +178,7 @@ shared_context "react_server", server: :react do
end
page.driver.post('/', @_script + ';' +
- Ruby2JS.convert(block, react: true, ivars: locals))
+ Ruby2JS.convert(block, vue: true, vue_h: '$h', ivars: locals).to_s)
end
after :each do
@@ -141,6 +186,6 @@ shared_context "react_server", server: :react do
end
at_exit do
- ReactServer.stop
+ VueServer.stop
end
end
diff --git a/www/board/agenda/views/buttons/add-comment.js.rb b/www/board/agenda/views/buttons/add-comment.js.rb
index 5632f01..7c2ad93 100644
--- a/www/board/agenda/views/buttons/add-comment.js.rb
+++ b/www/board/agenda/views/buttons/add-comment.js.rb
@@ -37,7 +37,7 @@ class AddComment < Vue
#input field: initials
_input.comment_initials! label: 'Initials',
placeholder: 'initials', disabled: @disabled,
- defaultValue: @@server.pending.initials || @@server.initials
+ value: @@server.pending.initials || @@server.initials
#input field: comment text
_textarea.comment_text! value: @comment, label: 'Comment',
--
To stop receiving notification emails like this one, please contact
['"commits@whimsical.apache.org" <co...@whimsical.apache.org>'].