contraption 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +17 -0
- data/.travis.yml +5 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +33 -0
- data/Rakefile +12 -0
- data/bin/contraption +7 -0
- data/contraption.gemspec +29 -0
- data/features/author_finalizes_draft.feature +21 -0
- data/features/author_generates_site.feature +35 -0
- data/features/step_definitions/author_steps.rb +52 -0
- data/features/support/env.rb +0 -0
- data/features/support/example_inputs.rb +188 -0
- data/features/support/hooks.rb +3 -0
- data/lib/contraption/catalog.rb +65 -0
- data/lib/contraption/formatter.rb +30 -0
- data/lib/contraption/header.rb +83 -0
- data/lib/contraption/http_handler.rb +11 -0
- data/lib/contraption/location.rb +81 -0
- data/lib/contraption/options.rb +56 -0
- data/lib/contraption/post.rb +69 -0
- data/lib/contraption/repository.rb +58 -0
- data/lib/contraption/rss_builder.rb +30 -0
- data/lib/contraption/runner.rb +60 -0
- data/lib/contraption/s3_uploader.rb +30 -0
- data/lib/contraption/site.rb +85 -0
- data/lib/contraption/tag.rb +20 -0
- data/lib/contraption/tag_cloud.rb +35 -0
- data/lib/contraption/version.rb +3 -0
- data/lib/contraption.rb +14 -0
- data/spec/contraption/lib/catalog_spec.rb +105 -0
- data/spec/contraption/lib/formatter_spec.rb +30 -0
- data/spec/contraption/lib/header_spec.rb +198 -0
- data/spec/contraption/lib/location_spec.rb +148 -0
- data/spec/contraption/lib/options_spec.rb +25 -0
- data/spec/contraption/lib/post_spec.rb +50 -0
- data/spec/contraption/lib/repository_spec.rb +38 -0
- data/spec/contraption/lib/tag_cloud_spec.rb +39 -0
- data/spec/contraption/lib/tag_spec.rb +38 -0
- data/spec/contraption/lib/version_spec.rb +9 -0
- data/spec/spec_helper.rb +6 -0
- metadata +201 -0
@@ -0,0 +1,198 @@
|
|
1
|
+
require_relative '../../spec_helper.rb'
|
2
|
+
|
3
|
+
require 'date'
|
4
|
+
|
5
|
+
module Contraption
|
6
|
+
describe Header do
|
7
|
+
before(:each) do
|
8
|
+
@title = "The Title"
|
9
|
+
@date = DateTime.now
|
10
|
+
@type = :a_type
|
11
|
+
@tags = []
|
12
|
+
@summary = "some witty line to get people to read the post"
|
13
|
+
@h = Header.new title: @title, publication_date: @date, type: @type, tags: @tags, summary: @summary
|
14
|
+
end
|
15
|
+
|
16
|
+
context "initialization" do
|
17
|
+
|
18
|
+
it "returns the initial title" do
|
19
|
+
@h.title.should eq(@title)
|
20
|
+
end
|
21
|
+
|
22
|
+
it "returns the initial date" do
|
23
|
+
@h.publication_date.should eq(@date)
|
24
|
+
end
|
25
|
+
|
26
|
+
it "returns the initial type" do
|
27
|
+
@h.type.should eq(@type)
|
28
|
+
end
|
29
|
+
|
30
|
+
it "returns the initial tags" do
|
31
|
+
@h.tags.should eq(@tags)
|
32
|
+
end
|
33
|
+
|
34
|
+
it "returns the summary" do
|
35
|
+
@h.summary.should eq(@summary)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
context ".new?" do
|
40
|
+
it "knows when it is new" do
|
41
|
+
h = Header.from "published: now"
|
42
|
+
h.new?.should be_true
|
43
|
+
end
|
44
|
+
|
45
|
+
it "knows when it is not new" do
|
46
|
+
h = Header.from "published: #{@date}"
|
47
|
+
h.new?.should be_false
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
context "#filename" do
|
52
|
+
it "stores the filename if specified in the initializer" do
|
53
|
+
h = Header.new ({filename: "a-filename.md"})
|
54
|
+
h.filename.should eq "a-filename.md"
|
55
|
+
end
|
56
|
+
|
57
|
+
it "returns a filename computed from the title if no filename given" do
|
58
|
+
h = Header.new ({title: "A Filename"})
|
59
|
+
h.filename.should eq "a-filename.md"
|
60
|
+
end
|
61
|
+
|
62
|
+
it "removes non-alphanumeric characters" do
|
63
|
+
h = Header.new ({title: "Call Me ... Maybe?!"})
|
64
|
+
h.filename.should eq "call-me-maybe.md"
|
65
|
+
end
|
66
|
+
|
67
|
+
it "does not remove '-'" do
|
68
|
+
h = Header.new ({title: "Hyphenated-title"})
|
69
|
+
h.filename.should eq "hyphenated-title.md"
|
70
|
+
end
|
71
|
+
|
72
|
+
it "has only one extension" do
|
73
|
+
h = Header.new ({filename: "a-filename.md"})
|
74
|
+
h.filename.split('.').length.should eq 2
|
75
|
+
end
|
76
|
+
|
77
|
+
it "has an extension when not specified" do
|
78
|
+
h = Header.new ({filename: "a-filename"})
|
79
|
+
h.filename.split('.').length.should eq 2
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
context "#update" do
|
84
|
+
it "returns a new object" do
|
85
|
+
update_h = @h.update
|
86
|
+
update_h.should_not eq @h
|
87
|
+
end
|
88
|
+
|
89
|
+
it "does not modify the original header" do
|
90
|
+
initial_h = @h
|
91
|
+
@h.update
|
92
|
+
initial_h.should eq @h
|
93
|
+
end
|
94
|
+
|
95
|
+
it "stores the new title" do
|
96
|
+
new_h = @h.update title: "New Title"
|
97
|
+
new_h.title.should eq "New Title"
|
98
|
+
end
|
99
|
+
|
100
|
+
it "retains the original values" do
|
101
|
+
new_h = @h.update
|
102
|
+
new_h.title.should eq @h.title
|
103
|
+
end
|
104
|
+
|
105
|
+
it "stores all of the new values" do
|
106
|
+
new_h = @h.update title: "New Title", tags: %w[ruby]
|
107
|
+
new_h.title.should eq "New Title"
|
108
|
+
new_h.tags.should eq %w[ruby]
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
context "::from" do
|
113
|
+
let(:title) { "The Title" }
|
114
|
+
let(:pub_date) { "Published: Mon, 31 Dec 2012 15:41:00 EST" }
|
115
|
+
let(:expected_date) { DateTime.new(2012, 12, 31, 15, 41, 00, '-5') }
|
116
|
+
let(:summary) { "SuMMAry: Something witty to get 'eyeballs'" }
|
117
|
+
let(:type) { "tyPe: Article" }
|
118
|
+
let(:tags) { "TaGS: red, green, blue, purple" }
|
119
|
+
|
120
|
+
it "returns a Header" do
|
121
|
+
h = Header.from ""
|
122
|
+
h.class.should eq Header
|
123
|
+
end
|
124
|
+
|
125
|
+
it "finds the title" do
|
126
|
+
h = Header.from title
|
127
|
+
h.title.should eq title
|
128
|
+
end
|
129
|
+
|
130
|
+
it "finds the filename" do
|
131
|
+
h = Header.from "filenAmE: the-filename-goes-here.md"
|
132
|
+
h.filename.should eq "the-filename-goes-here.md"
|
133
|
+
end
|
134
|
+
|
135
|
+
it "finds the publication date" do
|
136
|
+
h = Header.from pub_date
|
137
|
+
h.publication_date.should eq expected_date
|
138
|
+
end
|
139
|
+
|
140
|
+
it "does not manipulate now" do
|
141
|
+
h = Header.from "published: now"
|
142
|
+
h.publication_date.should eq :now
|
143
|
+
end
|
144
|
+
|
145
|
+
it "finds the summary" do
|
146
|
+
h = Header.from summary
|
147
|
+
h.summary.should eq "Something witty to get 'eyeballs'"
|
148
|
+
end
|
149
|
+
|
150
|
+
it "finds the type" do
|
151
|
+
h = Header.from type
|
152
|
+
h.type.should eq :article
|
153
|
+
end
|
154
|
+
|
155
|
+
it "finds the tags" do
|
156
|
+
h = Header.from tags
|
157
|
+
h.tags.map{|t| t.to_s}.should eq %w[red green blue purple]
|
158
|
+
end
|
159
|
+
|
160
|
+
it "finds multiple elements" do
|
161
|
+
combined_input = [title, pub_date, type, tags].join("\n")
|
162
|
+
h = Header.from combined_input
|
163
|
+
h.title.should eq title
|
164
|
+
h.publication_date.should eq expected_date
|
165
|
+
h.type.should eq :article
|
166
|
+
h.tags.map{|t| t.to_s}.should eq %w[red green blue purple]
|
167
|
+
end
|
168
|
+
|
169
|
+
it "alternate definition for titles" do
|
170
|
+
title = "thetitle: and a subtitle"
|
171
|
+
h = Header.from("title: " + title)
|
172
|
+
h.title.should eq title
|
173
|
+
end
|
174
|
+
|
175
|
+
it "handles initial whitespace" do
|
176
|
+
t = "\t A title starting with Whitespace"
|
177
|
+
h = Header.from "title: " + t
|
178
|
+
h.title.should eq "A title starting with Whitespace"
|
179
|
+
end
|
180
|
+
|
181
|
+
it "handles unsupported header lines" do
|
182
|
+
h = Header.from "unsupported: this should not exist"
|
183
|
+
expect {h.unsupported}.to raise_error NameError
|
184
|
+
end
|
185
|
+
|
186
|
+
it "ignores '====' separators" do
|
187
|
+
example = [title, "="*15].join("\n")
|
188
|
+
h = Header.from example
|
189
|
+
h.title.should eq title
|
190
|
+
end
|
191
|
+
|
192
|
+
it "finds external links" do
|
193
|
+
h = Header.from "external: http://ruby-lang.org"
|
194
|
+
h.external.should eq "http://ruby-lang.org"
|
195
|
+
end
|
196
|
+
end
|
197
|
+
end
|
198
|
+
end
|
@@ -0,0 +1,148 @@
|
|
1
|
+
require_relative '../../spec_helper'
|
2
|
+
|
3
|
+
module Contraption
|
4
|
+
describe Location do
|
5
|
+
before(:all) { `mkdir /tmp/qscfr` }
|
6
|
+
after(:all) { `rm -r /tmp/qscfr` }
|
7
|
+
|
8
|
+
let (:dir) { "/tmp/qscfr" }
|
9
|
+
after(:each) { `rm -rf #{dir}/*` }
|
10
|
+
|
11
|
+
let (:l) { Location.new dir }
|
12
|
+
|
13
|
+
it "has a path" do
|
14
|
+
l.path.should eq dir
|
15
|
+
end
|
16
|
+
|
17
|
+
it "can create itself on disk" do
|
18
|
+
new_location = Location.new(dir + '/newdir')
|
19
|
+
new_location.create!
|
20
|
+
File.exist?(dir+'/newdir').should be_true
|
21
|
+
end
|
22
|
+
|
23
|
+
context "#list" do
|
24
|
+
it "handles empty directories" do
|
25
|
+
l.list.should eq []
|
26
|
+
end
|
27
|
+
|
28
|
+
it "handles directories with one file" do
|
29
|
+
`touch #{dir}/monkeys`
|
30
|
+
l.list.should eq ['monkeys']
|
31
|
+
end
|
32
|
+
|
33
|
+
it "handles directories with multiple files" do
|
34
|
+
10.times {|i| `touch #{dir}/#{i}`}
|
35
|
+
l.list.should eq (0..9).map{|i| i.to_s}
|
36
|
+
end
|
37
|
+
|
38
|
+
it "only finds files with specific extension" do
|
39
|
+
`touch #{dir}/10.txt #{dir}/10.html #{dir}/10.md #{dir}/10.rb`
|
40
|
+
l.list(".html").should eq ["10.html"]
|
41
|
+
end
|
42
|
+
|
43
|
+
it "finds files with any of a list of extensions" do
|
44
|
+
`touch #{dir}/10.txt #{dir}/10.html #{dir}/10.md #{dir}/10.rb`
|
45
|
+
l.list(%w[.html .md]).should eq %w[10.html 10.md]
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
context "#read" do
|
50
|
+
let(:content) { "stuff\nthings" }
|
51
|
+
before(:each) { File.open("#{dir}/file", "w:UTF-8") { |f| f.print content } }
|
52
|
+
|
53
|
+
it "returns the contents of the file" do
|
54
|
+
l.read("file").should eq content
|
55
|
+
end
|
56
|
+
|
57
|
+
it "yields to block when passed" do
|
58
|
+
l.read("file") do |io|
|
59
|
+
io.map {|l| l[0]}
|
60
|
+
end.should eq ["s","t"]
|
61
|
+
end
|
62
|
+
|
63
|
+
it "returns a useful token if file does not exist" do
|
64
|
+
l.read("nonexistent_file").should eq :file_does_not_exist
|
65
|
+
end
|
66
|
+
|
67
|
+
it "returns a useful token if file is not readable" do
|
68
|
+
`touch #{dir}/file && chmod -r #{dir}/file`
|
69
|
+
l.read("#{dir}/file").should eq :file_not_readable
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
context "#write" do
|
74
|
+
it "writes the provided string to a file" do
|
75
|
+
l.write "filename", "this is a test string.\nand another line just for fun."
|
76
|
+
end
|
77
|
+
|
78
|
+
it "does not destructively write to a file" do
|
79
|
+
`touch #{dir}/a_new_file`
|
80
|
+
l.write("a_new_file", "some content that will not be written").should eq :file_already_exists
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
context "#remove" do
|
85
|
+
it "forgets an existing file" do
|
86
|
+
l.write("a_new_file", "some stuff to write")
|
87
|
+
l.remove("a_new_file")
|
88
|
+
l.list.should_not include("a_new_file")
|
89
|
+
end
|
90
|
+
|
91
|
+
it "does nothing for non-existing files" do
|
92
|
+
l.remove("a_non_existant_file").should eq :file_does_not_exist
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
context "directory trees" do
|
97
|
+
it "recursively creates directories" do
|
98
|
+
l.write "some/thing", "something"
|
99
|
+
l.read("some/thing").should eq "something"
|
100
|
+
end
|
101
|
+
|
102
|
+
it "recursively lists files" do
|
103
|
+
l.write "some/thing", "something"
|
104
|
+
l.write "a/new/file", "a"
|
105
|
+
l.list.should eq %w[a new file some thing]
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
context "equality" do
|
110
|
+
it "returns true for Locations with the same path" do
|
111
|
+
l.==(Location.new(dir)).should be_true
|
112
|
+
end
|
113
|
+
|
114
|
+
it "returns false for Locations with different paths" do
|
115
|
+
l.==(Location.new(dir+"a")).should be_false
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
context "interrogation" do
|
120
|
+
it "contains exist?" do
|
121
|
+
l.exist?
|
122
|
+
end
|
123
|
+
|
124
|
+
it "contains readable?" do
|
125
|
+
l.readable?
|
126
|
+
end
|
127
|
+
|
128
|
+
it "contains writable?" do
|
129
|
+
l.writable?
|
130
|
+
end
|
131
|
+
|
132
|
+
it "contains executable?" do
|
133
|
+
l.executable?
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
context "cd" do
|
138
|
+
it "returns a new Location rooted at argument" do
|
139
|
+
`mkdir #{dir}/subdir`
|
140
|
+
l.cd("subdir").path.should eq "#{dir}/subdir"
|
141
|
+
end
|
142
|
+
|
143
|
+
it "creates location if directory does not exist" do
|
144
|
+
l.cd("subdir").exist?.should be_true
|
145
|
+
end
|
146
|
+
end
|
147
|
+
end
|
148
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require_relative '../../../lib/contraption/options'
|
2
|
+
|
3
|
+
module Contraption
|
4
|
+
describe Options do
|
5
|
+
it "accepts an array of arguments" do
|
6
|
+
Options.new []
|
7
|
+
end
|
8
|
+
|
9
|
+
it "sets the source with -s" do
|
10
|
+
Options.new(["-s", "TheSource"]).source.path.should eq "TheSource"
|
11
|
+
end
|
12
|
+
|
13
|
+
it "sets the source with --source" do
|
14
|
+
Options.new(["--source", "TheSource"]).source.path.should eq "TheSource"
|
15
|
+
end
|
16
|
+
|
17
|
+
it "sets the destination with -d" do
|
18
|
+
Options.new(["-d", "TheDestination"]).destination.path.should eq "TheDestination"
|
19
|
+
end
|
20
|
+
|
21
|
+
it "sets the destination with --destination" do
|
22
|
+
Options.new(["--destination", "TheDestination"]).destination.path.should eq "TheDestination"
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
require_relative '../../spec_helper.rb'
|
2
|
+
|
3
|
+
module Contraption
|
4
|
+
describe Post do
|
5
|
+
it "has a body" do
|
6
|
+
Post.new.body
|
7
|
+
end
|
8
|
+
|
9
|
+
it "has metadata" do
|
10
|
+
Post.new.metadata
|
11
|
+
end
|
12
|
+
|
13
|
+
context "::build" do
|
14
|
+
it "returns a post object from the given string" do
|
15
|
+
Post.build("testing").class.should eq Post
|
16
|
+
end
|
17
|
+
|
18
|
+
it "has a nonempty title" do
|
19
|
+
Post.build("testing").title.should_not eq ""
|
20
|
+
end
|
21
|
+
|
22
|
+
it "has a nonempty body" do
|
23
|
+
p = Post.build("testing\n\nsome content for the post")
|
24
|
+
p.body.should_not eq ""
|
25
|
+
end
|
26
|
+
|
27
|
+
it "captures the entire contents of multiline posts" do
|
28
|
+
p = Post.build("testing\n\nsome content for the post\n\nsome more content")
|
29
|
+
p.body.should include "<p>some content for the post</p>\n\n<p>some more content</p>"
|
30
|
+
end
|
31
|
+
|
32
|
+
it "translates markdown to html" do
|
33
|
+
p = Post.build("testing\n\n__bold text__")
|
34
|
+
p.body.should include "<strong>bold text</strong>"
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
context ".publish" do
|
39
|
+
it "sets the new date" do
|
40
|
+
p = Post.build "\n\n"
|
41
|
+
p = p.publish.publication_date.to_s.should eq Time.now.to_s
|
42
|
+
end
|
43
|
+
|
44
|
+
it "does not modify the body" do
|
45
|
+
p = Post.build "\n\nSome stuff"
|
46
|
+
p.publish.body.should include "Some stuff"
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require_relative '../../../lib/contraption/repository.rb'
|
2
|
+
|
3
|
+
module Contraption
|
4
|
+
describe Repository do
|
5
|
+
context "validity" do
|
6
|
+
before(:each) do
|
7
|
+
@source = double()
|
8
|
+
@source.stub(exist?: true)
|
9
|
+
@source.stub(:cd).and_return("")
|
10
|
+
end
|
11
|
+
|
12
|
+
it "raises an error if the structure is invalid" do
|
13
|
+
@source.stub(list: %w[drafts pictures])
|
14
|
+
expect {r = Repository.new(@source)}.to raise_error
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
it "finds the drafts" do
|
19
|
+
Repository.any_instance.stub(:validate)
|
20
|
+
source = double()
|
21
|
+
source.stub(:list).and_return(%w[test.md house.md])
|
22
|
+
source.stub(cd: source)
|
23
|
+
r = Repository.new(source)
|
24
|
+
r.drafts.should eq %w[test.md house.md]
|
25
|
+
end
|
26
|
+
|
27
|
+
it "returns a collection of posts" do
|
28
|
+
Repository.any_instance.stub(:validate)
|
29
|
+
source = double()
|
30
|
+
source.stub(:list).and_return(%w[test.md house.md])
|
31
|
+
source.stub(:read).with("test.md").and_return("something")
|
32
|
+
source.stub(:read).with("house.md").and_return("something else")
|
33
|
+
source.stub(cd: source)
|
34
|
+
r = Repository.new(source)
|
35
|
+
r.posts.should respond_to :each
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require_relative '../../../lib/contraption/tag_cloud'
|
2
|
+
|
3
|
+
module Contraption
|
4
|
+
describe TagCloud do
|
5
|
+
context "#initialize" do
|
6
|
+
it "takes a collection of posts" do
|
7
|
+
tc = TagCloud.new []
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
context "#to_s" do
|
12
|
+
before do
|
13
|
+
tag1 = double
|
14
|
+
tag2 = double
|
15
|
+
tag1.stub(:to_s).and_return("Ruby")
|
16
|
+
tag1.stub(:to_url).and_return("ruby")
|
17
|
+
tag2.stub(:to_s).and_return("OS X")
|
18
|
+
tag2.stub(:to_url).and_return("os-x")
|
19
|
+
posts = double
|
20
|
+
posts.stub(:by_tag).and_return( {tag1 => [1, 2], tag2 => [1]} )
|
21
|
+
@tc = TagCloud.new posts
|
22
|
+
end
|
23
|
+
|
24
|
+
it "contains all of the tags" do
|
25
|
+
@tc.to_s.should include 'ruby'
|
26
|
+
@tc.to_s.should include 'os-x'
|
27
|
+
end
|
28
|
+
|
29
|
+
it "includes a link to the tag page" do
|
30
|
+
@tc.to_s.should include 'ruby/index.html'
|
31
|
+
@tc.to_s.should include 'os-x/index.html'
|
32
|
+
end
|
33
|
+
|
34
|
+
it "sets the size of each tag" do
|
35
|
+
@tc.to_s.should include 'font-size'
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require_relative '../../../lib/contraption/tag.rb'
|
2
|
+
|
3
|
+
module Contraption
|
4
|
+
describe Tag do
|
5
|
+
it "accepts a string to be displayed" do
|
6
|
+
t = Tag.new "Ruby"
|
7
|
+
end
|
8
|
+
|
9
|
+
it "returns the display text" do
|
10
|
+
t = Tag.new "Ruby"
|
11
|
+
t.to_s.should eq "Ruby"
|
12
|
+
end
|
13
|
+
|
14
|
+
context "#to_url" do
|
15
|
+
it "provides a url friendly version" do
|
16
|
+
t = Tag.new "Ruby"
|
17
|
+
t.to_url
|
18
|
+
end
|
19
|
+
|
20
|
+
it "downcases the output" do
|
21
|
+
t = Tag.new "Ruby"
|
22
|
+
t.to_url.should eq "ruby"
|
23
|
+
end
|
24
|
+
|
25
|
+
it "replaces spaces with dashes" do
|
26
|
+
t = Tag.new "ruby rocks"
|
27
|
+
t.to_url.should eq "ruby-rocks"
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
context "#to_sym" do
|
32
|
+
it "returns a symbolized version of the display text" do
|
33
|
+
t = Tag.new "Qwerty"
|
34
|
+
t.to_sym.should eq "Qwerty".to_sym
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|