whimsical-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Sam Ruby <ru...@apache.org>
Subject [whimsy.git] [36/50] Commit 178ce95: rough in react server test
Date Fri, 22 Jan 2016 02:40:57 GMT
Commit 178ce950a54aca8be7e5643513cc6c6cc0129085:
    rough in react server test


Branch: refs/heads/master
Author: Sam Ruby <rubys@intertwingly.net>
Committer: Sam Ruby <rubys@intertwingly.net>
Pusher: rubys <rubys@apache.org>

------------------------------------------------------------
spec/form_spec.rb                                            | ++++++++++ 
spec/react_server.rb                                         | ++++++++++++ 
views/add-comment.js.rb                                      | + -
------------------------------------------------------------
136 changes: 135 additions, 1 deletions.
------------------------------------------------------------


diff --git a/spec/form_spec.rb b/spec/form_spec.rb
new file mode 100644
index 0000000..38c0f26
--- /dev/null
+++ b/spec/form_spec.rb
@@ -0,0 +1,38 @@
+require 'capybara/rspec'
+require_relative './react_server'
+require 'ruby2js/filter/react'
+
+describe "forms", type: :feature do
+  before :all do
+    @app, Capybara.app = Capybara.app, ReactServer.new
+    ReactServer.start
+    Dir.chdir File.expand_path('../../views', __FILE__) do
+      @script = Ruby2JS.convert(File.read('app.js.rb'), file: 'app.js.rb')
+    end
+  end
+
+  def on_react_server(&block)
+    page.driver.post('/', @script + ';' + Ruby2JS.convert(block, react: true))
+  end
+
+  it "has an add-comment form with a disabled Save button" do
+    on_react_server do
+      React.render _AddComment(server: {initials: 'sr'}), document.body do
+        response.end document.body.innerHTML
+      end
+    end
+
+    expect(page).to have_selector '.modal#comment-form'
+    expect(page).to have_selector '.modal .modal-dialog .modal-header h4',
+      text: 'Enter a comment'
+    expect(page).to have_selector '.modal-body input'
+#   expect(page).to have_selector '.modal-body input[value="sr"]'
+    expect(page).to have_selector '.modal-footer button[disabled]',
+      text: 'Save'
+  end
+
+  after :all do
+    ReactServer.stop
+    Capybara.app = @app
+  end
+end
diff --git a/spec/react_server.rb b/spec/react_server.rb
new file mode 100644
index 0000000..6ae74e9
--- /dev/null
+++ b/spec/react_server.rb
@@ -0,0 +1,96 @@
+#
+# This class spawns a io.js process to run a HTTP server which accepts
+# POST requests containing React TestUtils scripts and responds with 
+# HTML results.  It provides a Rack interface, enabling this server to
+# be run with Capybara/RackTest.
+#
+
+require 'ruby2js'
+require 'net/http'
+require 'stringio'
+
+class ReactServer
+  @@pid = nil
+  @@port = nil
+
+  # start a new server
+  def self.start
+    return if @@pid
+
+    # select an available port
+    server = TCPServer.new('127.0.0.1', 0)
+    @@port = server.addr[1]
+    server.close
+
+    # spawn a server process
+    @@pid = spawn('iojs', '-e', 
+      Ruby2JS.convert(@@server, {ivars: {:@port => @@port}}))
+
+    # wait for server to start
+    (0..10).each do |i|
+      begin
+        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')
+      rescue Errno::ECONNREFUSED
+        sleep i * 0.1
+      end
+    end
+  end
+
+  # rack compatible interface
+  def call(env)
+    http = Net::HTTP.new('localhost', @@port)
+    request = Net::HTTP::Post.new('/', {})
+    request.body = env['rack.input'].read
+    response = http.request(request)
+    [response.code, response.to_hash(), response.body]
+  end
+
+  # stop server
+  def self.stop
+    return unless @@pid
+    http = Net::HTTP.new('localhost', @@port)
+    request = Net::HTTP::Post.new('/', {})
+    request.body = "response.end('bye'); process.exit(0)"
+    response = http.request(request)
+    Process.wait(@@pid)
+    @@pid = nil
+  end
+
+  # the server itself
+  @@server = proc do
+    React = require 'react'
+    ReactAddons = require 'react/addons'
+    TestUtils = React.addons.TestUtils
+
+    jsdom = require("jsdom").jsdom
+    global.document = jsdom('<html><body></body></html>')
+    global.window = document.defaultView
+
+    http = require('http')
+    server = http.createServer do |request, response|
+      data = ''
+      request.on('data') do |chunk| 
+        data += chunk
+      end
+
+      request.on 'error' do |error|
+        console.log "ReactServer error: #{error.message}"
+      end
+
+      request.on 'end' do
+        response.writeHead(200, 'Content-Type' => 'text/plain')
+
+        begin
+          eval(data)
+        rescue => error
+          response.end(error.toString());
+        end
+      end
+    end
+
+    server.listen(@port)
+  end
+end
diff --git a/views/add-comment.js.rb b/views/add-comment.js.rb
new file mode 100644
index 0000000..766dc86
--- /dev/null
+++ b/views/add-comment.js.rb
@@ -0,0 +1,58 @@
+class AddComment < React
+  def initialize
+    @save_disabled = true
+  end
+
+  def self.button
+    {
+      text: 'add comment',
+      class: 'btn_primary',
+      data_toggle: 'modal',
+      data_target: '#comment-form'
+    }
+  end
+
+  def render
+    _ModalDialog.comment_form! color: 'commented' do
+      # header
+      _h4 'Enter a comment'
+
+      #input field: initials
+      _div.form_group do
+        _label 'Initials', for: 'comment-initials'
+        _input.comment_initials!.form_control label: 'Initials',
+          placeholder: 'initials', defaultValue: Server.initials
+      end
+
+      #input field: comment text
+      _div.form_group do
+        _label 'Comment', for: 'comment-text'
+        _textarea.comment_text!.form_control label: 'Comment',
+          placeholder: 'comment', rows: 5, onInput: self.input
+      end
+
+      # footer buttons
+      _button.btn_default 'Cancel', data_dismiss: 'modal'
+      _button.btn_primary 'Save', disabled: @save_disabled, onClick: self.save
+    end
+  end
+
+  # enable/disable save when input changes
+  def input(event)
+    @save_disabled = ( event.target.value.length == 0 )
+  end
+
+  def save(event)
+    data = {
+      agenda: Agenda.file,
+      attach: @@item.attach,
+      initials: ~'#comment_initials'.value,
+      text: ~'#comment_text'.value
+    }
+
+    post 'comment', data do |pending|
+      Pending.load pending
+      ~'#comment-form'.modal(:hide)
+    end
+  end
+end
diff --git a/views/add-comment.rb b/views/add-comment.rb
deleted file mode 100644
index d397668..0000000
--- a/views/add-comment.rb
+++ /dev/null
@@ -1,58 +0,0 @@
-class AddComment < React
-  def initialize
-    @save_disabled = true
-  end
-
-  def self.button
-    {
-      text: 'add comment',
-      class: 'btn_primary',
-      data_toggle: 'modal',
-      data_target: '#comment-form'
-    }
-  end
-
-  def render
-    _ModalDialog.comment_form! color: 'commented' do
-      # header
-      _h4 'Enter a comment'
-
-      #input field: initials
-      _div.form_group do
-        _label 'Initials', for: 'comment-initials'
-        _input.comment_initials!.form_control label: 'Initials',
-          placeholder: 'initials', defaultValue: Server.initials
-      end
-
-      #input field: comment text
-      _div.form_group do
-        _label 'Comment', for: 'comment-text'
-        _textarea.comment_text!.form_control label: 'Comment',
-          placeholder: 'comment', rows: 5, onInput: self.input
-      end
-
-      # footer buttons
-      _button.btn_default 'Cancel', data_dismiss: 'modal'
-      _button.btn_primary 'Save', disabled: @save_disabled, onClick: self.save
-    end
-  end
-
-  # enable/disable save when input changes
-  def input(event)
-    @save_disabled = ( event.target.value.length == 0 )
-  end
-
-  def save(event)
-    data = {
-      agenda: Agenda.file,
-      attach: @item.attach,
-      initials: ~'#comment_initials'.value,
-      text: ~'#comment_text'.value
-    }
-
-    post 'comment', data do |pending|
-      Pending.load pending
-      ~'#comment-form'.modal(:hide)
-    end
-  end
-end

Mime
View raw message