Showing posts with label OperSource. Show all posts
Showing posts with label OperSource. Show all posts

Wednesday, September 19, 2007

Cotta 1.2 Release

I have got quite a few good feedback from Brian who is using it ('in anger'!) at Guidewire. So I am putting together a 1.2 release, even though the change list is really small.

This also include some JavaDoc updates. Even though I am not a believer myself on JavaDoc, I have come to realize that it is still a recognized way of communication and sometimes preferred over email or forum.

(I have been writing drafts about the work that I have been doing at Guidewire, just never been able to publish any of them... Not good if I want to keep this blog alive)

Friday, September 07, 2007

WebGen, Cool!

I finally run into WebGen today when checking out rSpec. So far by the look of it, it is exactly what I have been looking for for the last two years! Of course, that means that one third of my work with BuildMaster will be out of commission, but this is such a good thing!

I supposed this was bound to happen sooner or later.

I thought it was a bit odd that I didn't find anything interesting when I had the idea of generating a static HTML website based on specified template and using wiki style format like Textile. I had several simple websites to generate at that moment (my homepage, jBehave at the time, Cotta, and BuildMaster), so I settled for creating one of my own with some simple Ruby script as the base. It worked out well because I have been able to update the content very easily. Earlier this year, I also set up the selenium Ruby project very easily.

It didn't come without a price, when I released BuildMaster 0.7.0 . I just settled for the fact that there is simply not one that is easily found. I also try my best to enhance it to be more powerful and flexible but I just never got enough time.

Now with WebGen, I can finally take something off my plate and still get what I want. Since I wrote those websites with Textile syntax already, I don't see a big content format conversion either.

My first reaction was that "Man I wasted a lot of time because the lack of information". Then I realized that I learned pretty much everything I know about Ruby and rSpec while working on this module, and that the Cotta layer that I extracted out of it is still very valuable. So even though I do need to do a better research next time, this time it worked out for the best.

Friday, June 01, 2007

rSpec 1.0.4

Busy with BuildMaster, selenium-ruby, and Entrance, I have not looked at rspec for a while.

Until the Code Kata with rSpec we did at BayXP last week.

Boy have they changed...

And all for the better I'll say, after converted one file last night. Personally I liked the 'specify' more like 'it'. Actually, I thought they would go with 'should' since I type that at the beginning of the every specification name.

But that is small thing. With the new version, it would be a lot easier to come up with new matchers, re-use behaviors.

Update: Check out the rspec report I have after converting to this version! It is actually cool to see the broken tests report, more so than the passing report that rspec has itself

http://buildmaster.rubyforge.org/rspec/

Friday, December 15, 2006

fix svn tagging in sourceforge

I have been having tagging problem with Subversion in Sourceforge. It took me several days to realize that this is not going to be resolved by itself. Once again, Google helped me found the solution:

You need to point your working directory to a different repository URL, through command like:

svn switch --relocate https://svn.sourceforge.net/svnroot/cotta/trunk https://cotta.svn.sourceforge.net/svnroot/cotta/trunk

You just need to replace 'cotta' to the unix name of your project.

Thursday, November 09, 2006

Code Snippet, with Color!

I did it!

Now build master can grab code snippet from another file and apply syntax highlighting using syntax.

Next step is to figure out a way to specify the snippet validations.

I am dead tired right now and I have a 9am meeting tomorrow. So I just updated two (actually one and half) pages to show it off.


I also fixed the document source and history link at the end of each page so you should be able to see the source file now.

Saturday, September 23, 2006

BuildMaster Surgery - Moving to Cotta

I have been struggling with the File operations for a while, before I fully understand what is going on.

After I released Cotta project, the way File operations works in Ruby is like a hideous stain on top of a shining gem, always bugged me, especially when there are these nice classes like Pathname and StringIO already exist in Ruby.

Finally, my curiosity of making it better got the best of me, and I ported BuildMaster over to Cotta Style.

I have decided to call the files CottaFile and CottaDirectory so that I don't have to worried about the name space issue. Since BuildMaster does quite a bit of shell operations, I added method "shell" to the cotta instance so that the in memory version can log them for tests.

All things are happening behind the scene. The following is a code snippet demonstrate the new API:


#system implementation is injected here
cotta = BuildMaster::Cotta.new(BuildMaster::InMemorySystem.new)
file2 = cotta.file('dir2/file.txt')
file2.exists?.should_equal false
# parent directories are created automatically
@file.save('my content')
@file.copy_to(file2)
file2.exists?.should_equal true
file2.load.should_equal 'my content'
file2.read {|file| puts file.gets}


The API still need to be fine tuned but they provide all the operations that BuildMaster needs for the moment. Hopefully, someday something like this can be part of the ruby library.

BuildMaster Surgery - Moving to rSpec

This is the first part of the BuildMaster surgery that I have just finished (well, 95%) that have been keeping me up late every day. I will write the second part as a separate blog.

Moving BuildMaster to rSpec turned out to be not as smoothly as I hoped. Hopefully this blog will help anyone who is interested on similar task. This is what I have figured out so far so if there is a better way of doing it do let me know.

Syntax Change

If you have tons of test/unit scripts already, changing the code to use the rSpec syntax could be boring. They do have "Test::Unit Migration" support. However, I didn't get to take full advantage. It just generated "migration error" with no detail information for me. So I had to use some regular expressions to get the most of the change done, which I have blogged in "Going rSpec".

Specification Sharing

The "Context API" document on rSpec teaches you how to call helper methods in your specification code. However, it does not show you how you can make two context share the specifications, which is very useful if you want to make sure that two different implementation of the same interface shares the exact same behaviors.

Brain from Pivotal showed me that you can achieve this by using 'extend' (instead of include). So you can write the common behavior specifications in one file:

module CottaSpecifications

def register_cotta_file_specifications
setup do
# this one uses the @system that will be set up by each implementation spec setup
@file = BuildMaster::CottaFile.new(@system, Pathname.new('dir/file.txt'))
end

specify 'file can be created with system and pathname' do
@file.name.should_equal 'file.txt'
end
end
Then you can include those common behavior in your specification file for the implementation:
require 'cotta_file_specifications'
module BuildMaster
context 'Cotta file' do
# extending the module so that you can call the methods
extend CottaSpecifications
setup do
# setup the implementation for specifications
@system = InMemorySystem.new
end

# this call registers all the spefications
register_cotta_file_specifications
end
end
Hopefully the above code makes sense to you. If not, let me know.


Running All Specifications

Again, thanks Brain to explain the reason and provided me with a solution.

Somehow, all the registered contexts are run at the end of each context registration. So my code for loading all the tests will now make the same context run again and again:

If you have context A and B in tc_a.rb and tc_b.rb and you require each file one by one. After "require 'tc_a'", the specifications in Context A will run. After "require 'tc_b'", the specifications in Context B will run, this time ALONG with all the specification in Context A. If you have C, D, etc., then specifications of Context A will run again and again at the end of each following require.

So Brain wrote his own specification runner, which will hold off the execution until all the contexts are loaded:

require 'rubygems'
require 'spec'
#require 'diff/lcs'
dir = File.dirname(__FILE__)
#require "#{dir}/../test/common_test_case"
require 'test/unit'
Test::Unit.run = true

args = ARGV.dup
unless args.include?("-f") || args.include?("--format")
args << "--format"
args << "specdoc"
end
#args << "--diff"
args << $0
$context_runner = ::Spec::Runner::OptionParser.create_context_runner(args, false, STDERR, STDOUT)

def run_context_runner_if_necessary(system_exit, has_run)
return if system_exit && !(system_exit.respond_to?(:success?) && system_exit.success?)
return if has_run
exit context_runner.run(true)
end

at_exit do
has_run = !context_runner.instance_eval {@reporter}.instance_eval {@start_time}.nil?
run_context_runner_if_necessary($!, has_run)
end


To use this, all I needed to do was to require this file at the beginning of my "ts_buildmaster.rb" file.

And it generates nice output too:

...
Directory object with cotta for in memory system
...
- dir should return sub directory
- dir should return a directory from a relative pathname
- should get file in current directory
- should create dir and its parent
- should delete dir and its children
- should do nothing if dir already exists
- should list dirs

Directory object with cotta for physical system
...
- dir should return sub directory
- dir should return a directory from a relative pathname
- should get file in current directory
- should create dir and its parent
- should delete dir and its children
- should do nothing if dir already exists
- should list dirs
...

Friday, September 01, 2006

One Week in SLC

The past four days just flew by and I am now sitting at the airport waiting for my flight back. I was hoping to fly my wife over so that we can visit the mountains around here during the weekend but it turned out to be much more expensive. That is OK, I still need to scout out the beach park where I am going to host the BBQ party next weekend.

I held on to a story card and paired with different developer each day. The domain that this story affects turned out to be the worst part of the application so each day I did a bit of clean-up and refactoring. The story dragged on a bit but I managed to make steady progress.

Since this is a .NET project, there are SQL server and IIS server to run on the laptop. After figuring out how to start and stop the service from the command, I wrote two Ruby driver class for them in the hotel room and checked them into BuildMaster.

So now I have a script that I can call to stop both service with:
services.rb stop
and all it does is:
services = [
BuildMaster::IisDriver.new, BuildMaster::SqlServerDriver.new
].each do |service|
service.send ARGV[0]
end

Saturday, August 26, 2006

Tying Up Loose End - Cotta

So I have rolled off another project and I am going on the next project right away next week.

Typing up a few the loose end at the moment, since I won't be able to have a couple of weeks beach time like I did last time.

I have started with Cotta because this is most close to being ready. Based on the feedback and my experience with Ruby file handling, I have finalized the core API. Release candidate is now available. Even though I still prefer setting all the API right on the first release, my busy schedule just won't allow it. I think I'll release 1.0 and leave it like that, until I get a chance using it or get some feedback from the field.

Of course, SourceForge is done, so in the meanwhile, only the website is available.

More blog coming up with last project, and other loose ends.