| // Copyright 2017 The casbin Authors. All Rights Reserved. |
| // |
| // Licensed under the Apache License, Version 2.0 (the "License"); |
| // you may not use this file except in compliance with the License. |
| // You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, software |
| // distributed under the License is distributed on an "AS IS" BASIS, |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| // See the License for the specific language governing permissions and |
| // limitations under the License. |
| |
| package util |
| |
| import ( |
| "testing" |
| ) |
| |
| func testEscapeAssertion(t *testing.T, s string, res string) { |
| t.Helper() |
| myRes := EscapeAssertion(s) |
| t.Logf("%s: %s", s, myRes) |
| |
| if myRes != res { |
| t.Errorf("%s: %s, supposed to be %s", s, myRes, res) |
| } |
| } |
| |
| func TestEscapeAssertion(t *testing.T) { |
| testEscapeAssertion(t, "r_sub == r_obj.value", "r_sub == r_obj.value") |
| testEscapeAssertion(t, "p_sub == r_sub.value", "p_sub == r_sub.value") |
| testEscapeAssertion(t, "r.attr.value == p.attr", "r_attr.value == p_attr") |
| testEscapeAssertion(t, "r.attr.value == p.attr", "r_attr.value == p_attr") |
| testEscapeAssertion(t, "r.attp.value || p.attr", "r_attp.value || p_attr") |
| testEscapeAssertion(t, "r2.attr.value == p2.attr", "r2_attr.value == p2_attr") |
| testEscapeAssertion(t, "r2.attp.value || p2.attr", "r2_attp.value || p2_attr") |
| testEscapeAssertion(t, "r.attp.value &&p.attr", "r_attp.value &&p_attr") |
| testEscapeAssertion(t, "r.attp.value >p.attr", "r_attp.value >p_attr") |
| testEscapeAssertion(t, "r.attp.value <p.attr", "r_attp.value <p_attr") |
| testEscapeAssertion(t, "r.attp.value +p.attr", "r_attp.value +p_attr") |
| testEscapeAssertion(t, "r.attp.value -p.attr", "r_attp.value -p_attr") |
| testEscapeAssertion(t, "r.attp.value *p.attr", "r_attp.value *p_attr") |
| testEscapeAssertion(t, "r.attp.value /p.attr", "r_attp.value /p_attr") |
| testEscapeAssertion(t, "!r.attp.value /p.attr", "!r_attp.value /p_attr") |
| testEscapeAssertion(t, "g(r.sub, p.sub) == p.attr", "g(r_sub, p_sub) == p_attr") |
| testEscapeAssertion(t, "g(r.sub,p.sub) == p.attr", "g(r_sub,p_sub) == p_attr") |
| testEscapeAssertion(t, "(r.attp.value || p.attr)p.u", "(r_attp.value || p_attr)p_u") |
| // Test that patterns inside strings are not escaped |
| testEscapeAssertion(t, `r.sub == "a.p.p.l.e"`, `r_sub == "a.p.p.l.e"`) |
| testEscapeAssertion(t, `r.sub == "test.p.value"`, `r_sub == "test.p.value"`) |
| } |
| |
| func testRemoveComments(t *testing.T, s string, res string) { |
| t.Helper() |
| myRes := RemoveComments(s) |
| t.Logf("%s: %s", s, myRes) |
| |
| if myRes != res { |
| t.Errorf("%s: %s, supposed to be %s", s, myRes, res) |
| } |
| } |
| |
| func TestRemoveComments(t *testing.T) { |
| testRemoveComments(t, "r.act == p.act # comments", "r.act == p.act") |
| testRemoveComments(t, "r.act == p.act#comments", "r.act == p.act") |
| testRemoveComments(t, "r.act == p.act###", "r.act == p.act") |
| testRemoveComments(t, "### comments", "") |
| testRemoveComments(t, "r.act == p.act", "r.act == p.act") |
| } |
| |
| func testArrayEquals(t *testing.T, a []string, b []string, res bool) { |
| t.Helper() |
| myRes := ArrayEquals(a, b) |
| t.Logf("%s == %s: %t", a, b, myRes) |
| |
| if myRes != res { |
| t.Errorf("%s == %s: %t, supposed to be %t", a, b, myRes, res) |
| } |
| } |
| |
| func TestArrayEquals(t *testing.T) { |
| testArrayEquals(t, []string{"a", "b", "c"}, []string{"a", "b", "c"}, true) |
| testArrayEquals(t, []string{"a", "b", "c"}, []string{"a", "b"}, false) |
| testArrayEquals(t, []string{"a", "b", "c"}, []string{"a", "c", "b"}, false) |
| testArrayEquals(t, []string{"a", "b", "c"}, []string{}, false) |
| } |
| |
| func testArray2DEquals(t *testing.T, a [][]string, b [][]string, res bool) { |
| t.Helper() |
| myRes := Array2DEquals(a, b) |
| t.Logf("%s == %s: %t", a, b, myRes) |
| |
| if myRes != res { |
| t.Errorf("%s == %s: %t, supposed to be %t", a, b, myRes, res) |
| } |
| } |
| |
| func TestArray2DEquals(t *testing.T) { |
| testArray2DEquals(t, [][]string{{"a", "b", "c"}, {"1", "2", "3"}}, [][]string{{"a", "b", "c"}, {"1", "2", "3"}}, true) |
| testArray2DEquals(t, [][]string{{"a", "b", "c"}, {"1", "2", "3"}}, [][]string{{"a", "b", "c"}}, false) |
| testArray2DEquals(t, [][]string{{"a", "b", "c"}, {"1", "2", "3"}}, [][]string{{"a", "b", "c"}, {"1", "2"}}, false) |
| testArray2DEquals(t, [][]string{{"a", "b", "c"}, {"1", "2", "3"}}, [][]string{{"1", "2", "3"}, {"a", "b", "c"}}, false) |
| testArray2DEquals(t, [][]string{{"a", "b", "c"}, {"1", "2", "3"}}, [][]string{}, false) |
| } |
| |
| func testSetEquals(t *testing.T, a []string, b []string, res bool) { |
| t.Helper() |
| myRes := SetEquals(a, b) |
| t.Logf("%s == %s: %t", a, b, myRes) |
| |
| if myRes != res { |
| t.Errorf("%s == %s: %t, supposed to be %t", a, b, myRes, res) |
| } |
| } |
| |
| func TestSetEquals(t *testing.T) { |
| testSetEquals(t, []string{"a", "b", "c"}, []string{"a", "b", "c"}, true) |
| testSetEquals(t, []string{"a", "b", "c"}, []string{"a", "b"}, false) |
| testSetEquals(t, []string{"a", "b", "c"}, []string{"a", "c", "b"}, true) |
| testSetEquals(t, []string{"a", "b", "c"}, []string{}, false) |
| } |
| |
| func testContainEval(t *testing.T, s string, res bool) { |
| t.Helper() |
| myRes := HasEval(s) |
| if myRes != res { |
| t.Errorf("%s: %t, supposed to be %t", s, myRes, res) |
| } |
| } |
| func TestContainEval(t *testing.T) { |
| testContainEval(t, "eval() && a && b && c", true) |
| testContainEval(t, "eval) && a && b && c", false) |
| testContainEval(t, "eval)( && a && b && c", false) |
| testContainEval(t, "eval(c * (a + b)) && a && b && c", true) |
| testContainEval(t, "xeval() && a && b && c", false) |
| } |
| |
| func testReplaceEval(t *testing.T, s string, rule string, res string) { |
| t.Helper() |
| myRes := ReplaceEval(s, rule) |
| |
| if myRes != res { |
| t.Errorf("%s: %s supposed to be %s", s, myRes, res) |
| } |
| } |
| func TestReplaceEval(t *testing.T) { |
| testReplaceEval(t, "eval() && a && b && c", "a", "(a) && a && b && c") |
| testReplaceEval(t, "eval() && a && b && c", "(a)", "((a)) && a && b && c") |
| } |
| |
| func testGetEvalValue(t *testing.T, s string, res []string) { |
| t.Helper() |
| myRes := GetEvalValue(s) |
| |
| if !ArrayEquals(myRes, res) { |
| t.Errorf("%s: %s supposed to be %s", s, myRes, res) |
| } |
| } |
| |
| func TestGetEvalValue(t *testing.T) { |
| testGetEvalValue(t, "eval(a) && a && b && c", []string{"a"}) |
| testGetEvalValue(t, "a && eval(a) && b && c", []string{"a"}) |
| testGetEvalValue(t, "eval(a) && eval(b) && a && b && c", []string{"a", "b"}) |
| testGetEvalValue(t, "a && eval(a) && eval(b) && b && c", []string{"a", "b"}) |
| } |
| |
| func testReplaceEvalWithMap(t *testing.T, s string, sets map[string]string, res string) { |
| t.Helper() |
| myRes := ReplaceEvalWithMap(s, sets) |
| |
| if myRes != res { |
| t.Errorf("%s: %s supposed to be %s", s, myRes, res) |
| } |
| } |
| |
| func TestReplaceEvalWithMap(t *testing.T) { |
| testReplaceEvalWithMap(t, "eval(rule1)", map[string]string{"rule1": "a == b"}, "a == b") |
| testReplaceEvalWithMap(t, "eval(rule1) && c && d", map[string]string{"rule1": "a == b"}, "a == b && c && d") |
| testReplaceEvalWithMap(t, "eval(rule1)", nil, "eval(rule1)") |
| testReplaceEvalWithMap(t, "eval(rule1) && c && d", nil, "eval(rule1) && c && d") |
| testReplaceEvalWithMap(t, "eval(rule1) || eval(rule2)", map[string]string{"rule1": "a == b", "rule2": "a == c"}, "a == b || a == c") |
| testReplaceEvalWithMap(t, "eval(rule1) || eval(rule2) && c && d", map[string]string{"rule1": "a == b", "rule2": "a == c"}, "a == b || a == c && c && d") |
| testReplaceEvalWithMap(t, "eval(rule1) || eval(rule2)", map[string]string{"rule1": "a == b"}, "a == b || eval(rule2)") |
| testReplaceEvalWithMap(t, "eval(rule1) || eval(rule2) && c && d", map[string]string{"rule1": "a == b"}, "a == b || eval(rule2) && c && d") |
| testReplaceEvalWithMap(t, "eval(rule1) || eval(rule2)", map[string]string{"rule2": "a == b"}, "eval(rule1) || a == b") |
| testReplaceEvalWithMap(t, "eval(rule1) || eval(rule2) && c && d", map[string]string{"rule2": "a == b"}, "eval(rule1) || a == b && c && d") |
| testReplaceEvalWithMap(t, "eval(rule1) || eval(rule2)", nil, "eval(rule1) || eval(rule2)") |
| testReplaceEvalWithMap(t, "eval(rule1) || eval(rule2) && c && d", nil, "eval(rule1) || eval(rule2) && c && d") |
| } |
| |
| func testCacheGet(t *testing.T, c *LRUCache, key string, value interface{}, ok bool) { |
| v, o := c.Get(key) |
| if v != value || o != ok { |
| t.Errorf("Get(%s): (%s, %t) supposed to be (%s, %t)", key, v, o, value, ok) |
| } |
| } |
| |
| func testCachePut(t *testing.T, c *LRUCache, key string, value interface{}) { |
| c.Put(key, value) |
| v, o := c.Get(key) |
| if v != value || o != true { |
| t.Errorf("Put(%s, %s): didn't add value", key, value) |
| } |
| } |
| |
| func testCacheEqual(t *testing.T, c *LRUCache, values []int) { |
| cacheValues := []int{} |
| for _, v := range c.m { |
| cacheValues = append(cacheValues, v.value.(int)) |
| } |
| |
| if SetEqualsInt(values, cacheValues) == false { |
| t.Errorf("cache values: %d supposed to be %d", cacheValues, values) |
| } |
| } |
| |
| func TestLRUCache(t *testing.T) { |
| cache := NewLRUCache(3) |
| testCachePut(t, cache, "one", 1) |
| testCachePut(t, cache, "two", 2) |
| testCacheGet(t, cache, "one", 1, true) |
| testCachePut(t, cache, "three", 3) |
| testCachePut(t, cache, "four", 4) |
| testCacheGet(t, cache, "two", nil, false) |
| testCacheEqual(t, cache, []int{1, 3, 4}) |
| } |
| |
| func testEscapeStringLiterals(t *testing.T, input string, expected string) { |
| t.Helper() |
| result := EscapeStringLiterals(input) |
| t.Logf("Input: %q", input) |
| t.Logf("Expected: %q", expected) |
| t.Logf("Got: %q", result) |
| |
| if result != expected { |
| t.Errorf("EscapeStringLiterals(%q) = %q, expected %q", input, result, expected) |
| } |
| } |
| |
| func TestEscapeStringLiterals(t *testing.T) { |
| // Test single-quoted strings |
| testEscapeStringLiterals(t, `'\1\2'`, `'\\1\\2'`) |
| testEscapeStringLiterals(t, `'\n\t'`, `'\\n\\t'`) |
| testEscapeStringLiterals(t, `'\\already\\escaped'`, `'\\\\already\\\\escaped'`) |
| |
| // Test double-quoted strings |
| testEscapeStringLiterals(t, `"\1\2"`, `"\\1\\2"`) |
| testEscapeStringLiterals(t, `"\n\t"`, `"\\n\\t"`) |
| |
| // Test expressions with string literals |
| testEscapeStringLiterals(t, `regexMatch('\1\2', p.obj)`, `regexMatch('\\1\\2', p.obj)`) |
| testEscapeStringLiterals(t, `regexMatch("\1\2", p.obj)`, `regexMatch("\\1\\2", p.obj)`) |
| testEscapeStringLiterals(t, `r.sub == '\test'`, `r.sub == '\\test'`) |
| |
| // Test expressions without string literals |
| testEscapeStringLiterals(t, `r.sub == p.sub`, `r.sub == p.sub`) |
| testEscapeStringLiterals(t, `keyMatch(r.obj, p.obj)`, `keyMatch(r.obj, p.obj)`) |
| |
| // Test multiple strings in one expression |
| testEscapeStringLiterals(t, `regexMatch('\1', '\2')`, `regexMatch('\\1', '\\2')`) |
| |
| // Test empty strings |
| testEscapeStringLiterals(t, `''`, `''`) |
| testEscapeStringLiterals(t, `""`, `""`) |
| |
| // Test strings with no backslashes |
| testEscapeStringLiterals(t, `'hello'`, `'hello'`) |
| testEscapeStringLiterals(t, `"world"`, `"world"`) |
| } |