require "spec_helper"
describe ProjectSearch::WordSearch do
after do
FileUtils.rm_rf(project_search_fixture_dir + "/.redcar")
ProjectSearch.indexes.clear
end
describe "options of the search" do
it "should have a query_string method" do
make_search("testset").query_string.should == "testset"
end
it "should construct a regex to match the query string" do
make_search("asdf", false).regex.should == /asdf/i
make_search("asdf", true).regex.should == /asdf/
end
it "should respond whether matching case or not" do
make_search("asdf", nil).match_case?.should == false
make_search("asdf", 123).match_case?.should == true
end
end
def fixture_project
@fixture_project ||= Redcar::Project.new(project_search_fixture_dir)
end
def make_search(query, match_case=true, context=0)
ProjectSearch::WordSearch.new(fixture_project, query, match_case, context)
end
describe "finding hits" do
it "should find one occurrence" do
results = make_search("Foo").results
results.length.should == 1
result = results.first
result.should be_an_instance_of(ProjectSearch::Hit)
File.expand_path(result.file).should == File.expand_path(project_search_fixture_dir + "/foo.txt")
result.line_num.should == 0
result.line("", "").should == "Foo Bar Baz"
end
it "should ignore binary files" do
results = make_search("HoHo").results
results.length.should == 0
end
it "should find every occurrence" do
results = make_search("xxx").results
results.length.should == 7
results.map {|r| r.line_num}.should == [16, 17, 19, 22, 26, 31, 37]
end
it "should ignore case if asked" do
results = make_search("Foo", false).results
results.length.should == 2
results.map {|r| r.line_num}.should == [0, 1]
results[0].file.should =~ /foo.txt$/
results[1].file.should =~ /foo.txt$/
end
end
describe "hits" do
it "should enwrap every occurrence" do
results = make_search("Corge").results
results.length.should == 1
result = results.first
result.should be_an_instance_of(ProjectSearch::Hit)
File.expand_path(result.file).should == File.expand_path(project_search_fixture_dir + "/foo.txt")
result.line_num.should == 2
result.line("", "").should == "Corge Corge Corge"
end
end
describe "pre context" do
it "should return pre context" do
results = make_search("333", true, 2).results
results.length.should == 1
result = results.first
result.pre_context.should == ["111", "222"]
end
it "should return no pre context for first line" do
results = make_search("Foo", true, 2).results
results.length.should == 1
result = results.first
result.pre_context.should == []
end
it "should return short pre context for second line" do
results = make_search("foo", true, 2).results
results.length.should == 1
result = results.first
result.pre_context.should == ["Foo Bar Baz"]
end
it "should return pre context for hits right after one another" do
results = make_search("xxx", true, 2).results
results[0].pre_context.should == [",,,", "aaa"]
results[1].pre_context.should == ["aaa", "bbb xxx"]
end
end
describe "post context" do
it "should return post context" do
results = make_search("333", true, 2).results
results.length.should == 1
result = results.first
result.post_context.should == ["444", "555"]
end
it "should return post context for hits right after one another" do
results = make_search("xxx", true, 2).results
results[0].post_context.should == ["ccc xxx", "ddd"]
results[1].post_context.should == ["ddd", "eee xxx"]
end
end
describe "when there are changes to the file system" do
it "should not return results for deleted files" do
test_file = File.expand_path(project_search_fixture_dir + "/jscar.txt")
File.open(test_file, "w") do |fout|
fout.puts "aa testword bb"
end
# indexing should have happened by now
search = make_search("testword")
search.results.map {|r| File.expand_path(r.file)}.should include(test_file)
FileUtils.rm_rf(test_file)
# should still work but should not include the result
search = make_search("testword")
search.results.map {|r| File.expand_path(r.file)}.should_not include(test_file)
end
end
describe "streaming search results" do
it "should stream by file" do
search = make_search("Christmas")
results_by_file = []
search.on_file_results do |file_hits|
results_by_file << file_hits
end
search.results
results_by_file.length.should == 2
results_by_file.map {|r| r.first.file.split("/").last}.sort.should == ["foo.txt", "qux.rb"].sort
end
end
end