Tonight I continue to work on adding the
!code
macro to the couch_docs gem. The !code
macro, adopted from couchapp, kicks in when assembling individual Javascript files into a CouchDB design document. When a line with that macro is encountered, it is replaced with the contents of the referenced file (e.g. "foo.js" in "!code foo.js").First up, I have to decide from where to pull the library files. I'll opt for a sub-directory called "
__lib
":it "should find files with relative paths in __lib" doI can make that pass with:
File.
should_receive(:read).
with("fixtures/_design/__lib/foo.js")
@it.read_from_lib("foo.js")
end
def read_from_lib(path)Now I need to hook this code into the method that maps the directory structure into a code data structure:
File.read("#{couch_view_dir}/__lib/#{path}")
end
def expand_file(filename)The test coverage over this is functional rather than unit. I have fixture that are being assembled so that the result can be compared to expectations. What this means for my work here is that I have a freer reign in refactoring. Specifically, I can move that
File.dirname(filename).
gsub(/#{couch_view_dir}\/?/, '').
split(/\//) +
[
File.basename(filename, '.js').gsub(/%2F/, '/'),
File.read(filename)
]
end
File.read
into a separate method that can ultimately be hooked into the new read_from_lib
method:def expand_file(filename)Since I am already using fixtures in this area of the code, I might as well continue to do so. I create a
File.dirname(filename).
gsub(/#{couch_view_dir}\/?/, '').
split(/\//) +
[
File.basename(filename, '.js').gsub(/%2F/, '/'),
read_value(filename)
]
end
def read_value(filename)
File.read(filename)
end
fixtures/_design/x/z.js
file. This should map into a design document named "x" that points to a data structure like:{In the
"z" : "// contents of the z.js file"
}
z.js
file, I add the following contents, including a !code
macro:// !code foo.jsTo verify the
function bar () { return "bar"; }
!code
macro is working I create a fixtures/_design/__lib/foo.js
with the following contents:function foo () { return "foo"; }Thus, if the
!code
macro works, I expect the contents of the design document to be:function foo () { return "foo"; }Or, in RSpec format:
function bar () { return "bar"; }
it "should process code macros when assembling" doSince I have yet to hook the
@it.to_hash['x'].
should == {
'z' =>
"function foo () { return \"foo\"; }\n" +
"function bar () { return \"bar\"; }\n"
}
end
!code
processing macro into the read_value
method, this example fails:1)First, I switch the
'CouchDocs::DesignDirectory a valid directory should process code macros when assembling' FAILED
expected: {"z"=>"function foo () { return \"foo\"; }\nfunction bar () { return \"bar\"; }\n"},
got: {"z"=>"// !code foo.js\nfunction bar () { return \"bar\"; }\n"} (using ==)
./spec/couch_docs_spec.rb:309:
read_line
method to use read_lines
/join
instead of read
:def read_value(filename)I run my specs to verify that I have not broken functionality (the new
File.
readlines(filename).
join
end
!code
example still fails). Then I add a map
to make sure that the !code
macro get evaluated:def read_value(filename)Running my spec now, I find that indeed, I have got the
File.
readlines(filename).
map { |line| process_code_macro(line) }.
join
end
def process_code_macro(line)
if line =~ %r{\s*//\s*!code\s*(\S+)\s*}
read_from_lib($1)
else
line
end
end
!code
macro working as desired:cstrom@whitefall:~/repos/couch_docs$ spec spec/couch_docs_spec.rbNice! That will serve well as a stopping point for tonight. I am nearly at the end of my couch_docs 1.1 feature set.
.........................................
Finished in 0.129324 seconds
41 examples, 0 failures
Day #34
No comments:
Post a Comment