Repository: diegoholiveira/jsonlogic (go)

Issue:
max/min logic is incorrect
Max starts with "SmallestNonzeroFloat64" which is the smallest positive, non-zero value. So max:[0,0], max:[-1,0], max:[-3,-2] and etc. will all get incorrect answer. Also, min is correctly start with maximum value but min:[] return very large number make no sense. It should return null or error *spec in jsonlogic website return null for empty or if it contains not-numeric-castable.
So I think you should start with first found number. Then compare following number with the first one, not some made-up value. Return null for  not-numeric-castable/empty input if want to follow jsonlogic.

Pull request:
Use the first value when min / max
close #71 

Patch:
diff --git a/jsonlogic.go b/jsonlogic.go
index bd5c676..babe7f8 100644
--- a/jsonlogic.go
+++ b/jsonlogic.go
@@ -4,7 +4,6 @@ import (
 	"encoding/json"
 	"fmt"
 	"io"
-	"math"
 	"sort"
 	"strings"
 
@@ -195,10 +194,16 @@ func _in(value interface{}, values interface{}) bool {
 }
 
 func max(values interface{}) interface{} {
-	bigger := math.SmallestNonzeroFloat64
+	converted := values.([]interface{})
+	size := len(converted)
+	if size == 0 {
+		return nil
+	}
+
+	bigger := toNumber(converted[0])
 
-	for _, n := range values.([]interface{}) {
-		_n := toNumber(n)
+	for i := 1; i < size; i++ {
+		_n := toNumber(converted[i])
 		if _n > bigger {
 			bigger = _n
 		}
@@ -208,10 +213,16 @@ func max(values interface{}) interface{} {
 }
 
 func min(values interface{}) interface{} {
-	smallest := math.MaxFloat64
+	converted := values.([]interface{})
+	size := len(converted)
+	if size == 0 {
+		return nil
+	}
+
+	smallest := toNumber(converted[0])
 
-	for _, n := range values.([]interface{}) {
-		_n := toNumber(n)
+	for i := 1; i < size; i++ {
+		_n := toNumber(converted[i])
 		if smallest > _n {
 			smallest = _n
 		}


Test patch:
diff --git a/jsonlogic_test.go b/jsonlogic_test.go
index 1747f23..07b0b02 100644
--- a/jsonlogic_test.go
+++ b/jsonlogic_test.go
@@ -741,6 +741,48 @@ func TestIssue58_example(t *testing.T) {
 	assert.JSONEq(t, expected, result.String())
 }
 
+func TestIssue71_example_empty_min(t *testing.T) {
+	data := strings.NewReader(`{}`)
+	logic := strings.NewReader(`{"min":[]}`)
+
+	var result bytes.Buffer
+	err := Apply(logic, data, &result)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	expected := `null`
+	assert.JSONEq(t, expected, result.String())
+}
+
+func TestIssue71_example_empty_max(t *testing.T) {
+	data := strings.NewReader(`{}`)
+	logic := strings.NewReader(`{"max":[]}`)
+
+	var result bytes.Buffer
+	err := Apply(logic, data, &result)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	expected := `null`
+	assert.JSONEq(t, expected, result.String())
+}
+
+func TestIssue71_example_max(t *testing.T) {
+	data := strings.NewReader(`{}`)
+	logic := strings.NewReader(`{"max":[-3, -2]}`)
+
+	var result bytes.Buffer
+	err := Apply(logic, data, &result)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	expected := `-2`
+	assert.JSONEq(t, expected, result.String())
+}
+
 func TestJsonLogicWithSolvedVars(t *testing.T) {
 	rule := json.RawMessage(`{
 		"or":[