Added Filter, FilterRegexp and FilterPrefix
diff --git a/properties.go b/properties.go index a5aaa21..e9386fb 100644 --- a/properties.go +++ b/properties.go
@@ -12,6 +12,7 @@ "io" "log" "os" + "regexp" "strconv" "strings" "time" @@ -319,6 +320,41 @@ // ---------------------------------------------------------------------------- +// Filter returns a new properties object which contains all properties +// for which the key matches the pattern. +func (p *Properties) Filter(pattern string) (*Properties, error) { + re, err := regexp.Compile(pattern) + if err != nil { + return nil, err + } + + return p.FilterRegexp(re), nil +} + +// FilterRegexp returns a new properties object which contains all properties +// for which the key matches the regular expression. +func (p *Properties) FilterRegexp(re *regexp.Regexp) *Properties { + pp := NewProperties() + for k, v := range p.m { + if re.MatchString(k) { + pp.Set(k, v) + } + } + return pp +} + +// FilterPrefix returns a new properties object which contains all properties +// for which the key starts with the prefix. +func (p *Properties) FilterPrefix(prefix string) *Properties { + pp := NewProperties() + for k, v := range p.m { + if strings.HasPrefix(k, prefix) { + pp.Set(k, v) + } + } + return pp +} + // Len returns the number of keys. func (p *Properties) Len() int { return len(p.m)
diff --git a/properties_test.go b/properties_test.go index ef5ce2c..ba5d6be 100644 --- a/properties_test.go +++ b/properties_test.go
@@ -299,6 +299,53 @@ // ---------------------------------------------------------------------------- +type filterTest struct { + input string + pattern string + keys []string + err string +} + +var filterTests = []*filterTest{ + &filterTest{"", "", []string{}, ""}, + &filterTest{"", "abc", []string{}, ""}, + &filterTest{"key=value", "", []string{"key"}, ""}, + &filterTest{"key=value", "key=", []string{}, ""}, + &filterTest{"key=value\nfoo=bar", "", []string{"foo", "key"}, ""}, + &filterTest{"key=value\nfoo=bar", "f", []string{"foo"}, ""}, + &filterTest{"key=value\nfoo=bar", "fo", []string{"foo"}, ""}, + &filterTest{"key=value\nfoo=bar", "foo", []string{"foo"}, ""}, + &filterTest{"key=value\nfoo=bar", "fooo", []string{}, ""}, + &filterTest{"key=value\nkey2=value2\nfoo=bar", "ey", []string{"key", "key2"}, ""}, + &filterTest{"key=value\nkey2=value2\nfoo=bar", "key", []string{"key", "key2"}, ""}, + &filterTest{"key=value\nkey2=value2\nfoo=bar", "^key", []string{"key", "key2"}, ""}, + &filterTest{"key=value\nkey2=value2\nfoo=bar", "^(key|foo)", []string{"foo", "key", "key2"}, ""}, + &filterTest{"key=value\nkey2=value2\nfoo=bar", "[ abc", nil, "error parsing regexp.*"}, +} + +// ---------------------------------------------------------------------------- + +type filterPrefixTest struct { + input string + prefix string + keys []string +} + +var filterPrefixTests = []*filterPrefixTest{ + &filterPrefixTest{"", "", []string{}}, + &filterPrefixTest{"", "abc", []string{}}, + &filterPrefixTest{"key=value", "", []string{"key"}}, + &filterPrefixTest{"key=value", "key=", []string{}}, + &filterPrefixTest{"key=value\nfoo=bar", "", []string{"foo", "key"}}, + &filterPrefixTest{"key=value\nfoo=bar", "f", []string{"foo"}}, + &filterPrefixTest{"key=value\nfoo=bar", "fo", []string{"foo"}}, + &filterPrefixTest{"key=value\nfoo=bar", "foo", []string{"foo"}}, + &filterPrefixTest{"key=value\nfoo=bar", "fooo", []string{}}, + &filterPrefixTest{"key=value\nkey2=value2\nfoo=bar", "key", []string{"key", "key2"}}, +} + +// ---------------------------------------------------------------------------- + // TestBasic tests basic single key/value combinations with all possible // whitespace, delimiter and newline permutations. func (l *TestSuite) TestBasic(c *C) { @@ -470,6 +517,44 @@ c.Assert(func() { p.MustGetString("invalid") }, PanicMatches, "unknown property: invalid") } +func (l *TestSuite) TestFilter(c *C) { + for _, test := range filterTests { + p, err := parse(test.input) + c.Assert(err, IsNil) + pp, err := p.Filter(test.pattern) + if err != nil { + c.Assert(err, ErrorMatches, test.err) + continue + } + c.Assert(pp, NotNil) + c.Assert(pp.Len(), Equals, len(test.keys)) + for _, key := range test.keys { + v1, ok1 := p.Get(key) + v2, ok2 := pp.Get(key) + c.Assert(ok1, Equals, true) + c.Assert(ok2, Equals, true) + c.Assert(v1, Equals, v2) + } + } +} + +func (l *TestSuite) TestFilterPrefix(c *C) { + for _, test := range filterPrefixTests { + p, err := parse(test.input) + c.Assert(err, IsNil) + pp := p.FilterPrefix(test.prefix) + c.Assert(pp, NotNil) + c.Assert(pp.Len(), Equals, len(test.keys)) + for _, key := range test.keys { + v1, ok1 := p.Get(key) + v2, ok2 := pp.Get(key) + c.Assert(ok1, Equals, true) + c.Assert(ok2, Equals, true) + c.Assert(v1, Equals, v2) + } + } +} + func (l *TestSuite) TestKeys(c *C) { for _, test := range keysTests { p, err := parse(test.input)