tmin_test 0.0.1

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/spec/spec.opts ADDED
@@ -0,0 +1,4 @@
1
+ --colour
2
+ --format progress
3
+ --loadby mtime
4
+ --reverse
@@ -0,0 +1,55 @@
1
+ require File.join(File.dirname(__FILE__), '..', 'lib', 'firefly.rb')
2
+
3
+ require 'rubygems'
4
+ require "bundler/setup"
5
+
6
+ require 'sinatra'
7
+ require 'rack/test'
8
+ require 'yaml'
9
+ require 'database_cleaner'
10
+
11
+ # set test environment
12
+ set :environment, :test
13
+ set :run, false
14
+ set :raise_errors, true
15
+ set :logging, false
16
+
17
+ @@app = Firefly::Server.new do
18
+ set :hostname, "test.host"
19
+ set :api_key, "test"
20
+ set :database, "sqlite3::memory:"
21
+
22
+ set :sharing_key, "asdfasdf"
23
+ set :sharing_targets, [:twitter, :hyves, :facebook]
24
+ set :sharing_domains, ["example.com", "example.net"]
25
+ end
26
+
27
+ RSpec.configure do |config|
28
+
29
+ config.before(:suite) do
30
+ DatabaseCleaner.strategy = :truncation
31
+ DatabaseCleaner.clean_with(:truncation)
32
+ Firefly::CodeFactory.create(:count => 0)
33
+ end
34
+
35
+ config.before(:each) do
36
+ DatabaseCleaner.start
37
+ end
38
+
39
+ config.after(:each) do
40
+ DatabaseCleaner.clean
41
+ Firefly::CodeFactory.create(:count => 0)
42
+ end
43
+
44
+ # Loads the urls.yml fixtures.
45
+ def load_fixtures
46
+ Firefly::Url.destroy
47
+ urls = YAML::load(File.open('spec/fixtures/urls.yml'))
48
+ urls.each { |key, url| Firefly::Url.create(url) }
49
+ end
50
+
51
+ # Load a spec file and return its contents
52
+ def spec_file(filename)
53
+ File.open('spec/files/'+filename) { |f| f.read }
54
+ end
55
+ end
data/test/helper.rb ADDED
@@ -0,0 +1,18 @@
1
+ require 'rubygems'
2
+ require 'bundler'
3
+ begin
4
+ Bundler.setup(:default, :development)
5
+ rescue Bundler::BundlerError => e
6
+ $stderr.puts e.message
7
+ $stderr.puts "Run `bundle install` to install missing gems"
8
+ exit e.status_code
9
+ end
10
+ require 'test/unit'
11
+ require 'shoulda'
12
+
13
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
14
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
15
+ require 'tmin'
16
+
17
+ class Test::Unit::TestCase
18
+ end
data/test/test_tmin.rb ADDED
@@ -0,0 +1,7 @@
1
+ require 'helper'
2
+
3
+ class TestTmin < Test::Unit::TestCase
4
+ should "probably rename this file and start testing for real" do
5
+ flunk "hey buddy, you should probably rename this file and start testing for real"
6
+ end
7
+ end
data/tmin_test.gemspec ADDED
@@ -0,0 +1,35 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "tmin/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "tmin_test"
7
+ s.version = Tminus::VERSION
8
+ s.platform = Gem::Platform::RUBY
9
+ s.authors = ["drobs"]
10
+ s.email = ["duggan@uncarbonatedsoftware.com"]
11
+ s.homepage = "http://uncarbonatedsoftware.com"
12
+ s.summary = %q{tminusit is your own personal URL shortener for your own domain.}
13
+ s.description = %q{tminusit is your own personal URL shortener for your own domain. It's written in Ruby and powered by Sinatra. You can run it with any Rack-capable web server.}
14
+
15
+ s.rubyforge_project = "tminusit"
16
+
17
+ s.files = `git ls-files`.split("\n")
18
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
19
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
20
+ s.require_paths = ["lib"]
21
+
22
+ s.add_runtime_dependency("sinatra", ["~> 1.2.0"])
23
+ s.add_runtime_dependency("dm-core", ["~> 1.2.0"])
24
+ s.add_runtime_dependency("dm-migrations", ["~> 1.2.0"])
25
+ s.add_runtime_dependency("dm-transactions", ["~> 1.2.0"])
26
+ s.add_runtime_dependency("dm-aggregates", ["~> 1.2.0"])
27
+ s.add_runtime_dependency("dm-mysql-adapter", ["~> 1.2.0"])
28
+ s.add_runtime_dependency("haml", ["~> 3.0.18"])
29
+ s.add_runtime_dependency("escape_utils", ["~> 0.2.3"])
30
+
31
+ s.add_development_dependency("rspec", ["~> 2.5.0"])
32
+ s.add_development_dependency("rack-test", ["~> 0.5.4"])
33
+ s.add_development_dependency("dm-sqlite-adapter", ["~> 1.2.0"])
34
+ s.add_development_dependency("database_cleaner", ["~> 0.6.6"])
35
+ end
data/views/admin.haml ADDED
@@ -0,0 +1,92 @@
1
+ - if @authenticated
2
+ .sidebox
3
+ %h2 Bookmarklet
4
+
5
+ %p
6
+ Drag the following link to your bookmarks. Click it to shorten the URL to the page you're currently viewing.
7
+ %p
8
+ %a{ :href => "javascript:var%20d=document,w=window,enc=encodeURIComponent,e=w.getSelection,k=d.getSelection,x=d.selection,s=(e?e():(k)?k():(x?x.createRange().text:0)),s2=((s.toString()=='')?s:('%22'+enc(s)+'%22')),key=enc('#{@config[:api_key]}'),f='http://#{@config[:hostname]}/api/add',l=d.location,p='?visual=1&api_key='+key+'&url='+enc(l.href),u=f+p;try{if(!/^(.*\.)?tumblrzzz[^.]*$/.test(l.host))throw(0);tstbklt();}catch(z){a%20=function(){if(!w.open(u))l.href=u;};if(/Firefox/.test(navigator.userAgent))setTimeout(a,0);else%20a();}void(0)" } Shorten with #{@config[:hostname]}
9
+
10
+ %h1 How about shortening a URL?
11
+
12
+ .the_form
13
+ %form{ :action => '/api/add', :method => 'post' }
14
+ %input{ :type => "hidden", :name => "visual", :value => "1" }
15
+ %p
16
+ %input.big_url{ :type => 'text', :placeholder => "Paste your long URL here...", :name => 'url', :id => 'url', :size => 40, :autocomplete => "off", :spellcheck => 'false' }
17
+ %span{ :style => "font-size: 1.8em;" }= '>'
18
+ %input.big_url{ :type => 'text', :placeholder => "Optional short code", :name => 'short', :id => 'short', :size => 20, :autocomplete => "off", :spellcheck => 'false' }
19
+ %p
20
+ %input.big_url{ :type => 'submit', :name => 'submit', :id => 'submit', :value => "Make it short!" }
21
+
22
+ - if @highlight
23
+ %h2 Your short URL
24
+
25
+ %table
26
+ %tr
27
+ %td.label Short URL
28
+ %td.label Full URL
29
+ %td.label Clicks
30
+ %td.label Shortened at
31
+ %td.label &nbsp;
32
+ %tr.highlighted
33
+ %td.value
34
+ %input{ :type => "text", :value => short_url(@highlight), :class => 'short_url', :size => 21 }
35
+ %td.value.fill <a href="#{@highlight.url}">#{truncate @highlight.url, 130}</a>
36
+ %td.value.center= @highlight.clicks
37
+ %td.value= @highlight.created_at.strftime("%Y-%m-%d %H:%M")
38
+ %td.value
39
+ %a{ :href => "http://twitter.com/home?status=#{tweet(short_url(@highlight))}" }
40
+ %img.twitter{ :src => "/images/twitter.png", :width => "16", :height => "16" }
41
+
42
+ %h2 Recently shortened
43
+
44
+ %table
45
+ %tr
46
+ %td.label(nowrap='nowrap') Short URL <a href="/?s=code&d=asc">▲</a> <a href="/?s=code&d=desc">▼</a>
47
+ %td.label(nowrap='nowrap') Full URL <a href="/?s=url&d=asc">▲</a> <a href="/?s=url&d=desc">▼</a>
48
+ %td.label(nowrap='nowrap') Clicks <a href="/?s=clicks&d=asc">▲</a> <a href="/?s=clicks&d=desc">▼</a>
49
+ %td.label(nowrap='nowrap') Shortened At <a href="/?s=created_at&d=asc">▲</a> <a href="/?s=created_at&d=desc">▼</a>
50
+ %td.label &nbsp;
51
+ - @urls.each do |url|
52
+ %tr{ :class => is_highlighted?(url) ? 'highlighted' : '' }
53
+ %td.value
54
+ %input{ :type => "text", :value => short_url(url), :class => 'short_url', :size => 31 }
55
+ %td.value.fill <a href="#{url.url}">#{truncate url.url, 95}</a>
56
+ %td.value.center= url.clicks
57
+ %td.value= url.created_at.strftime("%Y-%m-%d %H:%M")
58
+ %td.value
59
+ %a{ :href => "http://twitter.com/home?status=#{tweet(short_url(url))}" }
60
+ %img.twitter{ :src => "/images/twitter.png", :width => "16", :height => "16" }
61
+
62
+
63
+ :javascript
64
+ $(document).ready(function() {
65
+ $('input.short_url').each(function(index) {
66
+ $(this).mouseup(function() { $(this).select(); });
67
+ });
68
+
69
+ if (window.location.search == "") {
70
+ var pathname = window.location.pathname + '?s=created_at&d=desc';
71
+ } else {
72
+ var pathname = window.location.pathname + window.location.search;
73
+ }
74
+
75
+ $('#main table tr td.label a').each(function(index) {
76
+ if ($(this).attr('href') == pathname) {
77
+ $(this).addClass('highlight');
78
+ }
79
+ });
80
+ });
81
+ - else
82
+ %h1 Please enter your API key
83
+
84
+ %p
85
+ Please enter your API key below to make sure only you can shorten URLs here.
86
+
87
+ %form{ :action => '/api/set', :method => 'post' }
88
+ %p
89
+ %label{ :for => 'api_key' } API Key
90
+ %input{ :type => 'password', :name => 'api_key', :id => 'api_key' }
91
+ %p
92
+ %input{ :type => 'submit', :name => 'submit', :id => 'submit', :value => "Let me in" }
data/views/ec.haml ADDED
@@ -0,0 +1,35 @@
1
+ %a#applink1{:href => "#{@url.url}"}
2
+ %img#thumb{:src => "/images/ec_background.gif", :alt => "My Pic"}
3
+ %p Download tminus now
4
+
5
+
6
+ :javascript
7
+ var ref = document.referrer;
8
+ if(ref && ref.toLowerCase().indexOf("twitter.com")!==-1){
9
+ window.location.href="/";
10
+ }
11
+ var appstorefail = "itms://itunes.apple.com/us/app/tminus-make-share-countdown/id507726329?mt=8";
12
+ function applink(fail){
13
+ return function(){
14
+ var clickedAt = +new Date;
15
+ // During tests on 3g/3gs this timeout fires immediately if less than 500ms.
16
+ setTimeout(function(){
17
+ // To avoid failing on return to MobileSafari, ensure freshness!
18
+ if (+new Date - clickedAt < 2000){
19
+ window.location = fail;
20
+ }
21
+ }, 500);
22
+ };
23
+ }
24
+ document.getElementById("applink1").onclick = applink(appstorefail);
25
+ var button = document.getElementById("applink1")
26
+ simulateClick("applink1");
27
+ function simulateClick(elId) {
28
+ var evt;
29
+ var el = document.getElementById(elId);
30
+ if (document.createEvent) {
31
+ evt = document.createEvent("MouseEvents");
32
+ evt.initMouseEvent("click", true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
33
+ }
34
+ (evt) ? el.dispatchEvent(evt) : (el.click && el.click());
35
+ }
data/views/error.haml ADDED
@@ -0,0 +1,11 @@
1
+ %h1 Whoops!
2
+
3
+ %p
4
+ There was an error processing your request:
5
+
6
+ %p
7
+ %blockquote
8
+ = @result
9
+
10
+ %p
11
+ %a(href='/') Go back
data/views/index.haml ADDED
@@ -0,0 +1 @@
1
+ %h3 Nothing to see here!
data/views/info.haml ADDED
@@ -0,0 +1,26 @@
1
+ %p.link
2
+ %a{ :href => "/" } &laquo; Back
3
+
4
+ %h1 http://#{@config[:hostname]}/#{@url.code}
5
+
6
+ %table
7
+ %tr
8
+ %td.label Short URL
9
+ %td.label Full URL
10
+ %td.label Clicks
11
+ %td.label Shortened at
12
+
13
+ %tr
14
+ %td.value
15
+ %input{ :type => "text", :value => short_url(@url), :class => 'short_url', :size => 21 }
16
+ %td.value.fill <a href="#{@url.url}">#{@url.url}</a>
17
+ %td.value.center= @url.clicks
18
+ %td.value= @url.created_at.strftime("%Y-%m-%d %H:%M")
19
+
20
+ :javascript
21
+ $(document).ready(function() {
22
+ $('input.short_url').each(function(index) {
23
+ $(this).mouseup(function() { $(this).select(); });
24
+ });
25
+ });
26
+
data/views/layout.haml ADDED
@@ -0,0 +1,28 @@
1
+ !!!
2
+ %html
3
+ %head
4
+ %title #{@title}
5
+ %meta(charset="UTF-8")
6
+ %link{ :rel=> "Shortcut Icon", :href=> u('favicon.ico') }
7
+ %link{ :rel => "stylesheet", :href => u('reset.css') }
8
+ %link{ :rel => "stylesheet", :href => u('style.css') }
9
+ %script{ :type => "text/javascript", :src => u('jquery-1.4.2.min.js') }
10
+
11
+ :javascript
12
+ var _gaq = _gaq || [];
13
+ _gaq.push(['_setAccount', 'UA-30261711-1']);
14
+ _gaq.push(['_trackPageview']);
15
+
16
+ (function() {var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
17
+ ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
18
+ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
19
+ })();
20
+ %body
21
+ .header
22
+ %h1= @title
23
+
24
+ #main
25
+ = yield
26
+
27
+ #footer
28
+ %p
@@ -0,0 +1,51 @@
1
+ <a id="applink1" href="#{@url.url}">Opening the awesome event now!</a>
2
+
3
+
4
+ :javascript
5
+
6
+ function simulateClick(elId) {
7
+ var evt;
8
+ var el = document.getElementById(elId);
9
+ if (document.createEvent) {
10
+ evt = document.createEvent("MouseEvents");
11
+ evt.initMouseEvent("click", true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);
12
+ }
13
+ (evt) ? el.dispatchEvent(evt) : (el.click && el.click());
14
+ }
15
+
16
+
17
+ var appstorefail = "itms://itunes.apple.com/us/app/tminus-make-share-countdown/id507726329?mt=8";
18
+ function applink(fail){
19
+ return function(){
20
+ var clickedAt = +new Date;
21
+ // During tests on 3g/3gs this timeout fires immediately if less than 500ms.
22
+ setTimeout(function(){
23
+ // To avoid failing on return to MobileSafari, ensure freshness!
24
+ if (+new Date - clickedAt < 2000){
25
+ window.location = fail;
26
+ }
27
+ }, 500);
28
+ };
29
+ }
30
+
31
+
32
+ var ref = document.referrer,
33
+ host = ref.split('/')[2],
34
+ regexp = /(www\.)?twitter.com/,
35
+ match = host.match(regexp);
36
+
37
+ if(ref && !regexp.test(location.host)) {
38
+
39
+ if(match) {
40
+ simulateClick("applink1");
41
+ }
42
+ else {
43
+
44
+ document.getElementById("applink1").onclick = applink(appstorefail);
45
+ var button = document.getElementById("applink1")
46
+ simulateClick("applink1");
47
+
48
+ }
49
+ window.location = ref;
50
+
51
+ }
metadata ADDED
@@ -0,0 +1,242 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: tmin_test
3
+ version: !ruby/object:Gem::Version
4
+ prerelease:
5
+ version: 0.0.1
6
+ platform: ruby
7
+ authors:
8
+ - drobs
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+
13
+ date: 2012-03-28 00:00:00 Z
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: sinatra
17
+ prerelease: false
18
+ requirement: &id001 !ruby/object:Gem::Requirement
19
+ none: false
20
+ requirements:
21
+ - - ~>
22
+ - !ruby/object:Gem::Version
23
+ version: 1.2.0
24
+ type: :runtime
25
+ version_requirements: *id001
26
+ - !ruby/object:Gem::Dependency
27
+ name: dm-core
28
+ prerelease: false
29
+ requirement: &id002 !ruby/object:Gem::Requirement
30
+ none: false
31
+ requirements:
32
+ - - ~>
33
+ - !ruby/object:Gem::Version
34
+ version: 1.2.0
35
+ type: :runtime
36
+ version_requirements: *id002
37
+ - !ruby/object:Gem::Dependency
38
+ name: dm-migrations
39
+ prerelease: false
40
+ requirement: &id003 !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ~>
44
+ - !ruby/object:Gem::Version
45
+ version: 1.2.0
46
+ type: :runtime
47
+ version_requirements: *id003
48
+ - !ruby/object:Gem::Dependency
49
+ name: dm-transactions
50
+ prerelease: false
51
+ requirement: &id004 !ruby/object:Gem::Requirement
52
+ none: false
53
+ requirements:
54
+ - - ~>
55
+ - !ruby/object:Gem::Version
56
+ version: 1.2.0
57
+ type: :runtime
58
+ version_requirements: *id004
59
+ - !ruby/object:Gem::Dependency
60
+ name: dm-aggregates
61
+ prerelease: false
62
+ requirement: &id005 !ruby/object:Gem::Requirement
63
+ none: false
64
+ requirements:
65
+ - - ~>
66
+ - !ruby/object:Gem::Version
67
+ version: 1.2.0
68
+ type: :runtime
69
+ version_requirements: *id005
70
+ - !ruby/object:Gem::Dependency
71
+ name: dm-mysql-adapter
72
+ prerelease: false
73
+ requirement: &id006 !ruby/object:Gem::Requirement
74
+ none: false
75
+ requirements:
76
+ - - ~>
77
+ - !ruby/object:Gem::Version
78
+ version: 1.2.0
79
+ type: :runtime
80
+ version_requirements: *id006
81
+ - !ruby/object:Gem::Dependency
82
+ name: haml
83
+ prerelease: false
84
+ requirement: &id007 !ruby/object:Gem::Requirement
85
+ none: false
86
+ requirements:
87
+ - - ~>
88
+ - !ruby/object:Gem::Version
89
+ version: 3.0.18
90
+ type: :runtime
91
+ version_requirements: *id007
92
+ - !ruby/object:Gem::Dependency
93
+ name: escape_utils
94
+ prerelease: false
95
+ requirement: &id008 !ruby/object:Gem::Requirement
96
+ none: false
97
+ requirements:
98
+ - - ~>
99
+ - !ruby/object:Gem::Version
100
+ version: 0.2.3
101
+ type: :runtime
102
+ version_requirements: *id008
103
+ - !ruby/object:Gem::Dependency
104
+ name: rspec
105
+ prerelease: false
106
+ requirement: &id009 !ruby/object:Gem::Requirement
107
+ none: false
108
+ requirements:
109
+ - - ~>
110
+ - !ruby/object:Gem::Version
111
+ version: 2.5.0
112
+ type: :development
113
+ version_requirements: *id009
114
+ - !ruby/object:Gem::Dependency
115
+ name: rack-test
116
+ prerelease: false
117
+ requirement: &id010 !ruby/object:Gem::Requirement
118
+ none: false
119
+ requirements:
120
+ - - ~>
121
+ - !ruby/object:Gem::Version
122
+ version: 0.5.4
123
+ type: :development
124
+ version_requirements: *id010
125
+ - !ruby/object:Gem::Dependency
126
+ name: dm-sqlite-adapter
127
+ prerelease: false
128
+ requirement: &id011 !ruby/object:Gem::Requirement
129
+ none: false
130
+ requirements:
131
+ - - ~>
132
+ - !ruby/object:Gem::Version
133
+ version: 1.2.0
134
+ type: :development
135
+ version_requirements: *id011
136
+ - !ruby/object:Gem::Dependency
137
+ name: database_cleaner
138
+ prerelease: false
139
+ requirement: &id012 !ruby/object:Gem::Requirement
140
+ none: false
141
+ requirements:
142
+ - - ~>
143
+ - !ruby/object:Gem::Version
144
+ version: 0.6.6
145
+ type: :development
146
+ version_requirements: *id012
147
+ description: tminusit is your own personal URL shortener for your own domain. It's written in Ruby and powered by Sinatra. You can run it with any Rack-capable web server.
148
+ email:
149
+ - duggan@uncarbonatedsoftware.com
150
+ executables: []
151
+
152
+ extensions: []
153
+
154
+ extra_rdoc_files: []
155
+
156
+ files:
157
+ - .DS_Store
158
+ - .document
159
+ - .gitignore
160
+ - Gemfile
161
+ - Gemfile.lock
162
+ - LICENSE.txt
163
+ - README.rdoc
164
+ - Rakefile
165
+ - config.ru.example
166
+ - firefly.sqlite3
167
+ - lib/tmin.rb
168
+ - lib/tmin/base62.rb
169
+ - lib/tmin/code_factory.rb
170
+ - lib/tmin/config.rb
171
+ - lib/tmin/server.rb
172
+ - lib/tmin/url.rb
173
+ - lib/tmin/version.rb
174
+ - public/.DS_Store
175
+ - public/favicon.ico
176
+ - public/images/ec_background.gif
177
+ - public/images/twitter.png
178
+ - public/jquery-1.4.2.min.js
179
+ - public/reset.css
180
+ - public/style.css
181
+ - spec/firefly/api_spec.rb
182
+ - spec/firefly/base62_spec.rb
183
+ - spec/firefly/code_factory_spec.rb
184
+ - spec/firefly/server_spec.rb
185
+ - spec/firefly/sharing_facebook_spec.rb
186
+ - spec/firefly/sharing_hyves_spec.rb
187
+ - spec/firefly/sharing_twitter_spec.rb
188
+ - spec/firefly/url_spec.rb
189
+ - spec/fixtures/urls.yml
190
+ - spec/spec.opts
191
+ - spec/spec_helper.rb
192
+ - test/helper.rb
193
+ - test/test_tmin.rb
194
+ - tmin_test.gemspec
195
+ - views/admin.haml
196
+ - views/ec.haml
197
+ - views/error.haml
198
+ - views/index.haml
199
+ - views/info.haml
200
+ - views/layout.haml
201
+ - views/redirect.haml
202
+ homepage: http://uncarbonatedsoftware.com
203
+ licenses: []
204
+
205
+ post_install_message:
206
+ rdoc_options: []
207
+
208
+ require_paths:
209
+ - lib
210
+ required_ruby_version: !ruby/object:Gem::Requirement
211
+ none: false
212
+ requirements:
213
+ - - ">="
214
+ - !ruby/object:Gem::Version
215
+ version: "0"
216
+ required_rubygems_version: !ruby/object:Gem::Requirement
217
+ none: false
218
+ requirements:
219
+ - - ">="
220
+ - !ruby/object:Gem::Version
221
+ version: "0"
222
+ requirements: []
223
+
224
+ rubyforge_project: tminusit
225
+ rubygems_version: 1.8.21
226
+ signing_key:
227
+ specification_version: 3
228
+ summary: tminusit is your own personal URL shortener for your own domain.
229
+ test_files:
230
+ - spec/firefly/api_spec.rb
231
+ - spec/firefly/base62_spec.rb
232
+ - spec/firefly/code_factory_spec.rb
233
+ - spec/firefly/server_spec.rb
234
+ - spec/firefly/sharing_facebook_spec.rb
235
+ - spec/firefly/sharing_hyves_spec.rb
236
+ - spec/firefly/sharing_twitter_spec.rb
237
+ - spec/firefly/url_spec.rb
238
+ - spec/fixtures/urls.yml
239
+ - spec/spec.opts
240
+ - spec/spec_helper.rb
241
+ - test/helper.rb
242
+ - test/test_tmin.rb