machine_tag 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +17 -0
- data/.rspec +2 -0
- data/.travis.yml +4 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +89 -0
- data/Rakefile +8 -0
- data/lib/machine_tag.rb +26 -0
- data/lib/machine_tag/set.rb +113 -0
- data/lib/machine_tag/tag.rb +112 -0
- data/lib/machine_tag/version.rb +30 -0
- data/machine_tag.gemspec +27 -0
- data/spec/machine_tag_set_spec.rb +71 -0
- data/spec/machine_tag_spec.rb +7 -0
- data/spec/machine_tag_tag_spec.rb +57 -0
- data/spec/spec_helper.rb +2 -0
- metadata +163 -0
data/.gitignore
ADDED
data/.rspec
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2013 Douglas Thrift
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,89 @@
|
|
1
|
+
# MachineTag
|
2
|
+
|
3
|
+
[](http://badge.fury.io/rb/machine_tag)
|
4
|
+
[](https://travis-ci.org/douglaswth/machine_tag)
|
5
|
+
[](https://gemnasium.com/douglaswth/machine_tag)
|
6
|
+
|
7
|
+
MachineTag is a Ruby library for using machine tags like those used on [Flickr] and [RightScale].
|
8
|
+
|
9
|
+
[Flickr]: http://www.flickr.com/help/tags/#613430
|
10
|
+
[RightScale]: http://support.rightscale.com/12-Guides/RightScale_101/06-Advanced_Concepts/Tagging
|
11
|
+
|
12
|
+
## Installation
|
13
|
+
|
14
|
+
Add this line to your application's Gemfile:
|
15
|
+
|
16
|
+
gem 'machine_tag'
|
17
|
+
|
18
|
+
And then execute:
|
19
|
+
|
20
|
+
$ bundle
|
21
|
+
|
22
|
+
Or install it yourself as:
|
23
|
+
|
24
|
+
$ gem install machine_tag
|
25
|
+
|
26
|
+
## Usage
|
27
|
+
|
28
|
+
MachineTag provides two classes for dealing with machine tags and tags in general: `MachineTag::Tag`
|
29
|
+
and `MachineTag::Set`:
|
30
|
+
|
31
|
+
### MachineTag::Tag
|
32
|
+
|
33
|
+
The MachineTag::Tag class represents a tag which can either be a machine tag or a plain tag. It
|
34
|
+
inherits from [String] so it can be used in the same ways.
|
35
|
+
|
36
|
+
[String]: http://ruby-doc.org/core-1.9.3/String.html
|
37
|
+
|
38
|
+
```ruby
|
39
|
+
plain_tag = MachineTag::Tag.new('geotagged')
|
40
|
+
|
41
|
+
plain_tag == 'geotagged' # => true
|
42
|
+
plain_tag.machine_tag? # => false
|
43
|
+
|
44
|
+
machine_tag = MachineTag::Tag.new('geo:lat=34.4348067')
|
45
|
+
|
46
|
+
machine_tag == 'geo:lat=34.4348067' # => true
|
47
|
+
machine_tag.machine_tag? # => true
|
48
|
+
machine_tag.namespace # => "geo"
|
49
|
+
machine_tag.predicate # => "lat"
|
50
|
+
machine_tag.namespace_and_predicate # => "geo:lat"
|
51
|
+
machine_tag.value.to_f # => 34.4348067
|
52
|
+
|
53
|
+
machine_tag = MachineTag::Tag.machine_tag('geo', 'lon', -119.8016962)
|
54
|
+
|
55
|
+
machine_tag == 'geo:lon=-119.8016962' # => true
|
56
|
+
machine_tag.machine_tag? # => true
|
57
|
+
```
|
58
|
+
|
59
|
+
### MachineTag::Set
|
60
|
+
|
61
|
+
The `MachineTag::Set` class represents a set of tags and provides a way of looking them up by
|
62
|
+
namespace or by namespace and predicate. It inherits from the [Set] so it can be used in the same
|
63
|
+
ways. If `String` objects are passed into it they will automatically be converted to
|
64
|
+
`MachineTag::Tag` objects.
|
65
|
+
|
66
|
+
[Set]: http://ruby-doc.org/stdlib-1.9.3/libdoc/set/rdoc/Set.html
|
67
|
+
|
68
|
+
```ruby
|
69
|
+
tags = MachineTag::Set['geotagged', 'geo:lat=34.4348067', 'geo:lon=-119.8016962']
|
70
|
+
|
71
|
+
tags.include?('geotagged') # => true
|
72
|
+
tags.plain_tags # => #<Set: {"geotagged"}>
|
73
|
+
tags.machine_tags # => #<Set: {"geo:lat=34.4348067", "geo:lon=-119.8016962"}>
|
74
|
+
tags['geo'] # => #<Set: {"geo:lat=34.4348067", "geo:lon=-119.8016962"}>
|
75
|
+
tags['geo:lat'] # => #<Set: {"geo:lat=34.4348067"}>
|
76
|
+
tags['geo', 'lon'] # => #<Set: {"geo:lon=-119.8016962"}>
|
77
|
+
```
|
78
|
+
|
79
|
+
More information can be found in the [documentation].
|
80
|
+
|
81
|
+
[documentation]: http://rubydoc.info/gems/machine_tag/frame
|
82
|
+
|
83
|
+
## Contributing
|
84
|
+
|
85
|
+
1. Fork it
|
86
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
87
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
88
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
89
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
data/lib/machine_tag.rb
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
# Copyright (c) 2013 Douglas Thrift
|
2
|
+
#
|
3
|
+
# MIT License
|
4
|
+
#
|
5
|
+
# Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
# a copy of this software and associated documentation files (the
|
7
|
+
# "Software"), to deal in the Software without restriction, including
|
8
|
+
# without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
# distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
# permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
# the following conditions:
|
12
|
+
#
|
13
|
+
# The above copyright notice and this permission notice shall be
|
14
|
+
# included in all copies or substantial portions of the Software.
|
15
|
+
#
|
16
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
23
|
+
|
24
|
+
require "machine_tag/version"
|
25
|
+
require "machine_tag/tag"
|
26
|
+
require "machine_tag/set"
|
@@ -0,0 +1,113 @@
|
|
1
|
+
# Copyright (c) 2013 Douglas Thrift
|
2
|
+
#
|
3
|
+
# MIT License
|
4
|
+
#
|
5
|
+
# Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
# a copy of this software and associated documentation files (the
|
7
|
+
# "Software"), to deal in the Software without restriction, including
|
8
|
+
# without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
# distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
# permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
# the following conditions:
|
12
|
+
#
|
13
|
+
# The above copyright notice and this permission notice shall be
|
14
|
+
# included in all copies or substantial portions of the Software.
|
15
|
+
#
|
16
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
23
|
+
|
24
|
+
require 'set'
|
25
|
+
|
26
|
+
module MachineTag
|
27
|
+
# Set of tags which can be machine tags.
|
28
|
+
#
|
29
|
+
class Set < ::Set
|
30
|
+
# The tags in the set which are not machine tags
|
31
|
+
#
|
32
|
+
# @return [::Set<Tag>] the tags in the set which are not machine tags
|
33
|
+
#
|
34
|
+
attr_reader :plain_tags
|
35
|
+
|
36
|
+
# The tags in the set which are machine tags
|
37
|
+
#
|
38
|
+
# @return [::Set<Tag>] the tags in the set which are machine tags
|
39
|
+
#
|
40
|
+
attr_reader :machine_tags
|
41
|
+
|
42
|
+
# Creates a set of tags which can be machine tags. If String objects are passed in they will be
|
43
|
+
# converted to {Tag}.
|
44
|
+
#
|
45
|
+
# @param enum [Enumerable<Tag, String>, nil] the enumerable object of tags
|
46
|
+
# @param block [Proc] the optional block to preprocess elements before inserting them
|
47
|
+
#
|
48
|
+
def initialize(enum = nil, &block)
|
49
|
+
@plain_tags = ::Set.new
|
50
|
+
@machine_tags = ::Set.new
|
51
|
+
@tags_by_namespace = {}
|
52
|
+
@tags_by_namespace_and_predicate = {}
|
53
|
+
super
|
54
|
+
end
|
55
|
+
|
56
|
+
# Adds a tag to the set of tags. If a String object is passed in it will be converted to {Tag}.
|
57
|
+
#
|
58
|
+
# @param tag [Tag, String] the tag or string to add
|
59
|
+
#
|
60
|
+
# @return [Set] the tag set
|
61
|
+
#
|
62
|
+
def add(tag)
|
63
|
+
tag = Tag.new(tag) unless tag.is_a? Tag
|
64
|
+
super(tag)
|
65
|
+
|
66
|
+
if tag.machine_tag?
|
67
|
+
@machine_tags << tag
|
68
|
+
@tags_by_namespace[tag.namespace] ||= ::Set.new
|
69
|
+
@tags_by_namespace[tag.namespace] << tag
|
70
|
+
@tags_by_namespace_and_predicate[tag.namespace_and_predicate] ||= ::Set.new
|
71
|
+
@tags_by_namespace_and_predicate[tag.namespace_and_predicate] << tag
|
72
|
+
else
|
73
|
+
@plain_tags << tag
|
74
|
+
end
|
75
|
+
|
76
|
+
self
|
77
|
+
end
|
78
|
+
alias_method :<<, :add
|
79
|
+
|
80
|
+
# Retrieves machine tags in the Set with a matching namespace or namespace and predicate.
|
81
|
+
#
|
82
|
+
# @example
|
83
|
+
# tags = MachineTag::Set['a:b=x', 'a:b=y', 'a:c=z']
|
84
|
+
# tags['a'] # => #<Set: {"a:b=x", "a:b=y", "a:c=z"}>
|
85
|
+
# tags['a', 'b'] # => #<Set: {"a:b=x", "a:b=y"}>
|
86
|
+
# tags['a:c'] # => #<Set: {"a:c=z"}>
|
87
|
+
#
|
88
|
+
# @param namespace_or_namespace_and_predicate [String] the namespace to retrieve or the namespace
|
89
|
+
# and predicate to retreive combined in a string separated by +':'+
|
90
|
+
# @param predicate [String, nil] the predicate to retreive
|
91
|
+
#
|
92
|
+
# @return [::Set<Tag>] the machines tags that have the given namespace or namespace and predicate
|
93
|
+
#
|
94
|
+
def [](namespace_or_namespace_and_predicate, predicate = nil)
|
95
|
+
if namespace_or_namespace_and_predicate =~ /^#{PREFIX}$/
|
96
|
+
namespace = namespace_or_namespace_and_predicate
|
97
|
+
|
98
|
+
unless predicate
|
99
|
+
@tags_by_namespace[namespace]
|
100
|
+
else
|
101
|
+
raise ArgumentError, "Invalid machine tag predicate: #{predicate.inspect}" unless predicate =~ /^#{PREFIX}$/
|
102
|
+
@tags_by_namespace_and_predicate["#{namespace}:#{predicate}"]
|
103
|
+
end
|
104
|
+
elsif namespace_or_namespace_and_predicate =~ /^#{NAMESPACE_AND_PREDICATE}$/
|
105
|
+
namespace_and_predicate = namespace_or_namespace_and_predicate
|
106
|
+
raise ArgumentError, "Separate predicate passed with namespace and predicate: #{namespace_and_predicate.inspect}, #{predicate.inspect}" if predicate
|
107
|
+
@tags_by_namespace_and_predicate[namespace_and_predicate]
|
108
|
+
else
|
109
|
+
raise ArgumentError, "Invalid machine tag namespace and/or predicate: #{namespace_or_namespace_and_predicate.inspect}, #{predicate.inspect}"
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
113
|
+
end
|
@@ -0,0 +1,112 @@
|
|
1
|
+
# Copyright (c) 2013 Douglas Thrift
|
2
|
+
#
|
3
|
+
# MIT License
|
4
|
+
#
|
5
|
+
# Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
# a copy of this software and associated documentation files (the
|
7
|
+
# "Software"), to deal in the Software without restriction, including
|
8
|
+
# without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
# distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
# permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
# the following conditions:
|
12
|
+
#
|
13
|
+
# The above copyright notice and this permission notice shall be
|
14
|
+
# included in all copies or substantial portions of the Software.
|
15
|
+
#
|
16
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
23
|
+
|
24
|
+
module MachineTag
|
25
|
+
# The regular expression for matching the individual namespace and predicate portions of a machine tag
|
26
|
+
#
|
27
|
+
# @return [Regexp] the regular expression for matching the individual namespace and predicate
|
28
|
+
# portions of a machine tag
|
29
|
+
#
|
30
|
+
PREFIX = /[a-z][a-z0-9_]*/i
|
31
|
+
|
32
|
+
# The regular expression for matching the namespace and predicate portion of a machine tag
|
33
|
+
#
|
34
|
+
# @return [Regexp] the regular expression for matching the namespace and predicate portion of a machine tag
|
35
|
+
#
|
36
|
+
NAMESPACE_AND_PREDICATE = /(?<namespace>#{PREFIX}):(?<predicate>#{PREFIX})/
|
37
|
+
|
38
|
+
# The regular expression for matching a machine tag
|
39
|
+
#
|
40
|
+
# @return [Regexp] the regular expression for matching a machine tag
|
41
|
+
#
|
42
|
+
MACHINE_TAG = /^(?<namespace_and_predicate>#{NAMESPACE_AND_PREDICATE})=(?<value>.*)$/
|
43
|
+
|
44
|
+
# A tag which can be a machine tag.
|
45
|
+
#
|
46
|
+
class Tag < String
|
47
|
+
# The namespace portion of the machine tag, +nil+ if the tag is not a machine tag
|
48
|
+
#
|
49
|
+
# @return [String, nil] the namespace portion of the machine tag, +nil+ if the tag is not a machine tag
|
50
|
+
#
|
51
|
+
attr_reader :namespace
|
52
|
+
|
53
|
+
# The predicate portion of the machine tag, +nil+ if the tag is not a machine tag
|
54
|
+
#
|
55
|
+
# @return [String, nil] the predicate portion of the machine tag, +nil+ if the tag is not a machine tag
|
56
|
+
#
|
57
|
+
attr_reader :predicate
|
58
|
+
|
59
|
+
# The namespace and predicate portion of the machine tag, +nil+ if the tag is not a machine tag
|
60
|
+
#
|
61
|
+
# @return [String, nil] the namespace and predicate portion of the machine tag, +nil+ if the tag
|
62
|
+
# is not a machine tag
|
63
|
+
#
|
64
|
+
attr_reader :namespace_and_predicate
|
65
|
+
|
66
|
+
# The value portion of the machine tag, +nil+ if the tag is not a machine tag
|
67
|
+
#
|
68
|
+
# @return [String, nil] the value portion of the machine tag is not a machine tag
|
69
|
+
#
|
70
|
+
attr_reader :value
|
71
|
+
|
72
|
+
# Creates a tag object which can be a machine tag.
|
73
|
+
#
|
74
|
+
# @param str [String] the tag string
|
75
|
+
#
|
76
|
+
def initialize(str)
|
77
|
+
super
|
78
|
+
if match = self.match(MACHINE_TAG)
|
79
|
+
@namespace_and_predicate = match[:namespace_and_predicate]
|
80
|
+
@namespace = match[:namespace]
|
81
|
+
@predicate = match[:predicate]
|
82
|
+
@value = match[:value]
|
83
|
+
@value = $1 if @value =~ /^"(.*)"$/
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
# Creates a machine tag from a given namespace, predicate, and value.
|
88
|
+
#
|
89
|
+
# @param namespace [String] the namespace
|
90
|
+
# @param predicate [String] the predicate
|
91
|
+
# @param value [String, #to_s] the value
|
92
|
+
#
|
93
|
+
# @return [Tag] the machine tag
|
94
|
+
#
|
95
|
+
# @raise [ArgumentError] if the +namespace+ or +predicate+ are not in the correct format
|
96
|
+
#
|
97
|
+
def self.machine_tag(namespace, predicate, value)
|
98
|
+
raise ArgumentError, "Invalid machine tag namespace: #{namespace.inspect}" unless namespace =~ /^#{PREFIX}$/
|
99
|
+
raise ArgumentError, "Invalid machine tag predicate: #{predicate.inspect}" unless predicate =~ /^#{PREFIX}$/
|
100
|
+
|
101
|
+
new("#{namespace}:#{predicate}=#{value}")
|
102
|
+
end
|
103
|
+
|
104
|
+
# Returns whether this tag is a machine tag or not.
|
105
|
+
#
|
106
|
+
# @return [Boolean] +true+ if this tag is a machine tag, otherwise +false+
|
107
|
+
#
|
108
|
+
def machine_tag?
|
109
|
+
!!namespace
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# Copyright (c) 2013 Douglas Thrift
|
2
|
+
#
|
3
|
+
# MIT License
|
4
|
+
#
|
5
|
+
# Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
# a copy of this software and associated documentation files (the
|
7
|
+
# "Software"), to deal in the Software without restriction, including
|
8
|
+
# without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
# distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
# permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
# the following conditions:
|
12
|
+
#
|
13
|
+
# The above copyright notice and this permission notice shall be
|
14
|
+
# included in all copies or substantial portions of the Software.
|
15
|
+
#
|
16
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
23
|
+
|
24
|
+
# Library for using Machine Tags.
|
25
|
+
#
|
26
|
+
module MachineTag
|
27
|
+
# The version of this library.
|
28
|
+
#
|
29
|
+
VERSION = "1.0.0"
|
30
|
+
end
|
data/machine_tag.gemspec
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'machine_tag/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "machine_tag"
|
8
|
+
spec.version = MachineTag::VERSION
|
9
|
+
spec.authors = ["Douglas Thrift"]
|
10
|
+
spec.email = ["douglas@douglasthrift.net"]
|
11
|
+
spec.description = %q{A Ruby library for using machine tags like those used on Flickr and RightScale}
|
12
|
+
spec.summary = %q{Library for using machine tags}
|
13
|
+
spec.homepage = "https://github.com/douglaswth/machine_tag"
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files`.split($/)
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_development_dependency "bundler", "~> 1.3"
|
22
|
+
spec.add_development_dependency "rake"
|
23
|
+
spec.add_development_dependency "rdoc"
|
24
|
+
spec.add_development_dependency "redcarpet"
|
25
|
+
spec.add_development_dependency "rspec"
|
26
|
+
spec.add_development_dependency "yard", "~> 0.8.7.2"
|
27
|
+
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe MachineTag::Set do
|
4
|
+
it 'should create sets with plain tags' do
|
5
|
+
tags = MachineTag::Set['a', 'b', 'c']
|
6
|
+
tags.should eq Set['a', 'b', 'c']
|
7
|
+
tags.plain_tags.should eq Set['a', 'b', 'c']
|
8
|
+
tags.machine_tags.should be_empty
|
9
|
+
end
|
10
|
+
|
11
|
+
it 'should create sets with machine tags' do
|
12
|
+
tags = MachineTag::Set['a:b=x', 'a:b=y', 'a:c=z', 'd:e=f']
|
13
|
+
tags.should eq Set['a:b=x', 'a:b=y', 'a:c=z', 'd:e=f']
|
14
|
+
tags.plain_tags.should be_empty
|
15
|
+
tags.machine_tags.should eq Set['a:b=x', 'a:b=y', 'a:c=z', 'd:e=f']
|
16
|
+
tags['a'].should eq Set['a:b=x', 'a:b=y', 'a:c=z']
|
17
|
+
tags['a:b'].should eq Set['a:b=x', 'a:b=y']
|
18
|
+
tags['a', 'c'].should eq Set['a:c=z']
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'should create sets with mixed plain and machine tags' do
|
22
|
+
tags = MachineTag::Set['a:b=x', 'a:b=y', 'a:c=z', 'd', 'e', 'f']
|
23
|
+
tags.should eq Set['a:b=x', 'a:b=y', 'a:c=z', 'd', 'e', 'f']
|
24
|
+
tags.plain_tags.should eq Set['d', 'e', 'f']
|
25
|
+
tags.machine_tags.should eq Set['a:b=x', 'a:b=y', 'a:c=z']
|
26
|
+
tags['a'].should eq Set['a:b=x', 'a:b=y', 'a:c=z']
|
27
|
+
tags['a:b'].should eq Set['a:b=x', 'a:b=y']
|
28
|
+
tags['a', 'c'].should eq Set['a:c=z']
|
29
|
+
end
|
30
|
+
|
31
|
+
describe '#add' do
|
32
|
+
let(:tags) { MachineTag::Set.new }
|
33
|
+
|
34
|
+
it 'should add strings' do
|
35
|
+
tags << 'a'
|
36
|
+
tags.first.should be_an_instance_of(MachineTag::Tag)
|
37
|
+
end
|
38
|
+
|
39
|
+
it 'should add tags' do
|
40
|
+
tag = MachineTag::Tag.new('a')
|
41
|
+
tags << tag
|
42
|
+
tags.first.should be(tag)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
describe '#[]' do
|
47
|
+
let(:tags) { MachineTag::Set.new }
|
48
|
+
|
49
|
+
it 'should not retrieve with an invalid predicate' do
|
50
|
+
expect do
|
51
|
+
tags['a', '!']
|
52
|
+
end.to raise_error(ArgumentError, 'Invalid machine tag predicate: "!"')
|
53
|
+
end
|
54
|
+
|
55
|
+
it 'should not retrieve with a combined namespace and predicate and a predicate' do
|
56
|
+
expect do
|
57
|
+
tags['a:b', 'c']
|
58
|
+
end.to raise_error(ArgumentError, 'Separate predicate passed with namespace and predicate: "a:b", "c"')
|
59
|
+
end
|
60
|
+
|
61
|
+
it 'should not retreive with an invalid namespace and/or predicate' do
|
62
|
+
expect do
|
63
|
+
tags['!']
|
64
|
+
end.to raise_error(ArgumentError, 'Invalid machine tag namespace and/or predicate: "!", nil')
|
65
|
+
|
66
|
+
expect do
|
67
|
+
tags['a:!']
|
68
|
+
end.to raise_error(ArgumentError, 'Invalid machine tag namespace and/or predicate: "a:!", nil')
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe MachineTag::Tag do
|
4
|
+
it 'should create plain tags' do
|
5
|
+
tag = MachineTag::Tag.new('a')
|
6
|
+
tag.should eq 'a'
|
7
|
+
tag.namespace.should be_nil
|
8
|
+
tag.predicate.should be_nil
|
9
|
+
tag.namespace_and_predicate.should be_nil
|
10
|
+
tag.value.should be_nil
|
11
|
+
tag.machine_tag?.should be_false
|
12
|
+
end
|
13
|
+
|
14
|
+
it 'should create machine tags' do
|
15
|
+
tag = MachineTag::Tag.new('a:b=c')
|
16
|
+
tag.should eq 'a:b=c'
|
17
|
+
tag.namespace.should eq 'a'
|
18
|
+
tag.predicate.should eq 'b'
|
19
|
+
tag.namespace_and_predicate.should eq 'a:b'
|
20
|
+
tag.value.should eq 'c'
|
21
|
+
tag.machine_tag?.should be_true
|
22
|
+
end
|
23
|
+
|
24
|
+
it 'should handle a machine tag with a quoted value' do
|
25
|
+
tag = MachineTag::Tag.new('a:b="c d"')
|
26
|
+
tag.should eq 'a:b="c d"'
|
27
|
+
tag.namespace.should eq 'a'
|
28
|
+
tag.predicate.should eq 'b'
|
29
|
+
tag.namespace_and_predicate.should eq 'a:b'
|
30
|
+
tag.value.should eq 'c d'
|
31
|
+
tag.machine_tag?.should be_true
|
32
|
+
end
|
33
|
+
|
34
|
+
describe '::machine_tag' do
|
35
|
+
it 'should create machine tags' do
|
36
|
+
tag = MachineTag::Tag.machine_tag('a', 'b', 'c')
|
37
|
+
tag.should eq 'a:b=c'
|
38
|
+
tag.namespace.should eq 'a'
|
39
|
+
tag.predicate.should eq 'b'
|
40
|
+
tag.namespace_and_predicate.should eq 'a:b'
|
41
|
+
tag.value.should eq 'c'
|
42
|
+
tag.machine_tag?.should be_true
|
43
|
+
end
|
44
|
+
|
45
|
+
it 'should not create machine tags with invalid namespaces' do
|
46
|
+
expect do
|
47
|
+
MachineTag::Tag.machine_tag('!', 'b', 'c')
|
48
|
+
end.to raise_error(ArgumentError, 'Invalid machine tag namespace: "!"')
|
49
|
+
end
|
50
|
+
|
51
|
+
it 'should not create machine tags with invalid predicates' do
|
52
|
+
expect do
|
53
|
+
MachineTag::Tag.machine_tag('a', '!', 'c')
|
54
|
+
end.to raise_error(ArgumentError, 'Invalid machine tag predicate: "!"')
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
data/spec/spec_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,163 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: machine_tag
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.0.0
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Douglas Thrift
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2013-11-16 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: bundler
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ~>
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '1.3'
|
22
|
+
type: :development
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ~>
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '1.3'
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: rake
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ! '>='
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '0'
|
38
|
+
type: :development
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '0'
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: rdoc
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ! '>='
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '0'
|
54
|
+
type: :development
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ! '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
- !ruby/object:Gem::Dependency
|
63
|
+
name: redcarpet
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
66
|
+
requirements:
|
67
|
+
- - ! '>='
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '0'
|
70
|
+
type: :development
|
71
|
+
prerelease: false
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ! '>='
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '0'
|
78
|
+
- !ruby/object:Gem::Dependency
|
79
|
+
name: rspec
|
80
|
+
requirement: !ruby/object:Gem::Requirement
|
81
|
+
none: false
|
82
|
+
requirements:
|
83
|
+
- - ! '>='
|
84
|
+
- !ruby/object:Gem::Version
|
85
|
+
version: '0'
|
86
|
+
type: :development
|
87
|
+
prerelease: false
|
88
|
+
version_requirements: !ruby/object:Gem::Requirement
|
89
|
+
none: false
|
90
|
+
requirements:
|
91
|
+
- - ! '>='
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: '0'
|
94
|
+
- !ruby/object:Gem::Dependency
|
95
|
+
name: yard
|
96
|
+
requirement: !ruby/object:Gem::Requirement
|
97
|
+
none: false
|
98
|
+
requirements:
|
99
|
+
- - ~>
|
100
|
+
- !ruby/object:Gem::Version
|
101
|
+
version: 0.8.7.2
|
102
|
+
type: :development
|
103
|
+
prerelease: false
|
104
|
+
version_requirements: !ruby/object:Gem::Requirement
|
105
|
+
none: false
|
106
|
+
requirements:
|
107
|
+
- - ~>
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
version: 0.8.7.2
|
110
|
+
description: A Ruby library for using machine tags like those used on Flickr and RightScale
|
111
|
+
email:
|
112
|
+
- douglas@douglasthrift.net
|
113
|
+
executables: []
|
114
|
+
extensions: []
|
115
|
+
extra_rdoc_files: []
|
116
|
+
files:
|
117
|
+
- .gitignore
|
118
|
+
- .rspec
|
119
|
+
- .travis.yml
|
120
|
+
- Gemfile
|
121
|
+
- LICENSE.txt
|
122
|
+
- README.md
|
123
|
+
- Rakefile
|
124
|
+
- lib/machine_tag.rb
|
125
|
+
- lib/machine_tag/set.rb
|
126
|
+
- lib/machine_tag/tag.rb
|
127
|
+
- lib/machine_tag/version.rb
|
128
|
+
- machine_tag.gemspec
|
129
|
+
- spec/machine_tag_set_spec.rb
|
130
|
+
- spec/machine_tag_spec.rb
|
131
|
+
- spec/machine_tag_tag_spec.rb
|
132
|
+
- spec/spec_helper.rb
|
133
|
+
homepage: https://github.com/douglaswth/machine_tag
|
134
|
+
licenses:
|
135
|
+
- MIT
|
136
|
+
post_install_message:
|
137
|
+
rdoc_options: []
|
138
|
+
require_paths:
|
139
|
+
- lib
|
140
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
141
|
+
none: false
|
142
|
+
requirements:
|
143
|
+
- - ! '>='
|
144
|
+
- !ruby/object:Gem::Version
|
145
|
+
version: '0'
|
146
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
147
|
+
none: false
|
148
|
+
requirements:
|
149
|
+
- - ! '>='
|
150
|
+
- !ruby/object:Gem::Version
|
151
|
+
version: '0'
|
152
|
+
requirements: []
|
153
|
+
rubyforge_project:
|
154
|
+
rubygems_version: 1.8.23
|
155
|
+
signing_key:
|
156
|
+
specification_version: 3
|
157
|
+
summary: Library for using machine tags
|
158
|
+
test_files:
|
159
|
+
- spec/machine_tag_set_spec.rb
|
160
|
+
- spec/machine_tag_spec.rb
|
161
|
+
- spec/machine_tag_tag_spec.rb
|
162
|
+
- spec/spec_helper.rb
|
163
|
+
has_rdoc:
|