Skip to content

Instantly share code, notes, and snippets.

@jimweirich
Created December 12, 2011 02:28
Show Gist options
  • Save jimweirich/1464394 to your computer and use it in GitHub Desktop.
Save jimweirich/1464394 to your computer and use it in GitHub Desktop.
Description of a Refactoring Kata

Refactoring Kata

Here's an interesting refactoring challenge.

Refactor the tangle.c program described at http://axiom-developer.org/axiom-website/litprog.html with the goal of making it more readable and maintainable.

Some suggested guidelines and constraints. Of course, you can do whatever you want in your kata practice, but here are some ideas.

(1) Stay with C, don't change languages. It's easy to get a more readable program when using a more expressive language. Our goal here is to stretch our skills in producing readable code, not rely on the programming language.

(2) Don't stray too far from the original algorithm. Of couse you will be changing it a bit, but see if you can make the original algorithm more self-explanatory.

# It's always nice to have some tests, so here are a few high-level
# functional tests that you may use if you like.
require 'fileutils'
require 'rspec/given'
describe "tangle program" do
before :all do
FileUtils.mkdir_p "data"
open("data/sample.html", "w") do |sample|
sample.puts %{
omit
<pre id="first">
first 1
first 2
</pre>
more omit
<pre id="second">
second
</pre>
<pre id = "whitespace" >
white-space
</pre>
<pre id="illformed">
ill-formed
</pre>
<pre id=noquotes>
no quotes
<pre>
<pre id="unterminated>
terminator "
</pre>
<pre id="program.c">
&lt;getchunk id="first"&gt;
&lt;getchunk id="second"&gt;
&lt;getchunk id="entities"&gt;
</pre>
<pre id="entities">
-&lt;&gt;-
</pre>
<pre id="ampersand">
-&amp;&amp;-
</pre>
last omit
}
end
end
after :all do
FileUtils.rm "data/sample.html"
FileUtils.rmdir "data"
end
Given(:pending_msg) { nil }
Given { pending pending_msg if pending_msg }
Given(:args) { "#{html_file} #{chunk}" }
Given(:html_file) { "data/sample.html" }
When(:output) {
`./tangle 2>&1 #{args}`
}
context "with no command line args" do
Given(:args) { "" }
Then { output.should =~ /Usage:/ }
end
context "with one command line arg" do
Given(:chunk) { "" }
Then { output.should =~ /Usage:/ }
end
context "when extracting the first chunk" do
Given(:chunk) { "first" }
Then { output.should =~ /first 1.*first 2/m }
Then { output.should_not =~ /second/ }
Then { output.should_not =~ /omit/ }
end
context "when extracting the second chunk" do
Given(:chunk) { "second" }
Then { output.should =~ /second/ }
Then { output.should_not =~ /first/ }
Then { output.should_not =~ /omit/ }
end
context "when extracting ill-formed chunks, nothing is output" do
Given(:chunk) { "illformed" }
Then { output.should_not =~ /ill-formed/m }
Then { output.should_not =~ /omit/ }
end
context "when extracting chunks without quotes, nothing is output" do
Given(:chunk) { "noquotes" }
Then { output.should_not =~ /no quotes/m }
Then { output.should_not =~ /omit/ }
end
context "when extracting chunks unterminated chunk names, nothing is output" do
Given(:chunk) { "unterminated" }
Then { output.should_not =~ /terminator/m }
Then { output.should_not =~ /omit/ }
end
context "when extracting entities, they are translated properly" do
Given(:chunk) { "entities" }
Then { output.should =~ /-<>-/m }
end
context "when extracting chunks with ampersands, they are translated properly" do
Given(:chunk) { "ampersand" }
Then { output.should =~ /-&&-/m }
end
context "when extracting the program, all parts are there" do
Given(:chunk) { "program.c" }
Then { output.should =~ /first 1.*first 2.*second.*<>/m }
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment