tags 1.0.1 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,48 +1,35 @@
1
- require 'set'
2
- require 'active_support'
1
+ require 'forwardable'
3
2
 
4
3
  class Tags
4
+ extend Forwardable
5
+ include Enumerable
5
6
 
6
- include Comparable
7
+ def_delegators :tags, :empty?, :to_ary, :to_a, :each, :size
7
8
 
8
- ##################################################
9
-
10
- def initialize(str_or_ary = nil)
11
- ary = str_or_ary.is_a?(Array) ? str_or_ary : str_or_ary.to_s.split(' ')
12
- @tags_set = Set.new(ary)
9
+ def initialize(tags)
10
+ @tags = tags.is_a?(Array) ? tags : tags.to_s.split(/\W+/)
11
+ @tags.each &:downcase!
12
+ @tags.uniq!
13
13
  end
14
14
 
15
15
  def to_s
16
- to_a.join(' ')
17
- end
18
-
19
- def to_a
20
- tags_set.to_a
16
+ tags.join ', '
21
17
  end
22
18
 
23
- def to_set
24
- tags_set.dup
19
+ def +(other)
20
+ self.class.new(to_a + other.to_a)
25
21
  end
26
22
 
27
23
  def -(other)
28
- raise ArgumentError, "must be a #{self.class} object" unless other.is_a?(self.class)
29
- ary_diff = (tags_set - other.to_set).to_a
30
- self.class.new(ary_diff)
31
- end
32
-
33
- def +(other)
34
- raise ArgumentError, "must be a #{self.class} object" unless other.is_a?(self.class)
35
- ary_add = (tags_set + other.to_set).to_a
36
- self.class.new(ary_add)
24
+ self.class.new(to_a - other.to_a)
37
25
  end
38
26
 
39
- def <=>(other)
40
- tags_set <=> other.to_set
27
+ def ==(other)
28
+ to_a == Array(other)
41
29
  end
42
30
 
43
- ##################################################
44
- private
31
+ private
45
32
 
46
- attr_reader :tags_set
33
+ attr_reader :tags
47
34
 
48
35
  end
@@ -1,3 +1,3 @@
1
1
  class Tags
2
- VERSION = "1.0.1"
2
+ VERSION = "1.1.0"
3
3
  end
@@ -2,68 +2,86 @@ require 'spec_helper'
2
2
 
3
3
  describe Tags do
4
4
 
5
- describe "#to_s" do
6
- it { Tags.new("one two").to_s.should eq("one two") }
7
- it { Tags.new.to_s.should eq("") }
8
- end
5
+ describe "instance methods" do
6
+ subject { described_class.new @arg }
9
7
 
10
- describe "#to_a" do
11
- it { Tags.new("one two").to_a.should eq(["one", "two"]) }
12
- it { Tags.new.to_a.should eq([]) }
13
- end
8
+ describe "#to_s" do
9
+ context "with a blank string" do
10
+ before { @arg = "" }
11
+ its(:to_s) { should eq("") }
12
+ end
14
13
 
15
- describe "#to_set" do
16
- it { Tags.new("one two").to_set.should eq(Set.new(["one", "two"])) }
17
- it { Tags.new.to_set.should eq(Set.new) }
18
- end
14
+ context "with tags separated by commas or whitespace" do
15
+ before { @arg = "barley, hops water, yeast" }
16
+ its(:to_s) { should eq("barley, hops, water, yeast") }
17
+ end
19
18
 
20
- describe "#-" do
21
- context "with a Tags" do
22
- it { (Tags.new - Tags.new("one")).should eq(Tags.new) }
23
- it { (Tags.new("one") - Tags.new("one")).should eq(Tags.new) }
24
- it { (Tags.new("one two") - Tags.new("one")).should eq(Tags.new("two")) }
25
- it { (Tags.new("one two") - Tags.new("three")).should eq(Tags.new("one two")) }
26
- it { (Tags.new("one two three") - Tags.new("one three")).should eq(Tags.new("two")) }
19
+ context "given nil" do
20
+ before { @arg = nil }
21
+ its(:to_s) { should eq("") }
22
+ end
27
23
  end
28
24
 
29
- it "argument must be of the Tags type" do
30
- lambda do
31
- Tags.new("one") - ["one"]
32
- end.should raise_error(ArgumentError, "must be a Tags object")
33
- end
34
- end
25
+ describe "#to_a" do
26
+ context "with a blank string" do
27
+ before { @arg = "" }
28
+ its(:to_a) { should eq([]) }
29
+ end
35
30
 
36
- describe "#+" do
37
- context "with a Tags" do
38
- it { (Tags.new + Tags.new("one")).should eq(Tags.new("one")) }
39
- it { (Tags.new("one") + Tags.new("one")).should eq(Tags.new("one")) }
40
- it { (Tags.new("one two") + Tags.new).should eq(Tags.new("one two")) }
41
- it { (Tags.new("one two") + Tags.new("three")).should eq(Tags.new("one two three")) }
42
- end
31
+ context "with tags separated by commas or whitespace" do
32
+ before { @arg = "barley, hops water, yeast" }
33
+ its(:to_a) { should eq(%w[barley hops water yeast]) }
34
+ end
35
+
36
+ context "with duplicate tags" do
37
+ before { @arg = "barley, hops, barley" }
38
+ it "eliminates duplicates" do
39
+ subject.to_a.should eq(%w[barley hops])
40
+ end
41
+ end
42
+
43
+ context "with mixed-case tags" do
44
+ before { @arg = "Barley, hOps, YEAST" }
45
+ it "lowercases the tags" do
46
+ subject.to_a.should eq(%w[barley hops yeast])
47
+ end
48
+ end
43
49
 
44
- it "argument must be of the Tags type" do
45
- lambda do
46
- Tags.new("one") + ["one"]
47
- end.should raise_error(ArgumentError, "must be a Tags object")
50
+ context "with duplicate mixed case tags" do
51
+ before { @arg = "barley, hops, BarlEy" }
52
+ it "eliminates duplicates ignoring case" do
53
+ subject.to_a.should eq(%w[barley hops])
54
+ end
55
+ end
48
56
  end
49
- end
50
57
 
51
- describe "#==" do
52
- context "with a Tags containing the same items" do
53
- it { Tags.new("one two").should eq(Tags.new("one two")) }
54
- it { Tags.new("one two three").should eq(Tags.new("one two three")) }
55
- it { Tags.new("one two").should eq(Tags.new("one two")) }
56
- it { Tags.new.should eq(Tags.new) }
58
+ describe "#+" do
59
+ it "combines tags into one" do
60
+ @arg = "foo, bar"
61
+ result = subject + described_class.new("baz, buz")
62
+ result.should eq(described_class.new("foo, bar, baz, buz"))
63
+ end
57
64
 
58
- it { Tags.new("one two").should_not eq(Tags.new("one two three")) }
59
- it { Tags.new.should_not eq(Tags.new("one two three")) }
65
+ # more examples
66
+ it { (Tags.new(nil) + Tags.new("one")).should eq(Tags.new("one")) }
67
+ it { (Tags.new("one") + Tags.new("one")).should eq(Tags.new("one")) }
68
+ it { (Tags.new("one two") + Tags.new(nil)).should eq(Tags.new("one two")) }
69
+ it { (Tags.new("one two") + Tags.new("three")).should eq(Tags.new("one two three")) }
60
70
  end
61
71
 
62
- context "with a non-Tags" do
63
- it { Tags.new("one").should_not eq("str") }
64
- it { Tags.new("one").should_not eq(["str"]) }
65
- it { Tags.new("one").should_not eq(Set.new(["str"])) }
66
- it { Tags.new.should_not eq(nil) }
72
+ describe "#-" do
73
+ it "returns the difference of the tags" do
74
+ @arg = "foo, buz"
75
+ result = subject - described_class.new("baz, buz")
76
+ result.should eq(described_class.new("foo"))
77
+ end
78
+
79
+ # more examples
80
+ it { (Tags.new(nil) - Tags.new("one")).should eq(Tags.new(nil)) }
81
+ it { (Tags.new("one") - Tags.new("one")).should eq(Tags.new(nil)) }
82
+ it { (Tags.new("one two") - Tags.new("one")).should eq(Tags.new("two")) }
83
+ it { (Tags.new("one two") - Tags.new("three")).should eq(Tags.new("one two")) }
84
+ it { (Tags.new("one two three") - Tags.new("one three")).should eq(Tags.new("two")) }
67
85
  end
68
86
  end
69
87
 
@@ -16,6 +16,4 @@ Gem::Specification.new do |spec|
16
16
  spec.version = Tags::VERSION
17
17
 
18
18
  spec.add_development_dependency "rspec", ">= 2.8"
19
-
20
- spec.add_dependency "activesupport", ">= 3"
21
19
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tags
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.1
4
+ version: 1.1.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -13,7 +13,7 @@ date: 2012-03-14 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rspec
16
- requirement: &70244872203780 !ruby/object:Gem::Requirement
16
+ requirement: &70238186485360 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,18 +21,7 @@ dependencies:
21
21
  version: '2.8'
22
22
  type: :development
23
23
  prerelease: false
24
- version_requirements: *70244872203780
25
- - !ruby/object:Gem::Dependency
26
- name: activesupport
27
- requirement: &70244872202800 !ruby/object:Gem::Requirement
28
- none: false
29
- requirements:
30
- - - ! '>='
31
- - !ruby/object:Gem::Version
32
- version: '3'
33
- type: :runtime
34
- prerelease: false
35
- version_requirements: *70244872202800
24
+ version_requirements: *70238186485360
36
25
  description: A Ruby object with the behavior of a list of tags.
37
26
  email:
38
27
  - austinthecoder@gmail.com