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