After updating couch-replicate yesterday, I take a look at my couch_docs gem tonight. I received a patch a while back suggesting that watch mode should not update all documents when any update is made. That seem reasonable, so...
When I first start watching a directory, all documents should be pushed to the CouchDB server. Afterwards, if the updates are design documents, only the design documents should be updated. If the updates are normal documents, then the individual, updated documents should be updated. Sounds like a bunch of predicate methods to me.
First up, an RSpec example describing initial directory parsing:
it "should be an initial add if everything is an add" doThis dumps me into change-the-message of:
args = [mock(:type => :added),
mock(:type => :added)]
CommandLine.should be_initial_add(args)
end
1)I eventually get this passing with:
NoMethodError in 'CouchDocs::CommandLine an instance that dumps a CouchDB database should be an initial add if everything is an add'
undefined method `initial_add?' for CouchDocs::CommandLine:Class
./spec/couch_docs_spec.rb:471:
def initial_add?(args)I add a few more predicate methods, and then I am ready to refactor my directory watcher update block:
args.all? { |f| f.type == :added }
end
dw.add_observer do |*args|First up, I pull the
puts "Updating documents on CouchDB Server..."
CouchDocs.put_dir(@options[:couchdb_url],
@options[:target_dir])
end
put_dir
call out into a new (testable) directory_watcher_update
method:#...I run all of my specs to ensure nothing has broken (it has not) before describing in more detail what should happen with directory watcher updates. First up, it should update both design document and normal documents when first starting up (which is what
dw.add_observer do |*args|
puts "Updating documents on CouchDB Server..."
directory_watcher_update(args)
end
#...
def directory_watcher_update(args)
CouchDocs.put_dir(@options[:couchdb_url],
@options[:target_dir])
end
put_dir
does):it "should only update design docs if only local design docs have changed" doThat example passes without any changes (because that is the current behavior of the method). The trick will be to retain this behavior going forward.
CouchDocs.
should_receive(:put_dir)
@it.stub!(:initial_add?).and_return(true)
@it.directory_watcher_update(@args)
end
I drive this method to be able to handle design document updates as well before needing to call it a night:
def directory_watcher_update(args)The call to update normal (non-design) documents may require some refactoring before it can be used in here. I will pick up with that (and hopefully finish) tomorrow.
if initial_add? args
CouchDocs.put_dir(@options[:couchdb_url],
@options[:target_dir])
else
if design_doc_update? args
CouchDocs.put_design_dir(@options[:couchdb_url],
"#{@options[:target_dir]}/_design")
end
end
end
Day #56
No comments:
Post a Comment