From a00b6aa80e8d8204aa8aeb9e3b61d94f98973f91 Mon Sep 17 00:00:00 2001
From: gedi <gediminas.morkevicius@gmail.com>
Date: Thu, 16 Feb 2017 22:33:12 +0200
Subject: [PATCH] asserts ordinal argument position, fixes expected query error
 message

---
 expectations.go                               |  9 +--------
 expectations_go18.go                          |  3 ++-
 ..._test_go18.go => expectations_go18_test.go |  0
 rows.go                                       | 19 +++++++++++++++++++
 4 files changed, 22 insertions(+), 9 deletions(-)
 rename expectations_test_go18.go => expectations_go18_test.go (100%)

diff --git a/expectations.go b/expectations.go
index adc726e..415759e 100644
--- a/expectations.go
+++ b/expectations.go
@@ -167,14 +167,7 @@ func (e *ExpectedQuery) String() string {
 	}
 
 	if e.rows != nil {
-		msg += "\n  - should return rows:\n"
-		rs, _ := e.rows.(*rowSets)
-		for _, set := range rs.sets {
-			for i, row := range set.rows {
-				msg += fmt.Sprintf("    %d - %+v\n", i, row)
-			}
-		}
-		msg = strings.TrimSpace(msg)
+		msg += fmt.Sprintf("\n  - %s", e.rows)
 	}
 
 	if e.err != nil {
diff --git a/expectations_go18.go b/expectations_go18.go
index 29eeb30..2b4b44e 100644
--- a/expectations_go18.go
+++ b/expectations_go18.go
@@ -32,7 +32,6 @@ func (e *queryBasedExpectation) argsMatches(args []namedValue) error {
 		// custom argument matcher
 		matcher, ok := e.args[k].(Argument)
 		if ok {
-			// @TODO: does it make sense to pass value instead of named value?
 			if !matcher.Match(v.Value) {
 				return fmt.Errorf("matcher %T could not match %d argument %T - %+v", matcher, k, args[k], args[k])
 			}
@@ -45,6 +44,8 @@ func (e *queryBasedExpectation) argsMatches(args []namedValue) error {
 			if v.Name != named.Name {
 				return fmt.Errorf("named argument %d: name: \"%s\" does not match expected: \"%s\"", k, v.Name, named.Name)
 			}
+		} else if k+1 != v.Ordinal {
+			return fmt.Errorf("argument %d: ordinal position: %d does not match expected: %d", k, k+1, v.Ordinal)
 		}
 
 		// convert to driver converter
diff --git a/expectations_test_go18.go b/expectations_go18_test.go
similarity index 100%
rename from expectations_test_go18.go
rename to expectations_go18_test.go
diff --git a/rows.go b/rows.go
index 43681d4..39f9f83 100644
--- a/rows.go
+++ b/rows.go
@@ -3,6 +3,7 @@ package sqlmock
 import (
 	"database/sql/driver"
 	"encoding/csv"
+	"fmt"
 	"io"
 	"strings"
 )
@@ -46,6 +47,24 @@ func (rs *rowSets) Next(dest []driver.Value) error {
 	return r.nextErr[r.pos-1]
 }
 
+// transforms to debuggable printable string
+func (rs *rowSets) String() string {
+	msg := "should return rows:\n"
+	if len(rs.sets) == 1 {
+		for n, row := range rs.sets[0].rows {
+			msg += fmt.Sprintf("    row %d - %+v\n", n, row)
+		}
+		return strings.TrimSpace(msg)
+	}
+	for i, set := range rs.sets {
+		msg += fmt.Sprintf("    result set: %d\n", i)
+		for n, row := range set.rows {
+			msg += fmt.Sprintf("      row %d - %+v\n", n, row)
+		}
+	}
+	return strings.TrimSpace(msg)
+}
+
 // Rows is a mocked collection of rows to
 // return for Query result
 type Rows struct {