komainu 0.0.8 → 0.0.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/README.md CHANGED
@@ -14,13 +14,18 @@ require "komainu"
14
14
  require "ostruct"
15
15
 
16
16
  item1 = OpenStruct.new
17
- item1.text = "hello"
17
+ item1.text = "You are a smelly pirate hooker."
18
+
18
19
  item2 = OpenStruct.new
19
- item2.text = "world"
20
+ item2.text = "You look like a blueberry."
21
+
22
+ item3 = OpenStruct.new
23
+ item3.text = "Why don't you go back to your home on Whore Island?"
24
+
20
25
  searchables = [item1, item2]
21
- Komainu.search("world", searchables)
26
+ Komainu.search("blue", searchables)
22
27
 
23
- #=> {:suggestion=>nil, :items=>["world"]}
28
+ #=> {:suggestion=>nil, :items=>["You look like a blueberry."]}
24
29
  ```
25
30
 
26
31
  ### Suggestions
@@ -15,13 +15,18 @@ require "komainu"
15
15
  require "ostruct"
16
16
 
17
17
  item1 = OpenStruct.new
18
- item1.text = "hello"
18
+ item1.text = "You are a smelly pirate hooker."
19
+
19
20
  item2 = OpenStruct.new
20
- item2.text = "world"
21
+ item2.text = "You look like a blueberry."
22
+
23
+ item3 = OpenStruct.new
24
+ item3.text = "Why don't you go back to your home on Whore Island?"
25
+
21
26
  searchables = [item1, item2]
22
- Komainu.search("world", searchables)
27
+ Komainu.search("blue", searchables)
23
28
 
24
- #=> {:suggestion=>nil, :items=>["world"]}
29
+ #=> {:suggestion=>nil, :items=>["You look like a blueberry."]}
25
30
  :end:
26
31
  ```
27
32
 
@@ -7,9 +7,9 @@ Gem::Specification.new do |s|
7
7
  s.version = Komainu::VERSION
8
8
  s.authors = ["Andrew Vos"]
9
9
  s.email = ["andrew.vos@gmail.com"]
10
- s.homepage = ""
11
- s.summary = %q{}
12
- s.description = %q{}
10
+ s.homepage = "https://github.com/AndrewVos/komainu"
11
+ s.summary = %q{Simple text search}
12
+ s.description = %q{Simple text search using a mixture of basic string search and Levenshtein Distance}
13
13
 
14
14
  s.rubyforge_project = "komainu"
15
15
 
@@ -1,7 +1,7 @@
1
1
  require "komainu/trie_node"
2
2
 
3
3
  module Komainu
4
- class Levenshtein
4
+ class CalculatesLevenshteinDistance
5
5
  def initialize(words)
6
6
  @trie = TrieNode.new
7
7
  words.each do |word|
@@ -0,0 +1,9 @@
1
+ module Komainu
2
+ class Match
3
+ attr_reader :index, :text
4
+ def initialize index, text
5
+ @index = index
6
+ @text = text
7
+ end
8
+ end
9
+ end
@@ -1,7 +1,16 @@
1
- require "komainu/levenshtein"
1
+ require "komainu/calculates_levenshtein_distance"
2
2
  require "komainu/search_results"
3
+ require "komainu/match"
3
4
 
4
5
  module Komainu
6
+ class SearchResult
7
+ attr_reader :object, :matches
8
+ def initialize object, matches
9
+ @object = object
10
+ @matches = matches
11
+ end
12
+ end
13
+
5
14
  class SearchesText
6
15
  def initialize data_to_search
7
16
  @data_to_search = data_to_search
@@ -10,10 +19,9 @@ module Komainu
10
19
  def search query
11
20
  results = SearchResults.new
12
21
  @data_to_search.each do |searchable|
13
- if text_includes_string(searchable.text, query)
14
- results.items << searchable
15
- elsif text_includes_words_from_string(searchable.text, query)
16
- results.items << searchable
22
+ matches = find_matches(searchable.text, query)
23
+ if matches.any?
24
+ results.items << SearchResult.new(searchable, matches)
17
25
  end
18
26
  end
19
27
 
@@ -25,7 +33,7 @@ module Komainu
25
33
 
26
34
  def calculate_suggestion(query)
27
35
  words = split_into_words(@data_to_search.map { |searchable| searchable.text }.join(" "))
28
- levenshtein = Levenshtein.new(words)
36
+ levenshtein = CalculatesLevenshteinDistance.new(words)
29
37
 
30
38
  suggestion = split_into_words(query).map do |word|
31
39
  matches = levenshtein.search(word, 2)
@@ -49,14 +57,18 @@ module Komainu
49
57
  string.scan(/\b\w+\b/)
50
58
  end
51
59
 
52
- def text_includes_string text, string
53
- text.downcase.include? string.downcase
54
- end
55
-
56
- def text_includes_words_from_string text, string
57
- string.split(" ").any? do |word|
58
- text_includes_string(text, word)
59
- end
60
+ def find_matches text, string
61
+ text = text.downcase
62
+ matches = []
63
+ string.split(" ").each { |word|
64
+ word = word.downcase
65
+ offset = 0
66
+ while matched_index = text.index(word, offset)
67
+ matches << Match.new(matched_index, word)
68
+ offset += word.length
69
+ end
70
+ }
71
+ matches
60
72
  end
61
73
  end
62
74
  end
@@ -1,3 +1,3 @@
1
1
  module Komainu
2
- VERSION = "0.0.8"
2
+ VERSION = "0.0.9"
3
3
  end
@@ -1,10 +1,10 @@
1
1
  require File.expand_path(File.join(File.dirname(__FILE__), "..", "spec_helper"))
2
- require "komainu/levenshtein"
2
+ require "komainu/calculates_levenshtein_distance"
3
3
 
4
4
  module Komainu
5
- describe Levenshtein do
5
+ describe CalculatesLevenshteinDistance do
6
6
  it "finds words with a distance less the maximum distance" do
7
- levenshtein = Levenshtein.new(["hello", "there", "good", "sirs"])
7
+ levenshtein = CalculatesLevenshteinDistance.new(["hello", "there", "good", "sirs"])
8
8
  levenshtein.search("hell", 14).must_equal({
9
9
  "hello" => 1,
10
10
  "there" => 3,
@@ -6,31 +6,27 @@ module Komainu
6
6
  subject { SearchesText.new(data_to_search) }
7
7
 
8
8
  let :data_to_search do
9
- item1 = OpenStruct.new
10
- item1.name = :item1
11
- item1.text = "This is some text."
12
- item2 = OpenStruct.new
13
- item2.name = :item2
14
- item2.text = "Batman has no parents"
15
- [item1, item2]
9
+ @item1 = OpenStruct.new({:text => "This is some text."})
10
+ @item2 = OpenStruct.new({:text => "Batman has no parents"})
11
+ [@item1, @item2]
16
12
  end
17
13
 
18
14
  it "finds exact matches" do
19
15
  result = subject.search("Batman has")
20
16
  result.items.size.must_equal 1
21
- result.items.first.name.must_equal :item2
17
+ result.items.first.object.must_equal @item2
22
18
  end
23
19
 
24
20
  it "finds matches in any case" do
25
21
  result = subject.search("BATMAN has")
26
22
  result.items.size.must_equal 1
27
- result.items.first.name.must_equal :item2
23
+ result.items.first.object.must_equal @item2
28
24
  end
29
25
 
30
26
  it "finds matches if the text is not in order" do
31
27
  result = subject.search("has batman")
32
28
  result.items.size.must_equal 1
33
- result.items.first.name.must_equal :item2
29
+ result.items.first.object.must_equal @item2
34
30
  end
35
31
 
36
32
  it "suggests an alternate query" do
@@ -49,5 +45,18 @@ module Komainu
49
45
  result = SearchesText.new([item]).search("hell")
50
46
  result.suggestion.must_equal "hellp"
51
47
  end
48
+
49
+ it "knows where the matches were" do
50
+ item = OpenStruct.new
51
+ item.text = "Derp herp"
52
+
53
+ result = SearchesText.new([item]).search("derp herp")
54
+
55
+ result.items.first.matches[0].text.must_equal "derp"
56
+ result.items.first.matches[0].index.must_equal 0
57
+
58
+ result.items.first.matches[2].text.must_equal "herp"
59
+ result.items.first.matches[2].index.must_equal 5
60
+ end
52
61
  end
53
62
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: komainu
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.8
4
+ version: 0.0.9
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2011-11-25 00:00:00.000000000Z
12
+ date: 2011-12-01 00:00:00.000000000Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: minitest
16
- requirement: &70133062670220 !ruby/object:Gem::Requirement
16
+ requirement: &70258233968580 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: '0'
22
22
  type: :development
23
23
  prerelease: false
24
- version_requirements: *70133062670220
24
+ version_requirements: *70258233968580
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: rake
27
- requirement: &70133062669200 !ruby/object:Gem::Requirement
27
+ requirement: &70258233967340 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ! '>='
@@ -32,10 +32,10 @@ dependencies:
32
32
  version: '0'
33
33
  type: :development
34
34
  prerelease: false
35
- version_requirements: *70133062669200
35
+ version_requirements: *70258233967340
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: docu
38
- requirement: &70133062668160 !ruby/object:Gem::Requirement
38
+ requirement: &70258233966460 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
41
  - - ! '>='
@@ -43,8 +43,9 @@ dependencies:
43
43
  version: '0'
44
44
  type: :development
45
45
  prerelease: false
46
- version_requirements: *70133062668160
47
- description: ''
46
+ version_requirements: *70258233966460
47
+ description: Simple text search using a mixture of basic string search and Levenshtein
48
+ Distance
48
49
  email:
49
50
  - andrew.vos@gmail.com
50
51
  executables: []
@@ -60,18 +61,19 @@ files:
60
61
  - Rakefile
61
62
  - komainu.gemspec
62
63
  - lib/komainu.rb
64
+ - lib/komainu/calculates_levenshtein_distance.rb
63
65
  - lib/komainu/komainu.rb
64
- - lib/komainu/levenshtein.rb
66
+ - lib/komainu/match.rb
65
67
  - lib/komainu/search_results.rb
66
68
  - lib/komainu/searches_text.rb
67
69
  - lib/komainu/trie_node.rb
68
70
  - lib/komainu/version.rb
71
+ - spec/komainu/calculates_levenshtein_distance_spec.rb
69
72
  - spec/komainu/komainu_spec.rb
70
- - spec/komainu/levenshtein_spec.rb
71
73
  - spec/komainu/searches_text_spec.rb
72
74
  - spec/komainu/trie_node_spec.rb
73
75
  - spec/spec_helper.rb
74
- homepage: ''
76
+ homepage: https://github.com/AndrewVos/komainu
75
77
  licenses: []
76
78
  post_install_message:
77
79
  rdoc_options: []
@@ -94,10 +96,10 @@ rubyforge_project: komainu
94
96
  rubygems_version: 1.8.10
95
97
  signing_key:
96
98
  specification_version: 3
97
- summary: ''
99
+ summary: Simple text search
98
100
  test_files:
101
+ - spec/komainu/calculates_levenshtein_distance_spec.rb
99
102
  - spec/komainu/komainu_spec.rb
100
- - spec/komainu/levenshtein_spec.rb
101
103
  - spec/komainu/searches_text_spec.rb
102
104
  - spec/komainu/trie_node_spec.rb
103
105
  - spec/spec_helper.rb