   match =
     guesses: 1
   msg = "estimate_guesses returns cached guesses when available"
-  t.equal scoring.estimate_guesses(match), 1, msg
+  t.equal scoring.estimate_guesses(match, ''), 1, msg
   match =
     pattern: 'date'
+    token: '1977'
     year: 1977
     month: 7
     day: 14
   msg = "estimate_guesses delegates based on pattern"
-  t.equal scoring.estimate_guesses(match), scoring.date_guesses(match), msg
+  t.equal scoring.estimate_guesses(match, '1977'), scoring.date_guesses(match), msg
   t.end()
 
 test 'repeat guesses', (t) ->

  approx_equal t, log10(n), Math.log(n) / Math.log(10), "base change rule"
  t.end()

test 'bruteforce cardinality', (t) ->
  for [str, cardinality] in [
    # beginning / middle / end of lowers range
    [ 'a', 26 ]
    [ 'h', 26 ]
    [ 'z', 26 ]
    # sample from each other character group
    [ 'Q', 26 ]
    [ '0', 10 ]
    [ '9', 10 ]
    [ '$', 33 ]
    [ '£', 64 ]
    [ 'å', 64 ]
    # unicode
    [ 'α', 40 ]
    [ 'αβ', 40 ]
    [ 'Ϫα', 58 ]
    [ '好', 40 ]
    [ '信息论', 100 ]
    # combinations
    [ 'a$', 59 ]
    [ 'aQ£', 116 ]
    [ '9Z9Z', 36 ]
    [ '«信息论»', 164 ]
    ]
    msg = "cardinality of #{str} is #{cardinality}"
    t.equal scoring.cardinality(str), cardinality, msg
  t.end()

test 'search', (t) ->
  m = (i, j, guesses) ->
    i: i
    j: j
    guesses: guesses
  password = '0123456789'
  cardinality = 10 # |digits| == 10

  msg = (s) -> "returns one bruteforce match given an empty match sequence: #{s}"
  result = scoring.most_guessable_match_sequence password, []


  msg = (s) -> "returns bruteforce + match when match covers a suffix: #{s}"
  matches = [m1] = [m(3, 9, 1)]
  result = scoring.most_guessable_match_sequence password, matches, exclude_additive
  t.equal result.sequence.length, 2, msg("result.match.sequence.length == 2")
  m0 = result.sequence[0]
  t.equal m0.pattern, 'bruteforce', msg("first match is bruteforce")
