require 'minitest/autorun'
require 'simstring_pure'

class SimStringTest < Minitest::Test
  def test_ngram_builder
    ngram_builder = SimString::NGramBuilder.new(3)
    ngrams = ngram_builder.features("food")
    expected_ngrams = Set.new([
      SimString::NGram.new("#{SimString::NGramBuilder::SENTINAL_CHAR * 2}f", 1),
      SimString::NGram.new("#{SimString::NGramBuilder::SENTINAL_CHAR * 1}fo", 1),
      SimString::NGram.new("foo", 1),
      SimString::NGram.new("ood", 1),
      SimString::NGram.new("od#{SimString::NGramBuilder::SENTINAL_CHAR * 1}", 1),
      SimString::NGram.new("d#{SimString::NGramBuilder::SENTINAL_CHAR * 2}", 1)
    ])
    assert_equal(expected_ngrams, ngrams)
  end

  # This test re-implements the sample program here: https://github.com/chokkan/simstring/blob/master/sample/sample.cpp
  # The following output was generated by running the official simstring tool against a database consisting of the two
  # strings: "Barack Hussein Obama II" and "James Gordon Brown"
  # The program below replicates the results.
  # Here are the results from the official simstring tool:
  #   davidellis:~/Projects/ruby/simstring (master) $ simstring -b -d sample.db -m
  #   SimString 1.1 Copyright (c) 2009-2011 Naoaki Okazaki
  #
  #   Constructing the database
  #   Database name: sample.db
  #   N-gram length: 3
  #   Begin/end marks: true
  #   Char type: c (1)
  #   Barack Hussein Obama II
  #   James Gordon Brown
  #   Number of strings: 2
  #
  #   Flushing the database
  #
  #   Total number of strings: 2
  #   Seconds required: 0.00165
  #
  #   davidellis:~/Projects/ruby/simstring (master) $ simstring -d sample.db -m -t 0.6
  #   Barack Obama
  #   0 strings retrieved (0.0005 sec)
  #   Gordon Brown
  #   	James Gordon Brown
  #   1 strings retrieved (0.000263 sec)
  #   Obama
  #   0 strings retrieved (0.00018 sec)
  #   davidellis:~/Projects/ruby/simstring (master) $ simstring -d sample.db -m -t 1.0 -s overlap
  #   Obama
  #   0 strings retrieved (0.000312 sec)
  #   ^C
  #   davidellis:~/Projects/ruby/simstring (master) $ simstring -d sample.db -m -t 0.42 -s overlap
  #   Obama
  #   	Barack Hussein Obama II
  #   1 strings retrieved (0.000311 sec)
  #   davidellis:~/Projects/ruby/simstring (master) $ simstring -d sample.db -m -t 0.43 -s overlap
  #   Obama
  #   0 strings retrieved (0.000292 sec)
  def test_string_matcher
    ngram_builder = SimString::NGramBuilder.new(3)
    db = SimString::Database.new(ngram_builder)

    db.add("Barack Hussein Obama II")
    db.add("James Gordon Brown")

    matcher = SimString::StringMatcher.new(db, SimString::CosineMeasure.new)

    assert_equal([], matcher.search("Barack Obama", 0.6))
    assert_equal(["James Gordon Brown"], matcher.search("Gordon Brown", 0.6))
    assert_equal([], matcher.search("Obama", 0.6))
    assert_equal([], matcher.search("Obama", 1, SimString::OverlapMeasure.new))
    assert_equal([], matcher.search("Barack Hussein Obama I", 1, SimString::OverlapMeasure.new))
    assert_equal(["Barack Hussein Obama II"], matcher.search("Barack Hussein Obama II", 1, SimString::OverlapMeasure.new))
    assert_equal(["Barack Hussein Obama II"], matcher.search("Obama", 0.42, SimString::OverlapMeasure.new))
    assert_equal([], matcher.search("Obama", 0.43, SimString::OverlapMeasure.new))
  end

  def test_string_matcher2
    ngram_builder = SimString::NGramBuilder.new(3)
    db = SimString::Database.new(ngram_builder)

    File.readlines("wordlists/companynames.txt").each {|line| db.add(line.strip) }

    matcher = SimString::StringMatcher.new(db, SimString::CosineMeasure.new)

    assert_equal(
      ["PHH Corp",
        "Viad Corp",
        "Aegion Corp",
        "B2Gold Corp",
        "InfoSonics Corp",
        "GSV Capital Corp",
        "Intel Corporation"
      ],
      matcher.search("Inyel Corp", 0.4)
    )

    assert_equal(["Intel Corporation"], matcher.search("Intel Corp", 0.6))
  end
end
