Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Improve cross platform portability #101

Merged
merged 5 commits into from almost 2 years ago

2 participants

Luis Lavena Josep M. Bach
Luis Lavena

Hello,

As discussed on the group:
https://groups.google.com/d/topic/spinach_bdd/Lyhr7E306Js/discussion

This pull request aims to make both tests and features work on Windows using functions found in Ruby 1.9 and removing non-cross platform things like FakeFS.

All tests pass on both Windows and OSX.

I wasn't sure about certain code guidelines so decided to use the ones I'm used while working on RubyGems. No ego will be offended if you ask me change the coding style :wink:

Thank you :heart::heart::heart:

added some commits April 26, 2012
Luis Lavena Remove open4 dependency and use Process.spawn
open4, POpen4, Open4 and many others, not counting cross OS version
of this gem.

Since Spinach aims to be Ruby 1.9 compatible, is better to use the
built in functionality which is cross-platform compatible.
159c358
Luis Lavena Do not shell out just to remove a directory ec4f083
Luis Lavena Don't leverage on shebang interpretation to run features
Instead, pre-compute `ruby` interpreter path and executable and use it.
212a2e3
Luis Lavena Use cross-platform friendly null device beb765b
Luis Lavena Remove FakeFS from test
And instead use the same trick used in features
3072e8d
Josep M. Bach txus merged commit 306dd40 into from April 26, 2012
Josep M. Bach txus closed this April 26, 2012
Josep M. Bach
Owner
txus commented April 26, 2012

That's a great pull request! Thank you Luis, merging right away, and releasing version 0.4.2. Thanks to you we can announce Windows compatibility <3 <3 !!!

Josep M. Bach
Owner
txus commented April 26, 2012

Oh sorry but Travis-CI just notified us the build was failing :/ It seems to have something to do with the filesystem: No such file or directory - tmp/fs.

Could you give it a look when you have a moment? Thank you again!

(Here's the failing Travis build)

Luis Lavena
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Showing 5 unique commits by 1 author.

Apr 26, 2012
Luis Lavena Remove open4 dependency and use Process.spawn
open4, POpen4, Open4 and many others, not counting cross OS version
of this gem.

Since Spinach aims to be Ruby 1.9 compatible, is better to use the
built in functionality which is cross-platform compatible.
159c358
Luis Lavena Do not shell out just to remove a directory ec4f083
Luis Lavena Don't leverage on shebang interpretation to run features
Instead, pre-compute `ruby` interpreter path and executable and use it.
212a2e3
Luis Lavena Use cross-platform friendly null device beb765b
Luis Lavena Remove FakeFS from test
And instead use the same trick used in features
3072e8d
This page is out of date. Refresh to see the latest.
29  features/support/filesystem.rb
... ...
@@ -1,5 +1,4 @@
1 1
 require 'fileutils'
2  
-require 'open4'
3 2
 
4 3
 # The Filesystem module runs commands, captures their output and exit status
5 4
 # and lets the host know about it.
@@ -46,11 +45,25 @@ def in_current_dir(&block)
46 45
   # @api public
47 46
   def run(command)
48 47
     in_current_dir do
49  
-      pid = Open4.popen4(command) do |pid, stdin, stdout, stderr|
50  
-        @stdout = stdout.readlines.join("\n")
51  
-        @stderr = stderr.readlines.join("\n")
52  
-      end
53  
-      @last_exit_status = pid.exitstatus
  48
+      # stdout, stderr pipes
  49
+      rout, wout = IO.pipe
  50
+      rerr, werr = IO.pipe
  51
+
  52
+      pid = Process.spawn(command, :out => wout, :err => werr)
  53
+      _, status = Process.wait2(pid)
  54
+
  55
+      # close write ends so we could read them
  56
+      wout.close
  57
+      werr.close
  58
+
  59
+      @stdout = rout.readlines.join("\n")
  60
+      @stderr = rerr.readlines.join("\n")
  61
+
  62
+      # dispose the read ends of the pipes
  63
+      rout.close
  64
+      rerr.close
  65
+
  66
+      @last_exit_status = status.exitstatus
54 67
     end
55 68
   end
56 69
 
@@ -60,6 +73,10 @@ def mkdir(dirname)
60 73
     FileUtils.mkdir_p(dirname) unless File.directory?(dirname)
61 74
   end
62 75
 
  76
+  def rmdir(dirname)
  77
+    FileUtils.rm_rf(dirname) unless File.directory?(dirname)
  78
+  end
  79
+
63 80
   def current_dir
64 81
     File.join(*dirs)
65 82
   end
13  features/support/spinach_runner.rb
... ...
@@ -1,3 +1,4 @@
  1
+require "rbconfig"
1 2
 require_relative 'filesystem'
2 3
 
3 4
 module Integration
@@ -8,7 +9,7 @@ def self.included(base)
8 9
       Spinach.hooks.before_scenario do
9 10
         if respond_to?(:in_current_dir)
10 11
           in_current_dir do
11  
-            run "rm -fR rails_app"
  12
+            rmdir "rails_app"
12 13
           end
13 14
         end
14 15
       end
@@ -18,7 +19,15 @@ def run_feature(command, options={})
18 19
       options[:framework] ||= :minitest
19 20
       use_minitest if options[:framework] == :minitest
20 21
       use_rspec if options[:framework] == :rspec
21  
-      run "../../bin/spinach #{command} #{options[:append]}"
  22
+      run "#{ruby} ../../bin/spinach #{command} #{options[:append]}"
  23
+    end
  24
+
  25
+    def ruby
  26
+      return @ruby if defined?(@ruby)
  27
+
  28
+      config = RbConfig::CONFIG
  29
+      @ruby = File.join(config["bindir"],
  30
+                  "#{config["ruby_install_name"]}#{config["EXEEXT"]}")
22 31
     end
23 32
 
24 33
     def use_minitest
15  lib/spinach/capybara.rb
... ...
@@ -1,5 +1,6 @@
1 1
 require 'capybara'
2 2
 require 'capybara/dsl'
  3
+require 'rbconfig'
3 4
 require_relative 'feature_steps'
4 5
 
5 6
 module Spinach
@@ -33,12 +34,24 @@ def self.included(base)
33 34
           def visit(*args)
34 35
             stream = STDOUT
35 36
             old_stream = stream.dup
36  
-            stream.reopen('/dev/null')
  37
+            stream.reopen(null_device)
37 38
             stream.sync = true
38 39
             super
39 40
           ensure
40 41
             stream.reopen(old_stream)
41 42
           end
  43
+
  44
+          def null_device
  45
+            return @null_device if defined?(@null_device)
  46
+
  47
+            if RbConfig::CONFIG["host_os"] =~ /mingw|mswin/
  48
+              @null_device = "NUL"
  49
+            else
  50
+              @null_device = "/dev/null"
  51
+            end
  52
+
  53
+            @null_device
  54
+          end
42 55
         end
43 56
       end
44 57
     end
2  spinach.gemspec
@@ -15,11 +15,9 @@ Gem::Specification.new do |gem|
15 15
   gem.add_development_dependency 'mocha'
16 16
   gem.add_development_dependency 'sinatra'
17 17
   gem.add_development_dependency 'capybara'
18  
-  gem.add_development_dependency 'open4'
19 18
   gem.add_development_dependency 'pry'
20 19
   gem.add_development_dependency 'simplecov'
21 20
   gem.add_development_dependency 'rspec'
22  
-  gem.add_development_dependency 'fakefs'
23 21
   gem.add_development_dependency 'minitest', '~> 2.0'
24 22
   gem.add_development_dependency 'turn'
25 23
 
34  test/spinach/generators/feature_generator_test.rb
@@ -63,28 +63,28 @@ module Spinach::Generators
63 63
 
64 64
     describe "#store" do
65 65
       it "stores the generated feature into a file" do
66  
-        FakeFS.activate!
67  
-        subject.store
68  
-        File.directory?("features/steps/").must_equal true
69  
-        File.exists?("features/steps/cheezburger_can_i_has.rb").must_equal true
70  
-        File.read("features/steps/cheezburger_can_i_has.rb").strip.must_equal(
71  
-          subject.generate.strip
72  
-        )
73  
-        FileUtils.rm_rf("features/steps")
74  
-        FakeFS.deactivate!
  66
+        in_current_dir do
  67
+          subject.store
  68
+          File.directory?("features/steps/").must_equal true
  69
+          File.exists?("features/steps/cheezburger_can_i_has.rb").must_equal true
  70
+          File.read("features/steps/cheezburger_can_i_has.rb").strip.must_equal(
  71
+            subject.generate.strip
  72
+          )
  73
+          FileUtils.rm_rf("features/steps")
  74
+        end
75 75
       end
76 76
 
77 77
       it "raises an error if the file already exists and does nothing" do
78 78
         file = "features/steps/cheezburger_can_i_has.rb"
79  
-        FakeFS.activate!
80  
-        FileUtils.mkdir_p "features/steps"
81  
-        File.open(file, 'w') do |f|
82  
-          f.write("Fake content")
  79
+        in_current_dir do
  80
+          FileUtils.mkdir_p "features/steps"
  81
+          File.open(file, 'w') do |f|
  82
+            f.write("Fake content")
  83
+          end
  84
+          Proc.new{subject.store}.must_raise(
  85
+            Spinach::Generators::FeatureGeneratorException)
  86
+          FileUtils.rm_rf("features/steps")
83 87
         end
84  
-        Proc.new{subject.store}.must_raise(
85  
-          Spinach::Generators::FeatureGeneratorException)
86  
-        FileUtils.rm_rf("features/steps")
87  
-        FakeFS.deactivate!
88 88
       end
89 89
     end
90 90
   end
25  test/spinach/generators_test.rb
@@ -32,19 +32,22 @@
32 32
   describe "#generate_feature" do
33 33
     it "generates a file" do
34 34
       feature_data = data
35  
-      FakeFS.activate!
36  
-      subject.generate_feature(feature_data)
37  
-      File.exists?("features/steps/cheezburger_can_i_has.rb").must_equal true
38  
-      FileUtils.rm_rf("features/steps")
39  
-      FakeFS.deactivate!
  35
+      in_current_dir do
  36
+        subject.generate_feature(feature_data)
  37
+        File.exists?("features/steps/cheezburger_can_i_has.rb").must_equal true
  38
+        FileUtils.rm_rf("features/steps")
  39
+      end
40 40
     end
  41
+
41 42
     it "outputs a message if feature cannot be generated" do
42  
-      subject::FeatureGenerator.expects(:new).raises(
43  
-        Spinach::Generators::FeatureGeneratorException.new("File already exists"))
44  
-      capture_stdout do
45  
-        subject.generate_feature(data)
46  
-      end.must_include "File already exists"
47  
-      File.exists?("features/steps/cheezburger_can_i_has.rb").must_equal false
  43
+      in_current_dir do
  44
+        subject::FeatureGenerator.expects(:new).raises(
  45
+          Spinach::Generators::FeatureGeneratorException.new("File already exists"))
  46
+        capture_stdout do
  47
+          subject.generate_feature(data)
  48
+        end.must_include "File already exists"
  49
+        File.exists?("features/steps/cheezburger_can_i_has.rb").must_equal false
  50
+      end
48 51
     end
49 52
   end
50 53
 end
13  test/support/filesystem.rb
... ...
@@ -0,0 +1,13 @@
  1
+require "fileutils"
  2
+
  3
+module Filesystem
  4
+  def in_current_dir(&block)
  5
+    dir = "tmp/fs"
  6
+    FileUtils.mkdir(dir)
  7
+    Dir.chdir(dir, &block)
  8
+  ensure
  9
+    FileUtils.rm_rf(dir)
  10
+  end
  11
+end
  12
+
  13
+MiniTest::Spec.send(:include, Filesystem)
3  test/test_helper.rb
@@ -15,11 +15,12 @@
15 15
 require 'ostruct'
16 16
 require 'stringio'
17 17
 require 'pry'
18  
-require 'fakefs/safe'
19 18
 require 'turn'
20 19
 
21 20
 require 'spinach'
22 21
 
  22
+require_relative "support/filesystem"
  23
+
23 24
 module Kernel
24 25
   def capture_stdout
25 26
     out = StringIO.new
Commit_comment_tip

Tip: You can add notes to lines in a file. Hover to the left of a line to make a note

Something went wrong with that request. Please try again.