Showing posts with label test. Show all posts
Showing posts with label test. Show all posts

Sunday, January 25, 2009

Building a Ruby Extension With Visual C++ Express 2008

Edit March 29, 2009: While the instructions below describe how to build the Win32::GuiTest extension, I didn't get very far with using it before I found Wx::Nobbie which I much prefer and have taken up the maintenance of at Github.

I'd like to be able to use Cucumber to drive the development of Windows applications so I went looking for something like Webrat for desktop GUI's. I found Win32::GuiTest.  There is a project of the same name on RubyForge that contains the same source but that's as far as that went. 

Win32::GuiTest is a C extension that was compiled with Cygwin, so I wanted to rebuild a native version.  I found some instructions on Kevin Kleinfelter's blog that look much like below, but using VC++ 2008 I got to skip a couple of steps:

  1. Download and install Visual C++ Express Edition (this is free, I got the 2008 version)
  2. Edit $RUBY_HOME/lib/ruby/1.8/i386-mswin32/config.h and delete the “#error MSC version unmatch” line
  3. Open a Visual Studio 2008 Command Prompt
    • Start
    • All Programs
    • Microsoft Visual C++ 2008 Express Edition
    • Visual Studio Tools
  4. cd C:\temp\guitest020218\ext\cguitest
    • I'm building the guitest extension
  5. ruby extconf.rb
  6. nmake
  7. mt.exe -manifest cguitest.so.manifest -outputresource:cguitest.so;2
    • Copy and paste the command above. You need it all from the 'mt' to the ';2'
  8. nmake install
  9. cd \temp\guitest020218
  10. ruby install.rb config
  11. ruby install.rb install
  12. To test:
    • irb
    • require 'win32/guitest'
    • check response is '=> true'

Wednesday, January 14, 2009

My first Rails bug – accepted!

At the time that I posted about My first Rails bug the tests that existed for Action Pack contained failures and the only test in integration_upload_test.rb was:

assert_equal(:multipart_form, SessionUploadTest.last_request_type)

I felt that my change could be submitted with no tests because:

  • The change was trivial (6 characters)
  • The change was for a well known Windows file issue
  • The tests that existed didn’t pass
  • There were no example tests for me to build on

Three months after I submitted the ticket, Pratik dismissed it by changing its state to incomplete with the comment “Missing a test case.”  Are these guys CRAZY?  No, no they are not.  Just because there were broken windows in the neighborhood did not give me the right to break any more.

So, I sucked it up, cloned the latest rails repository again and to my surprise … all the Action Pack tests passed! … and there was a nice simple example in multipart_params_parsing_test.rb:

  test "uploads and reads file" do
    with_test_routing do
      post '/read', :uploaded_data => fixture_file_upload(FIXTURE_PATH + "/hello.txt", "text/plain")
      assert_equal "File: Hello", response.body
    end
  end

This is too easy!  I added a test for my issue:

  test "uploads and reads a binary file in windows" do
    with_test_routing do
      fixture_file = FIXTURE_PATH + "/mona_lisa.jpg"
      post '/read', :uploaded_data => fixture_file_upload(fixture_file, "image/jpg")
      assert_equal 'File: '.length + File.size(fixture_file), response.content_length
    end
  end

Watched it fail.  Added the magic 6 characters (“, ‘rb’”).  Watched it pass.  Wrapped it up and shipped it off.  The following morning I pick up an email letting me know that Pratik has reopened the ticket and assigned it to Joshua Peek for review.  The change was committed before the day was out!

Many thanks to Pratik and Josh for attending to this so promptly.

Saturday, September 20, 2008

My first Rails bug

UPDATE January 14, 2009 -> The patch for this bug was accepted!

I'm pretty new to Rails and my first project included uploading videos. Shouldn't be too difficult I thought, after a little Google searching, I came up with the perfect example by Jim Neath: Converting Videos with Rails: Converting the Video Wanting to practice new skills with RSpec and Cucumber I wrote my first feature spec:

Feature: Upload videos
  In order to provide videos to users after hours
  As a videographer
  I want to upload videos

  Scenario: A valid filename is provided
    Given I go to the new video page
    And I browse to the file "Movie_0001.avi"

    When I submit the upload

    Then I should see "success"
    And the file should be uploaded
and the supporting steps file, upload_steps.rb:
require 'ftools'
require 'mime/types'

When /I browse to the file \"(.+)\"/ do |path|
  @original_filepath = File.join('features/fixtures/', path)
  mime_types = MIME::Types.of(@original_filepath)

  attach_file 'video[source]', @original_filepath, mime_types[0].content_type
end

When 'I submit the upload' do
  click_button 'Create'
end

def uploaded_filepath
  uploaded_basename = File.basename(@original_filepath)
  File.join(RAILS_ROOT, "public/videos/1", uploaded_basename)
end

Then /the file should be uploaded/ do
  assert File.compare(@original_filepath, uploaded_filepath)
end
what I got was:
...
    And the file should be uploaded
       is not true. (Test::Unit::AssertionFailedError)
      c:/ruby/lib/ruby/1.8/test/unit/assertions.rb:48:in `assert_block'
      c:/ruby/lib/ruby/1.8/test/unit/assertions.rb:500:in `_wrap_assertion'
      c:/ruby/lib/ruby/1.8/test/unit/assertions.rb:46:in `assert_block'
      c:/ruby/lib/ruby/1.8/test/unit/assertions.rb:63:in `assert'
      c:/ruby/lib/ruby/1.8/test/unit/assertions.rb:495:in `_wrap_assertion'
      c:/ruby/lib/ruby/1.8/test/unit/assertions.rb:61:in `assert'
      ./features/upload/steps/upload_steps.rb:22:in `And /the file should be uploaded/'
      features/upload/upload.feature:14:in `And the file should be uploaded'
...
On closer inspection, the test was failing because the uploaded file was truncated in some bizarre way. However, if I ran the application and manually upload a file from the browser, everything worked fine. After much hunting I ended up in rails/actionpack/lib/action_controller/integration.rb where in multipart_body, the mode is not specified in the call to File.open, so it defaults to "r". This is all well and good on anything but Windows, which I happen to be using! Windows requires that the mode be specified as "rb" to ensure the file is read as binary. I submitted a patch but I'm not holding my breath for it to be pulled in anytime soon.

Ruby PCAN DLL Wrapper

Inspired by System Testing In Ruby (Systir), I have published a small Ruby PCAN USB DLL Wrapper. Now with a small device available for less than $300 and some free software, I can write automated system test scripts of the form:
send tftp_rrq("autoexec.bat").with(blksize(2036)) verify_target_sends oack(blksize(2036) send ack(0) verify_target_sends autoexec_bat send ack(1)
If you have rubygems installed, PCAN DLL Wrapper is easily obtained:
set http_proxy=http://my_proxy_host.com:80 gem install pcanusb
and then use:
require 'pcan_usb' PCAN_USB.init(PCAN_USB::BAUD_1M) PCAN_USB.write(0x0E100501, "Hello World!") PCAN_USB.close