diff --git a/lib/puppet/util/tagging.rb b/lib/puppet/util/tagging.rb index 0eb0096fe..266029a1f 100644 --- a/lib/puppet/util/tagging.rb +++ b/lib/puppet/util/tagging.rb @@ -1,57 +1,56 @@ require 'puppet/util/tag_set' module Puppet::Util::Tagging ValidTagRegex = /^\w[-\w:.]*$/ # Add a tag to the current tag set. # When a tag set is used for a scope, these tags will be added to all of # the objects contained in this scope when the objects are finished. # def tag(*ary) @tags ||= new_tags ary.flatten.each do |tag| name = tag.to_s.downcase if name =~ ValidTagRegex @tags << name name.split("::").each do |section| - fail(Puppet::ParseError, "Invalid tag ''") if section.empty? @tags << section end else fail(Puppet::ParseError, "Invalid tag '#{name}'") end end end # Is the receiver tagged with the given tags? def tagged?(*tags) not ( self.tags & tags.flatten.collect { |t| t.to_s } ).empty? end # Return a copy of the tag list, so someone can't ask for our tags # and then modify them. def tags @tags ||= new_tags @tags.dup end def tags=(tags) @tags = new_tags return if tags.nil? or tags == "" tags = tags.strip.split(/\s*,\s*/) if tags.is_a?(String) tags.each {|t| tag(t) } end private def valid_tag?(tag) tag.is_a?(String) and tag =~ ValidTagRegex end def new_tags Puppet::Util::TagSet.new end end diff --git a/spec/unit/util/tagging_spec.rb b/spec/unit/util/tagging_spec.rb index bbe042334..c2ebeaab3 100755 --- a/spec/unit/util/tagging_spec.rb +++ b/spec/unit/util/tagging_spec.rb @@ -1,136 +1,162 @@ #! /usr/bin/env ruby require 'spec_helper' require 'puppet/util/tagging' describe Puppet::Util::Tagging do let(:tagger) { Object.new.extend(Puppet::Util::Tagging) } it "should add tags to the returned tag list" do tagger.tag("one") expect(tagger.tags).to include("one") end it "should return a duplicate of the tag list, rather than the original" do tagger.tag("one") tags = tagger.tags tags << "two" expect(tagger.tags).to_not include("two") end it "should add all provided tags to the tag list" do tagger.tag("one", "two") expect(tagger.tags).to include("one") expect(tagger.tags).to include("two") end it "should fail on tags containing '*' characters" do expect { tagger.tag("bad*tag") }.to raise_error(Puppet::ParseError) end it "should fail on tags starting with '-' characters" do expect { tagger.tag("-badtag") }.to raise_error(Puppet::ParseError) end it "should fail on tags containing ' ' characters" do expect { tagger.tag("bad tag") }.to raise_error(Puppet::ParseError) end it "should allow alpha tags" do expect { tagger.tag("good_tag") }.not_to raise_error end it "should allow tags containing '.' characters" do expect { tagger.tag("good.tag") }.to_not raise_error(Puppet::ParseError) end it "should add qualified classes as tags" do tagger.tag("one::two") expect(tagger.tags).to include("one::two") end it "should add each part of qualified classes as tags" do tagger.tag("one::two::three") expect(tagger.tags).to include('one') expect(tagger.tags).to include("two") expect(tagger.tags).to include("three") end it "should indicate when the object is tagged with a provided tag" do tagger.tag("one") expect(tagger).to be_tagged("one") end it "should indicate when the object is not tagged with a provided tag" do expect(tagger).to_not be_tagged("one") end it "should indicate when the object is tagged with any tag in an array" do tagger.tag("one") expect(tagger).to be_tagged("one","two","three") end it "should indicate when the object is not tagged with any tag in an array" do tagger.tag("one") expect(tagger).to_not be_tagged("two","three") end context "when tagging" do it "converts symbols to strings" do tagger.tag(:hello) expect(tagger.tags).to include('hello') end it "downcases tags" do tagger.tag(:HEllO) tagger.tag("GooDByE") expect(tagger).to be_tagged("hello") expect(tagger).to be_tagged("goodbye") end it "accepts hyphenated tags" do tagger.tag("my-tag") expect(tagger).to be_tagged("my-tag") end end context "when querying if tagged" do it "responds true if queried on the entire set" do tagger.tag("one", "two") expect(tagger).to be_tagged("one", "two") end it "responds true if queried on a subset" do tagger.tag("one", "two", "three") expect(tagger).to be_tagged("two", "one") end it "responds true if queried on an overlapping but not fully contained set" do tagger.tag("one", "two") expect(tagger).to be_tagged("zero", "one") end it "responds false if queried on a disjoint set" do tagger.tag("one", "two", "three") expect(tagger).to_not be_tagged("five") end it "responds false if queried on the empty set" do expect(tagger).to_not be_tagged end end context "when assigning tags" do it "splits a string on ','" do tagger.tags = "one, two, three" expect(tagger).to be_tagged("one") expect(tagger).to be_tagged("two") expect(tagger).to be_tagged("three") end it "protects against empty tags" do - expect { tagger.tags = "one::::two::three"}.to raise_error(/Invalid tag ''/) - expect { tagger.tags = "one,,,two,,,three,,"}.to raise_error(/Invalid tag ''/) + expect { tagger.tags = "one,,two"}.to raise_error(/Invalid tag ''/) + end + + it "takes an array of tags" do + tagger.tags = ["one", "two"] + + expect(tagger).to be_tagged("one") + expect(tagger).to be_tagged("two") + end + + it "removes any existing tags when reassigning" do + tagger.tags = "one, two" + + tagger.tags = "three, four" + + expect(tagger).to_not be_tagged("one") + expect(tagger).to_not be_tagged("two") + expect(tagger).to be_tagged("three") + expect(tagger).to be_tagged("four") + end + + it "allows empty tags that are generated from :: separated tags" do + tagger.tags = "one::::two::three" + + expect(tagger).to be_tagged("one") + expect(tagger).to be_tagged("") + expect(tagger).to be_tagged("two") + expect(tagger).to be_tagged("three") end end end