Fix stringContainsInOrder to account for repetitions and empty strings (#178)

Note that this may cause breakage in too many tests and need to be reverted.
diff --git a/CHANGELOG.md b/CHANGELOG.md
index d8a3dd1..db929a4 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,6 +1,8 @@
 ## 0.12.11-dev
 
 * Change many argument types from `dynamic` to `Object?`.
+* Fix `stringContainsInOrder` to account for repetitions and empty strings.
+  * **Note**: This may break some existing tests, as the behavior does change.
 
 ## 0.12.10
 
diff --git a/lib/src/string_matchers.dart b/lib/src/string_matchers.dart
index a0371c7..8b2f95a 100644
--- a/lib/src/string_matchers.dart
+++ b/lib/src/string_matchers.dart
@@ -122,8 +122,9 @@
   bool typedMatches(dynamic item, Map matchState) {
     var fromIndex = 0;
     for (var s in _substrings) {
-      fromIndex = item.indexOf(s, fromIndex);
-      if (fromIndex < 0) return false;
+      var index = item.indexOf(s, fromIndex);
+      if (index < 0) return false;
+      fromIndex = index + s.length;
     }
     return true;
   }
diff --git a/test/string_matchers_test.dart b/test/string_matchers_test.dart
index 0367660..2b42e43 100644
--- a/test/string_matchers_test.dart
+++ b/test/string_matchers_test.dart
@@ -120,6 +120,19 @@
         'goodbye cruel world', stringContainsInOrder(['cruel', 'world']));
     shouldPass('goodbye cruel world',
         stringContainsInOrder(['goodbye', 'cruel', 'world']));
+    shouldPass(
+        'foo', stringContainsInOrder(['f', '', '', '', 'o', '', '', 'o']));
+
+    shouldFail(
+        'abc',
+        stringContainsInOrder(['ab', 'bc']),
+        "Expected: a string containing 'ab', 'bc' in order "
+            "Actual: 'abc'");
+    shouldFail(
+        'hello',
+        stringContainsInOrder(['hello', 'hello']),
+        "Expected: a string containing 'hello', 'hello' in order "
+            "Actual: 'hello'");
     shouldFail(
         'goodbye cruel world',
         stringContainsInOrder(['goo', 'cruel', 'bye']),