Repository: casbin/casbin
Pull request #818 (2021-06-15 14:20:24)

fix: matcher function lost
Signed-off-by: closetool <c299999999@qq.com>

Fix: #817 

nodece: @closetool can you add a test for this change?
closetool: @nodece Sure
closetool: @nodece Added, plz review
hsluoyz: @nodece @closetool https://github.com/casbin/casbin/pull/819 is merged, is this PR still useful?
closetool: @hsluoyz Yeap, Model.ToText() still have a bug to fix.

Patch:
diff --git a/log/mocks/mock_logger.go b/log/mocks/mock_logger.go
index 49d5347..4fd438d 100644
--- a/log/mocks/mock_logger.go
+++ b/log/mocks/mock_logger.go
@@ -5,8 +5,9 @@
 package mocks
 
 import (
-	gomock "github.com/golang/mock/gomock"
 	reflect "reflect"
+
+	gomock "github.com/golang/mock/gomock"
 )
 
 // MockLogger is a mock of Logger interface
diff --git a/model/model.go b/model/model.go
index f90945e..06738a6 100644
--- a/model/model.go
+++ b/model/model.go
@@ -248,10 +248,21 @@ func (model Model) SortPoliciesByPriority() error {
 }
 
 func (model Model) ToText() string {
+	tokenPatterns := make(map[string]string)
+
+	for _, ptype := range []string{"r", "p"} {
+		for _, token := range model[ptype][ptype].Tokens {
+			tokenPatterns[token] = strings.Replace(token, "_", ".", -1)
+		}
+	}
 	s := strings.Builder{}
 	writeString := func(sec string) {
 		for ptype := range model[sec] {
-			s.WriteString(fmt.Sprintf("%s = %s\n", ptype, strings.Replace(model[sec][ptype].Value, "_", ".", -1)))
+			value := model[sec][ptype].Value
+			for tokenPattern, newToken := range tokenPatterns {
+				value = strings.Replace(value, tokenPattern, newToken, -1)
+			}
+			s.WriteString(fmt.Sprintf("%s = %s\n", sec, value))
 		}
 	}
 	s.WriteString("[request_definition]\n")


Test patch:
diff --git a/model/model_test.go b/model/model_test.go
index 7700118..d64595c 100644
--- a/model/model_test.go
+++ b/model/model_test.go
@@ -148,3 +148,38 @@ func TestModel_CopyTo(t *testing.T) {
 		t.Fatal(`the a["p"]["p"] and b["p"]["p"] should not be equal`)
 	}
 }
+
+func TestModelToTest(t *testing.T) {
+	testModelToText(t, "r.sub == p.sub && r.obj == p.obj && r_func(r.act, p.act) && testr_func(r.act, p.act)", "r_sub == p_sub && r_obj == p_obj && r_func(r_act, p_act) && testr_func(r_act, p_act)")
+	testModelToText(t, "r.sub == p.sub && r.obj == p.obj && p_func(r.act, p.act) && testp_func(r.act, p.act)", "r_sub == p_sub && r_obj == p_obj && p_func(r_act, p_act) && testp_func(r_act, p_act)")
+}
+
+func testModelToText(t *testing.T, mData, mExpected string) {
+	m := NewModel()
+	data := map[string]string{
+		"r": "sub, obj, act",
+		"p": "sub, obj, act",
+		"e": "some(where (p.eft == allow))",
+		"m": mData,
+	}
+	expected := map[string]string{
+		"r": "sub, obj, act",
+		"p": "sub, obj, act",
+		"e": "some(where (p_eft == allow))",
+		"m": mExpected,
+	}
+	addData := func(ptype string) {
+		m.AddDef(ptype, ptype, data[ptype])
+	}
+	for ptype := range data {
+		addData(ptype)
+	}
+	newM := NewModel()
+	print(m.ToText())
+	_ = newM.LoadModelFromText(m.ToText())
+	for ptype := range data {
+		if newM[ptype][ptype].Value != expected[ptype] {
+			t.Errorf("\"%s\" assertion value changed, current value: %s, it should be: %s", ptype, newM[ptype][ptype].Value, expected[ptype])
+		}
+	}
+}