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 ADDED
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --format documentation
2
+ --color
data/.travis.yml ADDED
@@ -0,0 +1,4 @@
1
+ language: ruby
2
+ rvm:
3
+ - 1.9.3
4
+ - 2.0.0
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in machine_tag.gemspec
4
+ gemspec
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
+ [![Gem Version](https://badge.fury.io/rb/machine_tag.png)](http://badge.fury.io/rb/machine_tag)
4
+ [![Build Status](https://travis-ci.org/douglaswth/machine_tag.png?branch=master)](https://travis-ci.org/douglaswth/machine_tag)
5
+ [![Dependency Status](https://gemnasium.com/douglaswth/machine_tag.png)](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
@@ -0,0 +1,8 @@
1
+ require "bundler/gem_tasks"
2
+ require "rspec/core/rake_task"
3
+ require "yard"
4
+
5
+ RSpec::Core::RakeTask.new(:spec)
6
+ YARD::Rake::YardocTask.new
7
+
8
+ task :default => :spec
@@ -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
@@ -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,7 @@
1
+ require 'spec_helper'
2
+
3
+ describe MachineTag do
4
+ it 'should have a version number' do
5
+ MachineTag::VERSION.should_not be_nil
6
+ end
7
+ 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
@@ -0,0 +1,2 @@
1
+ $LOAD_PATH.unshift File.expand_path('../../lib', __FILE__)
2
+ require 'machine_tag'
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: