erkki-bitly 0.3.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,48 @@
1
+ === 0.3 / 2009-07-09
2
+
3
+ * 1 major enhancement
4
+
5
+ * a full set of tests, properly mocked
6
+
7
+ * 1 minor enhancement
8
+
9
+ * calling bitly.shorten(:history => 1) will add the url to the api user's history.
10
+
11
+ * 1 bug fix
12
+
13
+ * you can no longer call shorten with a keyword, this was unsupported in the API and consequently removed
14
+
15
+ === 0.2 / 2009-06-23
16
+
17
+ * 1 enhancement
18
+
19
+ * Depends on Crack instead of JSON, so can run on Jruby
20
+
21
+ * 1 bug fix
22
+
23
+ * Does not choke when bit.ly chokes. Returns a BitlyError instead
24
+
25
+ === 0.1.4 / 2009-04-13
26
+
27
+ * 1 bug fix
28
+
29
+ * Urls with parameters were choking, changed to using CGI.
30
+
31
+ === 0.1.2 / 2009-03-12
32
+
33
+ * 1 minor enhancement
34
+
35
+ * Allows to add a keyword for shortening urls
36
+
37
+ === 0.1.1 / 2009-01-26
38
+
39
+ * 1 bug fix
40
+
41
+ * Didn't include dependency on JSON
42
+
43
+ === 0.1.0 / 2009-01-26
44
+
45
+ * 1 major enhancement
46
+
47
+ * First release
48
+
@@ -0,0 +1,11 @@
1
+ bitly.gemspec
2
+ History.txt
3
+ lib/bitly/client.rb
4
+ lib/bitly/url.rb
5
+ lib/bitly/utils.rb
6
+ lib/bitly/version.rb
7
+ lib/bitly.rb
8
+ Manifest
9
+ Rakefile
10
+ README.txt
11
+ test/test_bitly.rb
@@ -0,0 +1,65 @@
1
+ = bitly
2
+
3
+ == DESCRIPTION:
4
+
5
+ A Ruby API for bit.ly
6
+
7
+ http://code.google.com/p/bitly-api/wiki/ApiDocumentation
8
+
9
+ == INSTALLATION:
10
+
11
+ gem install bitly
12
+
13
+ == USAGE:
14
+
15
+ Create a Bitly client using your username and api key as follows:
16
+
17
+ bitly = Bitly.new(username, api_key)
18
+
19
+ You can then use that client to shorten or expand urls or return more information or statistics as so:
20
+
21
+ bitly.shorten('http://www.google.com')
22
+ bitly.shorten('http://www.google.com', :history => 1) # adds the url to the api user's history
23
+ bitly.expand('wQaT')
24
+ bitly.info('http://bit.ly/wQaT')
25
+ bitly.stats('http://bit.ly/wQaT')
26
+
27
+ Each can be used in all the methods described in the API docs, the shorten function, for example, takes a url or an array of urls.
28
+
29
+ All four functions return a Bitly::Url object (or an array of Bitly::Url objects if you supplied an array as the input). You can then get all the information required from that object.
30
+
31
+ u = bitly.shorten('http://www.google.com') #=> Bitly::Url
32
+
33
+ u.long_url #=> "http://www.google.com"
34
+ u.short_url #=> "http://bit.ly/Ywd1"
35
+ u.user_hash #=> "Ywd1"
36
+ u.hash #=> "2V6CFi"
37
+ u.info #=> a ruby hash of the JSON returned from the API
38
+ u.stats #=> a ruby hash of the JSON returned from the API
39
+
40
+ bitly.shorten('http://www.google.com', 'keyword')
41
+
42
+ == LICENSE:
43
+
44
+ (The MIT License)
45
+
46
+ Copyright (c) 2009 Phil Nash
47
+
48
+ Permission is hereby granted, free of charge, to any person obtaining
49
+ a copy of this software and associated documentation files (the
50
+ 'Software'), to deal in the Software without restriction, including
51
+ without limitation the rights to use, copy, modify, merge, publish,
52
+ distribute, sublicense, and/or sell copies of the Software, and to
53
+ permit persons to whom the Software is furnished to do so, subject to
54
+ the following conditions:
55
+
56
+ The above copyright notice and this permission notice shall be
57
+ included in all copies or substantial portions of the Software.
58
+
59
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
60
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
61
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
62
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
63
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
64
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
65
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,19 @@
1
+ # -*- ruby -*-
2
+
3
+ require 'rubygems'
4
+ require 'rake'
5
+ require 'echoe'
6
+ require './lib/bitly.rb'
7
+
8
+ # modified by coryosborn to remove native JSON dependency
9
+
10
+ Echoe.new('bitly', Bitly::VERSION) do |p|
11
+ p.description = "Use the bit.ly API to shorten or expand URLs"
12
+ p.url = "http://github.com/philnash/bitly"
13
+ p.author = "Phil Nash"
14
+ p.email = "philnash@gmail.com"
15
+ p.extra_deps = [['crack', '>= 0.1.1']]
16
+ p.development_dependencies = []
17
+ end
18
+
19
+ # vim: syntax=Ruby
@@ -0,0 +1,34 @@
1
+ # -*- encoding: utf-8 -*-
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = %q{bitly}
5
+ s.version = "0.3.1"
6
+
7
+ s.required_rubygems_version = Gem::Requirement.new(">= 1.2") if s.respond_to? :required_rubygems_version=
8
+ s.authors = ["Phil Nash"]
9
+ s.date = %q{2009-07-09}
10
+ s.description = %q{Use the bit.ly API to shorten or expand URLs}
11
+ s.email = %q{philnash@gmail.com}
12
+ s.extra_rdoc_files = ["lib/bitly/client.rb", "lib/bitly/url.rb", "lib/bitly/utils.rb", "lib/bitly/version.rb", "lib/bitly.rb", "README.txt"]
13
+ s.files = ["bitly.gemspec", "History.txt", "lib/bitly/client.rb", "lib/bitly/url.rb", "lib/bitly/utils.rb", "lib/bitly/version.rb", "lib/bitly.rb", "Manifest", "Rakefile", "README.txt", "test/test_bitly.rb", "test/bitly/test_client.rb", "test/bitly/test_url.rb", "test/bitly/test_utils.rb", "test/test_helper.rb"]
14
+ s.homepage = %q{http://github.com/philnash/bitly}
15
+ s.rdoc_options = ["--line-numbers", "--inline-source", "--title", "Bitly", "--main", "README.txt"]
16
+ s.require_paths = ["lib"]
17
+ s.rubyforge_project = %q{bitly}
18
+ s.rubygems_version = %q{1.3.4}
19
+ s.summary = %q{Use the bit.ly API to shorten or expand URLs}
20
+ s.test_files = ["test/bitly/test_client.rb", "test/bitly/test_url.rb", "test/bitly/test_utils.rb", "test/test_bitly.rb", "test/test_helper.rb"]
21
+
22
+ if s.respond_to? :specification_version then
23
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
24
+ s.specification_version = 3
25
+
26
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
27
+ s.add_runtime_dependency(%q<crack>, [">= 0.1.1"])
28
+ else
29
+ s.add_dependency(%q<crack>, [">= 0.1.1"])
30
+ end
31
+ else
32
+ s.add_dependency(%q<crack>, [">= 0.1.1"])
33
+ end
34
+ end
@@ -0,0 +1,10 @@
1
+ $:.unshift File.dirname(__FILE__)
2
+
3
+ require 'rubygems'
4
+ gem 'crack'
5
+ require 'crack'
6
+
7
+ require 'bitly/utils'
8
+ require 'bitly/client'
9
+ require 'bitly/url'
10
+ require 'bitly/version'
@@ -0,0 +1,150 @@
1
+ require 'rubygems'
2
+ require 'net/http'
3
+ require 'uri'
4
+
5
+ module Bitly
6
+ API_URL = 'http://api.bit.ly/'
7
+ API_VERSION = '2.0.1'
8
+
9
+ def self.new(login, api_key)
10
+ Bitly::Client.new(login,api_key)
11
+ end
12
+
13
+ class Client
14
+
15
+ include Bitly::Utils
16
+
17
+ def initialize(login,api_key)
18
+ @login = login
19
+ @api_key = api_key
20
+ end
21
+
22
+ def shorten(input, opts={})
23
+ if input.is_a? String
24
+ request = create_url("shorten", :longUrl => input, :history => (opts[:history] ? 1 : nil))
25
+ result = get_result(request)
26
+ result = {:long_url => input}.merge result[input]
27
+ Bitly::Url.new(@login,@api_key,result)
28
+ elsif input.is_a? Array
29
+ request = create_url("shorten", :history => (opts[:history] ? 1 : nil))
30
+ request.query << "&" + input.map { |long_url| "longUrl=#{CGI.escape(long_url)}" }.join("&") unless input.nil?
31
+ result = get_result(request)
32
+ input.map do |long_url|
33
+ new_url = {:long_url => long_url}.merge result[long_url]
34
+ long_url = Bitly::Url.new(@login,@api_key,new_url)
35
+ end
36
+ else
37
+ raise ArgumentError.new("Shorten requires either a url or an array of urls")
38
+ end
39
+ end
40
+
41
+ def expand(input)
42
+ if input.is_a? String
43
+ if input.include? "bit.ly/"
44
+ hash = create_hash_from_url(input)
45
+ request = create_url "expand", :hash => hash
46
+ result = get_result(request)
47
+ result = { :short_url => input, :hash => hash }.merge result[hash]
48
+ else
49
+ request = create_url "expand", :hash => input
50
+ result = get_result(request)
51
+ result = { :hash => input, :short_url => "http://bit.ly/#{input}" }.merge result[input]
52
+ end
53
+ Bitly::Url.new(@login,@api_key,result)
54
+ elsif input.is_a? Array
55
+ request = create_url "expand", :hash => input.join(',')
56
+ result = get_result(request)
57
+ input.map do |hsh|
58
+ new_url = {:hash => hsh, :short_url => "http://bit.ly/#{hsh}"}.merge result[hsh]
59
+ hsh = Bitly::Url.new(@login,@api_key,new_url)
60
+ end
61
+ else
62
+ raise ArgumentError('Expand requires either a short url, a hash or an array of hashes')
63
+ end
64
+ end
65
+
66
+ def info(input)
67
+ if input.is_a? String
68
+ if input.include? "bit.ly/"
69
+ hash = create_hash_from_url(input)
70
+ request = create_url 'info', :hash => hash
71
+ result = get_result(request)
72
+ result = { :short_url => "http://bit.ly/#{hash}", :hash => hash }.merge result[hash]
73
+ else
74
+ request = create_url 'info', :hash => input
75
+ result = get_result(request)
76
+ result = { :short_url => "http://bit.ly/#{input}", :hash => input }.merge result[input]
77
+ end
78
+ Bitly::Url.new(@login,@api_key,result)
79
+ elsif input.is_a? Array
80
+ request = create_url "info", :hash => input.join(',')
81
+ result = get_result(request)
82
+ input.map do |hsh|
83
+ new_url = {:hash => hsh, :short_url => "http://bit.ly/#{hsh}"}.merge result[hsh]
84
+ hsh = Bitly::Url.new(@login,@api_key,:info => new_url)
85
+ end
86
+ else
87
+ raise ArgumentError.new('Info requires either a short url, a hash or an array of hashes')
88
+ end
89
+ end
90
+
91
+ def stats(input)
92
+ if input.is_a? String
93
+ if input.include? "bit.ly/"
94
+ hash = create_hash_from_url(input)
95
+ request = create_url 'stats', :hash => hash
96
+ result = get_result(request)
97
+ result = { :short_url => "http://bit.ly/#{hash}", :hash => hash }.merge result
98
+ else
99
+ request = create_url 'stats', :hash => input
100
+ result = get_result(request)
101
+ result = { :short_url => "http://bit.ly/#{input}", :hash => input }.merge result
102
+ end
103
+ Bitly::Url.new(@login,@api_key,:stats => result)
104
+ else
105
+ raise ArgumentError.new("Stats requires either a short url or a hash")
106
+ end
107
+ end
108
+
109
+ end
110
+
111
+ end
112
+
113
+ class BitlyError < StandardError
114
+ attr_reader :code
115
+ alias :msg :message
116
+ def initialize(msg, code)
117
+ @code = code
118
+ super("#{msg} - '#{code}'")
119
+ end
120
+ end
121
+
122
+
123
+ # How it should work
124
+ # ==================
125
+ # bitly = Bitly::Base.new('philnash','R_7776acc394294b2b0ad2c261a91c483d')
126
+ # bitly.shorten("http://www.google.com")
127
+ # #=> Bitly::Url
128
+ # bitly.shorten(["http://www.google.com","http://cnn.com"])
129
+ # #=> [Bitly::Url,Bitly::Url]
130
+ #
131
+ # bitly.expand("http://bit.ly/wIRm")
132
+ # #=> Bitly::Url
133
+ # bitly.expand("wIRm")
134
+ # #=> Bitly::Url
135
+ # bitly.expand(["wIRm","sdfsd"])
136
+ # #=> [Bitly::Url,Bitly::Url]
137
+ #
138
+ # bitly.info("http://bit.ly/wIRm") || bitly.info("wIRm")
139
+ # #=> b = Bitly::Url
140
+ # #=> b.info #=> hash of data back from info
141
+ # bitly.info(['wIRm','qsads'])
142
+ # #=> [Bitly::Url, Bitly::Url]
143
+ # also, with any url = Bitly::Url
144
+ # url.info #=> hash of info data
145
+
146
+ # bitly.stats("http://bit.ly/wIRm") || bitly.stats("wIRm")
147
+ # #=> b = Bitly::Url
148
+ # #=> b.stats #=> hash of stats
149
+ # also, any url = Bitly::Url
150
+ # url.stats #=> hash of stats
@@ -0,0 +1,97 @@
1
+ module Bitly
2
+
3
+ class Url
4
+ include Bitly::Utils
5
+
6
+ attr_accessor :long_url, :short_url, :hash, :user_hash
7
+ attr_reader :info, :stats
8
+ VARIABLES = ['long_url', 'short_url', 'hash', 'user_hash']
9
+
10
+ def initialize(login,api_key,obj=nil)
11
+ unless obj.nil?
12
+ raise BitlyError.new(result['errorMessage'],result['errorCode']) if obj['statusCode'] == "ERROR"
13
+ instance_variablise(obj, VARIABLES)
14
+ @info = obj[:info] if obj[:info]
15
+ @stats = obj[:stats] if obj[:stats]
16
+ end
17
+ @login = login
18
+ @api_key = api_key
19
+ raise ArgumentError.new("Please provide a login and api_key") if @login.nil? || @api_key.nil?
20
+ end
21
+
22
+ def shorten(opts = {})
23
+ return @short_url if @short_url
24
+ unless @long_url.nil?
25
+ request = create_url("shorten", :longUrl => @long_url, :history => (opts[:history] ? 1 : nil))
26
+ result = get_result(request)[@long_url.gsub(/\/$/,'')]
27
+ if result['statusCode'] == "ERROR"
28
+ raise BitlyError.new(result['errorMessage'],result['errorCode'])
29
+ else
30
+ instance_variablise(result,VARIABLES)
31
+ return @short_url
32
+ end
33
+ else
34
+ raise ArgumentError.new("You need a long_url in order to shorten it")
35
+ end
36
+ end
37
+
38
+ def expand
39
+ return @long_url if @long_url
40
+ unless !(@short_url || @hash)
41
+ unless @hash
42
+ @hash = create_hash_from_url(@short_url)
43
+ end
44
+ request = create_url("expand", :hash => @hash)
45
+ result = get_result(request)[@hash]
46
+ if result['statusCode'] == "ERROR"
47
+ raise BitlyError.new(result['errorMessage'],result['errorCode'])
48
+ else
49
+ instance_variablise(result,VARIABLES)
50
+ return @long_url
51
+ end
52
+ else
53
+ raise ArgumentError.new("You need a short_url or a hash in order to expand it")
54
+ end
55
+ end
56
+
57
+ def info
58
+ if @info.nil?
59
+ if @hash
60
+ request = create_url "info", :hash => @hash
61
+ result = get_result(request)[@hash]
62
+ instance_variablise(result, VARIABLES)
63
+ @info = result
64
+ elsif @short_url
65
+ @hash = create_hash_from_url(@short_url)
66
+ request = create_url "info", :hash => hash
67
+ result = get_result(request)[hash]
68
+ instance_variablise(result, VARIABLES)
69
+ @info = result
70
+ else
71
+ raise ArgumentError.new("You need a hash or short_url in order to get info")
72
+ end
73
+ return @info
74
+ else
75
+ @info
76
+ end
77
+ end
78
+
79
+ def stats
80
+ if @stats.nil?
81
+ if @hash
82
+ request = create_url "stats", :hash => @hash
83
+ elsif @short_url
84
+ @hash = create_hash_from_url(@short_url)
85
+ request = create_url "stats", :hash => @hash
86
+ else
87
+ raise ArgumentError.new("You need a hash or short_url in order to get stats")
88
+ end
89
+ @stats = get_result(request)
90
+ else
91
+ @stats
92
+ end
93
+ end
94
+
95
+ end
96
+
97
+ end
@@ -0,0 +1,58 @@
1
+ require 'cgi'
2
+
3
+ module Bitly
4
+ module Utils
5
+ def underscore(camel_cased_word) # stolen from rails
6
+ camel_cased_word.to_s.gsub(/::/, '/').
7
+ gsub(/([A-Z]+)([A-Z][a-z])/,'\1_\2').
8
+ gsub(/([a-z\d])([A-Z])/,'\1_\2').
9
+ tr("-", "_").
10
+ downcase
11
+ end
12
+
13
+ def create_hash_from_url(url)
14
+ url.gsub(/^.*bit.ly\//,'')
15
+ end
16
+
17
+ def attr_define(k,v)
18
+ instance_variable_set("@#{k}", v)
19
+ meta = class << self; self; end
20
+ meta.class_eval { attr_reader k.to_sym }
21
+ end
22
+
23
+ def instance_variablise(obj,variables)
24
+ if obj.is_a? Hash
25
+ obj.each do |k,v|
26
+ if v.is_a? Hash
27
+ instance_variablise(v,variables)
28
+ else
29
+ attr_define(underscore(k),v) if variables.include?(underscore(k))
30
+ end
31
+ end
32
+ end
33
+ end
34
+
35
+ def create_url(resource="",args={})
36
+ args = args.merge({:login => @login, :apiKey => @api_key, :version => API_VERSION})
37
+ url = URI.join(API_URL,resource)
38
+ long_urls = args.delete(:long_urls)
39
+ url.query = args.map { |k,v| "%s=%s" % [CGI.escape(k.to_s), CGI.escape(v.to_s)] }.join("&")
40
+ url.query << "&" + long_urls.map { |long_url| "longUrl=#{CGI.escape(long_url)}" }.join("&") unless long_urls.nil?
41
+ url
42
+ end
43
+
44
+ def get_result(request)
45
+ begin
46
+ result = Crack::JSON.parse(Net::HTTP.get(request))
47
+ rescue
48
+ result = {'errorMessage' => 'JSON Parse Error(Bit.ly messed up)', 'errorCode' => 69, 'statusCode' => 'ERROR'}
49
+ end
50
+ if result['statusCode'] == "OK"
51
+ result = result['results']
52
+ else
53
+ raise BitlyError.new(result['errorMessage'],result['errorCode'])
54
+ end
55
+ end
56
+
57
+ end
58
+ end
@@ -0,0 +1,3 @@
1
+ module Bitly
2
+ VERSION = '0.3'
3
+ end
@@ -0,0 +1,187 @@
1
+ require File.join(File.dirname(__FILE__), '..', 'test_helper.rb')
2
+
3
+ class TestClient < Test::Unit::TestCase
4
+ context "bitly module" do
5
+ should "create a new bitly client" do
6
+ b = Bitly.new(login, api_key)
7
+ assert_equal Bitly::Client, b.class
8
+ end
9
+ end
10
+ context "using the bitly client" do
11
+ setup do
12
+ @bitly = Bitly.new(login, api_key)
13
+ end
14
+
15
+ context "shortening" do
16
+ context "a single link" do
17
+ setup do
18
+ stub_get(/^http:\/\/api.bit.ly\/shorten\?.*longUrl=.*cnn.com.*$/,"cnn.json")
19
+ @url = @bitly.shorten('http://cnn.com')
20
+ end
21
+ should "return a Bitly::Url" do
22
+ assert_kind_of Bitly::Url, @url
23
+ end
24
+ should "return a short bitly url" do
25
+ assert_equal "http://bit.ly/15DlK", @url.short_url
26
+ end
27
+ should "save the long url" do
28
+ assert_equal "http://cnn.com", @url.long_url
29
+ end
30
+ end
31
+ context "multiple links" do
32
+ setup do
33
+ stub_get(/^http:\/\/api.bit.ly\/shorten\?.*longUrl=.*longUrl=.*$/,"cnn_and_google.json")
34
+ @urls = @bitly.shorten(['http://cnn.com', 'http://google.com'])
35
+ end
36
+ should "return an array of Bitly::Urls" do
37
+ assert_kind_of Array, @urls
38
+ assert_kind_of Bitly::Url, @urls[0]
39
+ end
40
+ should "shorten the urls in order" do
41
+ assert_equal "http://bit.ly/15DlK", @urls[0].short_url
42
+ assert_equal "http://bit.ly/11etr", @urls[1].short_url
43
+ end
44
+ should "save the long urls" do
45
+ assert_equal "http://cnn.com", @urls[0].long_url
46
+ assert_equal "http://google.com", @urls[1].long_url
47
+ end
48
+ end
49
+ context "no links" do
50
+ should "raise an ArgumentError" do
51
+ assert_raise ArgumentError do
52
+ @bitly.shorten
53
+ end
54
+ end
55
+ end
56
+ end
57
+ context "expanding" do
58
+ context "a hash" do
59
+ setup do
60
+ stub_get(/^http:\/\/api.bit.ly\/expand\?.*hash=31IqMl.*$/,"expand_cnn.json")
61
+ @url = @bitly.expand("31IqMl")
62
+ end
63
+ should "return a Bitly::Url" do
64
+ assert_kind_of Bitly::Url, @url
65
+ end
66
+ should "return the expanded url" do
67
+ assert_equal "http://cnn.com/", @url.long_url
68
+ end
69
+ should "save the hash" do
70
+ assert_equal "31IqMl", @url.hash
71
+ end
72
+ should "save the short url" do
73
+ assert_equal "http://bit.ly/31IqMl", @url.short_url
74
+ end
75
+ end
76
+ context "a short url" do
77
+ setup do
78
+ stub_get(/^http:\/\/api.bit.ly\/expand\?.*hash=31IqMl.*$/,"expand_cnn.json")
79
+ @url = @bitly.expand("http://bit.ly/31IqMl")
80
+ end
81
+ should "return a Bitly::Url" do
82
+ assert_kind_of Bitly::Url, @url
83
+ end
84
+ should "return the expanded url" do
85
+ assert_equal "http://cnn.com/", @url.long_url
86
+ end
87
+ should "save the hash" do
88
+ assert_equal "31IqMl", @url.hash
89
+ end
90
+ should "save the short url" do
91
+ assert_equal "http://bit.ly/31IqMl", @url.short_url
92
+ end
93
+ end
94
+ context "multiple hashes" do
95
+ setup do
96
+ stub_get(/^http:\/\/api.bit.ly\/expand\?.*hash=15DlK.*3j4ir4.*$/,"expand_cnn_and_google.json")
97
+ @urls = @bitly.expand(["15DlK","3j4ir4"])
98
+ end
99
+ should "return an array of Bitly::Urls" do
100
+ assert_kind_of Array, @urls
101
+ assert_kind_of Bitly::Url, @urls[0]
102
+ assert_kind_of Bitly::Url, @urls[1]
103
+ end
104
+ should "expand the hashes in order" do
105
+ assert_equal "http://cnn.com/", @urls[0].long_url
106
+ assert_equal "http://google.com/", @urls[1].long_url
107
+ end
108
+ should "save the hash to each url" do
109
+ assert_equal "15DlK", @urls[0].hash
110
+ assert_equal "3j4ir4", @urls[1].hash
111
+ end
112
+ end
113
+ end
114
+ context "to get info on" do
115
+ context "a single link" do
116
+ setup do
117
+ stub_get(/^http:\/\/api.bit.ly\/info\?.*hash=3j4ir4.*$/,"google_info.json")
118
+ @url = @bitly.info('http://bit.ly/3j4ir4')
119
+ end
120
+ should "return a Bitly::Url" do
121
+ assert_kind_of Bitly::Url, @url
122
+ end
123
+ should "return an info object with the url" do
124
+ assert_not_nil @url.info
125
+ end
126
+ end
127
+ context "a single hash" do
128
+ setup do
129
+ stub_get(/^http:\/\/api.bit.ly\/info\?.*hash=3j4ir4.*$/,"google_info.json")
130
+ @url = @bitly.info('3j4ir4')
131
+ end
132
+ should "return a Bitly::Url" do
133
+ assert_kind_of Bitly::Url, @url
134
+ end
135
+ should "return an info object with the url" do
136
+ assert_not_nil @url.info
137
+ end
138
+ end
139
+ context "a list of hashes" do
140
+ setup do
141
+ stub_get(/^http:\/\/api.bit.ly\/info\?.*hash=3j4ir4.*31IqMl.*$/,"google_and_cnn_info.json")
142
+ @urls = @bitly.info(['3j4ir4','31IqMl'])
143
+ end
144
+ should "return a Bitly::Url" do
145
+ assert_kind_of Array, @urls
146
+ end
147
+ should "return an info object with the url" do
148
+ assert_not_nil @urls[0].info
149
+ assert_not_nil @urls[1].info
150
+ end
151
+ end
152
+ end
153
+ context "to get stats on" do
154
+ context "a single link" do
155
+ setup do
156
+ stub_get(/^http:\/\/api.bit.ly\/stats\?.*hash=3j4ir4.*$/,"google_stats.json")
157
+ @url = @bitly.stats('http://bit.ly/3j4ir4')
158
+ end
159
+ should "return a Bitly::Url" do
160
+ assert_kind_of Bitly::Url, @url
161
+ end
162
+ should "return an stats object" do
163
+ assert_not_nil @url.stats
164
+ end
165
+ end
166
+ context "a single hash" do
167
+ setup do
168
+ stub_get(/^http:\/\/api.bit.ly\/stats\?.*hash=3j4ir4.*$/,"google_stats.json")
169
+ @url = @bitly.stats('3j4ir4')
170
+ end
171
+ should "return a Bitly::Url" do
172
+ assert_kind_of Bitly::Url, @url
173
+ end
174
+ should "return an stats object" do
175
+ assert_not_nil @url.stats
176
+ end
177
+ end
178
+ context "a list of hashes" do
179
+ should "return an argument error" do
180
+ assert_raise ArgumentError do
181
+ @bitly.stats(['3j4ir4','31IqMl'])
182
+ end
183
+ end
184
+ end
185
+ end
186
+ end
187
+ end
@@ -0,0 +1,168 @@
1
+ require File.join(File.dirname(__FILE__), '..', 'test_helper.rb')
2
+
3
+ class TestUrl < Test::Unit::TestCase
4
+ context "a new Bitly::Url" do
5
+ should "require a login and api_key" do
6
+ assert_raise ArgumentError do Bitly::Url.new end
7
+ assert_raise ArgumentError do Bitly::Url.new(login) end
8
+ assert_raise ArgumentError do Bitly::Url.new(nil, api_key) end
9
+ assert_nothing_raised do
10
+ Bitly::Url.new(login, api_key)
11
+ Bitly::Url.new(login, api_key, :hash => '3j4ir4')
12
+ Bitly::Url.new(login, api_key, :short_url => 'http://bit.ly/3j4ir4')
13
+ Bitly::Url.new(login, api_key, :long_url => 'http://google.com/')
14
+ end
15
+ end
16
+ context "shortening" do
17
+ context "with a long url" do
18
+ setup do
19
+ stub_get(/^http:\/\/api.bit.ly\/shorten\?.*longUrl=.*cnn.com.*$/,"cnn.json")
20
+ @url = Bitly::Url.new(login, api_key, :long_url => 'http://cnn.com/')
21
+ end
22
+ should "return a short url" do
23
+ assert_equal "http://bit.ly/15DlK", @url.shorten
24
+ end
25
+ end
26
+ context "with no long url" do
27
+ setup do
28
+ @url = Bitly::Url.new(login, api_key)
29
+ end
30
+ should "raise an error" do
31
+ assert_raise ArgumentError do
32
+ @url.shorten
33
+ end
34
+ end
35
+ end
36
+ context "with a short url already" do
37
+ setup do
38
+ @url = Bitly::Url.new(login, api_key, :short_url => 'http://bit.ly/31IqMl')
39
+ flexmock(@url).should_receive(:create_url).never
40
+ end
41
+ should "not need to call the api" do
42
+ assert_equal "http://bit.ly/31IqMl", @url.shorten
43
+ end
44
+ end
45
+ end
46
+ context "expanding" do
47
+ context "with a hash" do
48
+ setup do
49
+ stub_get(/^http:\/\/api.bit.ly\/expand\?.*hash=31IqMl.*$/,"expand_cnn.json")
50
+ @url = Bitly::Url.new(login, api_key, :hash => '31IqMl')
51
+ end
52
+ should "return an expanded url" do
53
+ assert_equal "http://cnn.com/", @url.expand
54
+ end
55
+ end
56
+ context "with a short url" do
57
+ setup do
58
+ stub_get(/^http:\/\/api.bit.ly\/expand\?.*hash=31IqMl.*$/,"expand_cnn.json")
59
+ @url = Bitly::Url.new(login, api_key, :short_url => 'http://bit.ly/31IqMl')
60
+ end
61
+ should "return an expanded url" do
62
+ assert_equal "http://cnn.com/", @url.expand
63
+ end
64
+ end
65
+ context "with no short url or hash" do
66
+ setup do
67
+ @url = Bitly::Url.new(login, api_key)
68
+ end
69
+ should "raise an error" do
70
+ assert_raise ArgumentError do
71
+ @url.expand
72
+ end
73
+ end
74
+ end
75
+ context "with a long url already" do
76
+ setup do
77
+ @url = Bitly::Url.new(login, api_key, :long_url => 'http://google.com')
78
+ flexmock(@url).should_receive(:create_url).never
79
+ end
80
+ should "not need to call the api" do
81
+ assert_equal "http://google.com", @url.expand
82
+ end
83
+ end
84
+ end
85
+ context "info" do
86
+ context "with a hash" do
87
+ setup do
88
+ stub_get(/^http:\/\/api.bit.ly\/info\?.*hash=3j4ir4.*$/,"google_info.json")
89
+ @url = Bitly::Url.new(login, api_key, :hash => '3j4ir4')
90
+ end
91
+ should "return info" do
92
+ assert_equal "Google", @url.info['htmlTitle']
93
+ end
94
+ end
95
+ context "with a short url" do
96
+ setup do
97
+ stub_get(/^http:\/\/api.bit.ly\/info\?.*hash=3j4ir4.*$/,"google_info.json")
98
+ @url = Bitly::Url.new(login, api_key, :short_url => 'http://bit.ly/3j4ir4')
99
+ end
100
+ should "return an expanded url" do
101
+ assert_equal "Google", @url.info['htmlTitle']
102
+ end
103
+ end
104
+ context "without a short url or hash" do
105
+ setup do
106
+ @url = Bitly::Url.new(login, api_key, :long_url => 'http://google.com')
107
+ end
108
+ should "raise an error" do
109
+ assert_raise ArgumentError do
110
+ @url.info
111
+ end
112
+ end
113
+ end
114
+ context "with info already" do
115
+ setup do
116
+ stub_get(/^http:\/\/api.bit.ly\/info\?.*hash=3j4ir4.*$/,"google_info.json")
117
+ @url = Bitly::Url.new(login, api_key, :short_url => 'http://bit.ly/3j4ir4')
118
+ @url.info
119
+ end
120
+ should "not call the api twice" do
121
+ flexmock(@url).should_receive(:create_url).never
122
+ @url.info
123
+ end
124
+ end
125
+ end
126
+ context "stats" do
127
+ context "with a hash" do
128
+ setup do
129
+ stub_get(/^http:\/\/api.bit.ly\/stats\?.*hash=3j4ir4.*$/,"google_stats.json")
130
+ @url = Bitly::Url.new(login, api_key, :hash => '3j4ir4')
131
+ end
132
+ should "return info" do
133
+ assert_equal 2644, @url.stats['clicks']
134
+ end
135
+ end
136
+ context "with a short url" do
137
+ setup do
138
+ stub_get(/^http:\/\/api.bit.ly\/stats\?.*hash=3j4ir4.*$/,"google_stats.json")
139
+ @url = Bitly::Url.new(login, api_key, :short_url => 'http://bit.ly/3j4ir4')
140
+ end
141
+ should "return an expanded url" do
142
+ assert_equal 2644, @url.stats['clicks']
143
+ end
144
+ end
145
+ context "without a short url or hash" do
146
+ setup do
147
+ @url = Bitly::Url.new(login, api_key, :long_url => 'http://google.com')
148
+ end
149
+ should "raise an error" do
150
+ assert_raise ArgumentError do
151
+ @url.stats
152
+ end
153
+ end
154
+ end
155
+ context "with info already" do
156
+ setup do
157
+ stub_get(/^http:\/\/api.bit.ly\/stats\?.*hash=3j4ir4.*$/,"google_stats.json")
158
+ @url = Bitly::Url.new(login, api_key, :short_url => 'http://bit.ly/3j4ir4')
159
+ @url.stats
160
+ end
161
+ should "not call the api twice" do
162
+ flexmock(@url).should_receive(:create_url).never
163
+ @url.stats
164
+ end
165
+ end
166
+ end
167
+ end
168
+ end
@@ -0,0 +1,76 @@
1
+ require File.join(File.dirname(__FILE__), '..', 'test_helper.rb')
2
+
3
+ class TestUtils < Test::Unit::TestCase
4
+ include Bitly::Utils
5
+ API_VERSION = '2.0.1'
6
+
7
+ context "text utils" do
8
+ should "underscore a word" do
9
+ assert_equal "hello_world", underscore("HelloWorld")
10
+ end
11
+ should "create a hash from a short url" do
12
+ assert_equal "hello", create_hash_from_url("http://bit.ly/hello")
13
+ end
14
+ end
15
+
16
+ context "class utils" do
17
+ should "turn a key value pair into an instance variable" do
18
+ attr_define('hello','goodbye')
19
+ assert_equal @hello, "goodbye"
20
+ end
21
+
22
+ should "turn a hash into instance variables" do
23
+ instance_variablise({'hello' => 'goodbye'}, ['hello'])
24
+ assert_equal @hello, "goodbye"
25
+ end
26
+
27
+ should "not turn nonspecified variables into instance variables" do
28
+ instance_variablise({'hello' => 'goodbye'}, [])
29
+ assert_nil @hello
30
+ end
31
+ end
32
+
33
+ context "creating a url" do
34
+ setup do
35
+ @api_key = api_key
36
+ @login = login
37
+ end
38
+ should "contain all the basic information" do
39
+ url = create_url.to_s
40
+ assert url.include?('http://api.bit.ly/')
41
+ assert url.include?("version=#{API_VERSION}")
42
+ assert url.include?("apiKey=#{api_key}")
43
+ assert url.include?("login=#{login}")
44
+ end
45
+ should "contain the right resource" do
46
+ url = create_url('shorten').to_s
47
+ assert url.include?('/shorten')
48
+ end
49
+ should "contain extra parameters" do
50
+ url = create_url('shorten', :longUrl => 'http://google.com').to_s
51
+ assert url.include?("longUrl=#{CGI.escape('http://google.com')}")
52
+ end
53
+ end
54
+
55
+ context "fetching a url" do
56
+ context "successfully" do
57
+ setup do
58
+ stub_get("http://example.com","cnn.json")
59
+ end
60
+ should "return a json object successfully" do
61
+ result = get_result(URI.join("http://example.com"))
62
+ assert_equal Hash, result.class
63
+ end
64
+ end
65
+ context "unsuccessfully" do
66
+ setup do
67
+ stub_get("http://example.com", 'shorten_error.json')
68
+ end
69
+ should "raise BitlyError" do
70
+ assert_raise BitlyError do
71
+ result = get_result(URI.join("http://example.com"))
72
+ end
73
+ end
74
+ end
75
+ end
76
+ end
@@ -0,0 +1,81 @@
1
+ # require 'test/unit'
2
+ # require 'rubygems'
3
+ # require 'shoulda'
4
+ # require 'flexmock'
5
+ # require 'bitly'
6
+ #
7
+ # class TestBitly < Test::Unit::TestCase
8
+ #
9
+ # context "with a bitly client" do
10
+ # setup do
11
+ # @api_key = 'test_key'
12
+ # @login = 'test_account'
13
+ # @bitly = Bitly.new(@login,@api_key)
14
+ # end
15
+ #
16
+ # context "shortening" do
17
+ #
18
+ # context "a single url" do
19
+ # setup do
20
+ #
21
+ # end
22
+ # def test_returns_single_short_url
23
+ # url = @bitly.shorten("http://cnn.com")
24
+ # assert_kind_of Bitly::Url, url
25
+ # assert_equal "http://cnn.com", url.long_url
26
+ # assert_equal "http://bit.ly/15DlK", url.short_url
27
+ # end
28
+ #
29
+ # def test_shortens_multiple_urls
30
+ # urls = @bitly.shorten(["http://cnn.com","http://google.com"])
31
+ # assert_equal "http://cnn.com", urls[0].long_url
32
+ # assert_equal "http://bit.ly/15DlK", urls[0].short_url
33
+ # assert_equal "http://google.com", urls[1].long_url
34
+ # assert_equal "http://bit.ly/11etr", urls[1].short_url
35
+ # end
36
+ #
37
+ # def test_can_shorten_a_url_with_parameters
38
+ # url = @bitly.shorten("http://www.google.com/search?hl=en&q=url&btnG=Google+Search&aq=f&oq=")
39
+ # assert_kind_of Bitly::Url, url
40
+ # assert_equal "http://www.google.com/search?hl=en&q=url&btnG=Google+Search&aq=f&oq=", url.long_url
41
+ # assert_equal "http://bit.ly/NqK6i", url.short_url
42
+ # end
43
+ #
44
+ # def test_returns_a_long_url
45
+ # urls = @bitly.expand(["2bYgqR","1RmnUT"])
46
+ # assert_kind_of Bitly::Url, urls[0]
47
+ # assert_equal "http://cnn.com", urls[0].long_url
48
+ # assert_equal "2bYgqR", urls[0].hash
49
+ # assert_equal "http://google.com", urls[1].long_url
50
+ # assert_equal "1RmnUT", urls[1].hash
51
+ # url = @bitly.expand("http://bit.ly/wQaT")
52
+ # assert_kind_of Bitly::Url, url
53
+ # assert_equal "http://bit.ly/wQaT", url.short_url
54
+ # assert_equal "http://google.com/", url.long_url
55
+ # assert_equal "wQaT", url.hash
56
+ # url2 = @bitly.expand("wQaT")
57
+ # assert_kind_of Bitly::Url, url2
58
+ # assert_equal "wQaT", url2.hash
59
+ # assert_equal "http://bit.ly/wQaT", url2.short_url
60
+ # assert_equal "http://google.com/", url2.long_url
61
+ # end
62
+ #
63
+ # # def test_returns_keyword_url
64
+ # # #kind of ghetto test but we need it to be different every time
65
+ # # require 'digest/sha1'
66
+ # # keyword = Digest::SHA1.hexdigest(DateTime.now.to_s)
67
+ # #
68
+ # # url = @bitly.shorten("http://google.com", :keyword => keyword)
69
+ # # assert_equal url.short_keyword_url, "http://bit.ly/#{keyword}"
70
+ # # end
71
+ #
72
+ # def test_returns_error_on_existing_keyword
73
+ # keyword = 'apple'
74
+ # assert_raise BitlyError do
75
+ # @bitly.shorten("http://apple.com/itunes", :keyword => keyword)
76
+ # end
77
+ # end
78
+ #
79
+ #
80
+ #
81
+ # end
@@ -0,0 +1,29 @@
1
+ require 'test/unit'
2
+ require 'rubygems'
3
+ require 'shoulda'
4
+ require 'flexmock/test_unit'
5
+ require 'fakeweb'
6
+
7
+ require File.join(File.dirname(__FILE__), '..', 'lib', 'bitly')
8
+
9
+ FakeWeb.allow_net_connect = false
10
+
11
+ def fixture_file(filename)
12
+ return '' if filename == ''
13
+ file_path = File.expand_path(File.dirname(__FILE__) + '/fixtures/' + filename)
14
+ File.read(file_path)
15
+ end
16
+
17
+ def stub_get(url, filename, status=nil)
18
+ options = {:body => fixture_file(filename)}
19
+ options.merge!({:status => status}) unless status.nil?
20
+
21
+ FakeWeb.register_uri(:get, url, options)
22
+ end
23
+
24
+ def api_key
25
+ 'test_key'
26
+ end
27
+ def login
28
+ 'test_account'
29
+ end
metadata ADDED
@@ -0,0 +1,90 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: erkki-bitly
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.3.1
5
+ platform: ruby
6
+ authors:
7
+ - Phil Nash
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2009-07-09 00:00:00 -07:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: crack
17
+ type: :runtime
18
+ version_requirement:
19
+ version_requirements: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: 0.1.1
24
+ version:
25
+ description: Use the bit.ly API to shorten or expand URLs
26
+ email: philnash@gmail.com
27
+ executables: []
28
+
29
+ extensions: []
30
+
31
+ extra_rdoc_files:
32
+ - lib/bitly/client.rb
33
+ - lib/bitly/url.rb
34
+ - lib/bitly/utils.rb
35
+ - lib/bitly/version.rb
36
+ - lib/bitly.rb
37
+ - README.txt
38
+ files:
39
+ - bitly.gemspec
40
+ - History.txt
41
+ - lib/bitly/client.rb
42
+ - lib/bitly/url.rb
43
+ - lib/bitly/utils.rb
44
+ - lib/bitly/version.rb
45
+ - lib/bitly.rb
46
+ - Manifest
47
+ - Rakefile
48
+ - README.txt
49
+ - test/test_bitly.rb
50
+ - test/bitly/test_client.rb
51
+ - test/bitly/test_url.rb
52
+ - test/bitly/test_utils.rb
53
+ - test/test_helper.rb
54
+ has_rdoc: false
55
+ homepage: http://github.com/philnash/bitly
56
+ post_install_message:
57
+ rdoc_options:
58
+ - --line-numbers
59
+ - --inline-source
60
+ - --title
61
+ - Bitly
62
+ - --main
63
+ - README.txt
64
+ require_paths:
65
+ - lib
66
+ required_ruby_version: !ruby/object:Gem::Requirement
67
+ requirements:
68
+ - - ">="
69
+ - !ruby/object:Gem::Version
70
+ version: "0"
71
+ version:
72
+ required_rubygems_version: !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - - ">="
75
+ - !ruby/object:Gem::Version
76
+ version: "1.2"
77
+ version:
78
+ requirements: []
79
+
80
+ rubyforge_project: bitly
81
+ rubygems_version: 1.2.0
82
+ signing_key:
83
+ specification_version: 3
84
+ summary: Use the bit.ly API to shorten or expand URLs
85
+ test_files:
86
+ - test/bitly/test_client.rb
87
+ - test/bitly/test_url.rb
88
+ - test/bitly/test_utils.rb
89
+ - test/test_bitly.rb
90
+ - test/test_helper.rb