├── .rspec
├── .rvmrc
├── .gitignore
├── spec
├── spec_helper.rb
├── hackershout_spec.rb
└── hackershout
│ ├── provider
│ └── base_spec.rb
│ ├── provider_spec.rb
│ └── base_spec.rb
├── lib
├── hackershout
│ ├── version.rb
│ ├── output.rb
│ ├── provider
│ │ ├── hackernews.rb
│ │ ├── reddit.rb
│ │ ├── rubyflow.rb
│ │ └── base.rb
│ ├── provider.rb
│ └── base.rb
└── hackershout.rb
├── bin
└── hackershout
├── Gemfile
├── Rakefile
├── Guardfile
├── hackershout.gemspec
└── Readme.md
/.rspec:
--------------------------------------------------------------------------------
1 | --color
2 | --format documentation
3 |
--------------------------------------------------------------------------------
/.rvmrc:
--------------------------------------------------------------------------------
1 | rvm --create use ruby-1.9.2@hackershout
2 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | *.gem
2 | .bundle
3 | Gemfile.lock
4 | pkg/*
5 |
--------------------------------------------------------------------------------
/spec/spec_helper.rb:
--------------------------------------------------------------------------------
1 | require 'rspec'
2 | require 'hackershout'
3 |
--------------------------------------------------------------------------------
/lib/hackershout/version.rb:
--------------------------------------------------------------------------------
1 | module Hackershout
2 | VERSION = "0.2.0"
3 | end
4 |
--------------------------------------------------------------------------------
/bin/hackershout:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | $: << 'lib'
3 | require 'hackershout'
4 |
5 | Hackershout.run
6 |
--------------------------------------------------------------------------------
/Gemfile:
--------------------------------------------------------------------------------
1 | source "http://rubygems.org"
2 |
3 | # Specify your gem's dependencies in hackershout.gemspec
4 | gemspec
5 |
--------------------------------------------------------------------------------
/lib/hackershout/output.rb:
--------------------------------------------------------------------------------
1 | module Hackershout
2 | module Output
3 |
4 | def print(str)
5 | $stdout.print "\n" + str
6 | end
7 |
8 | def blank
9 | print "\n"
10 | end
11 |
12 | end
13 | end
14 |
--------------------------------------------------------------------------------
/Rakefile:
--------------------------------------------------------------------------------
1 | require 'bundler'
2 | Bundler::GemHelper.install_tasks
3 |
4 | require 'rspec/core'
5 | require 'rspec/core/rake_task'
6 | RSpec::Core::RakeTask.new(:spec) do |spec|
7 | spec.pattern = FileList['spec/**/*_spec.rb']
8 | end
9 |
10 | task :default => :spec
11 | task :test => [:spec]
12 |
--------------------------------------------------------------------------------
/Guardfile:
--------------------------------------------------------------------------------
1 | # A sample Guardfile
2 | # More info at https://github.com/guard/guard#readme
3 |
4 | guard 'rspec', :version => 2 do
5 | watch(/^spec\/(.*)_spec.rb/)
6 | watch(/^lib\/(.*)\.rb/) { |m| "spec/lib/#{m[1]}_spec.rb" }
7 | watch(/^spec\/spec_helper.rb/) { "spec" }
8 | end
9 |
--------------------------------------------------------------------------------
/spec/hackershout_spec.rb:
--------------------------------------------------------------------------------
1 | require 'spec_helper'
2 |
3 | describe Hackershout do
4 |
5 | describe ".run" do
6 | it 'calls run on a new Base instance' do
7 | Hackershout::Base.should_receive(:new).and_return(double(:base).tap { |b|
8 | b.should_receive(:run)
9 | })
10 | subject.run
11 | end
12 | end
13 |
14 | end
15 |
--------------------------------------------------------------------------------
/lib/hackershout.rb:
--------------------------------------------------------------------------------
1 | require 'hackershout/output'
2 | require 'hackershout/provider'
3 | require 'hackershout/provider/base'
4 | require 'hackershout/provider/reddit'
5 | require 'hackershout/provider/hackernews'
6 | require 'hackershout/provider/rubyflow'
7 | require 'hackershout/base'
8 |
9 | module Hackershout
10 | class << self
11 | def run
12 | Base.new.run
13 | end
14 | end
15 | end
16 |
--------------------------------------------------------------------------------
/lib/hackershout/provider/hackernews.rb:
--------------------------------------------------------------------------------
1 | module Hackershout
2 | module Provider
3 | class Hackernews < Base
4 |
5 | URL = {
6 | :login => 'http://news.ycombinator.com/submit'
7 | }
8 |
9 | def post
10 | page = agent.get(URL[:login])
11 | login_form = page.forms.first
12 | login_form.u = @login
13 | login_form.p = @password
14 | page = login_form.submit
15 | submit(page)
16 | end
17 |
18 | private
19 |
20 | def submit(submit_page)
21 | form = submit_page.forms.first
22 | form.t = @title
23 | form.u = @url
24 | form.submit
25 | end
26 |
27 | end
28 | end
29 | end
30 |
--------------------------------------------------------------------------------
/lib/hackershout/provider/reddit.rb:
--------------------------------------------------------------------------------
1 | module Hackershout
2 | module Provider
3 | class Reddit < Base
4 |
5 | URL = {
6 | :login => 'http://www.reddit.com/r/ruby/',
7 | :submit => 'http://www.reddit.com/r/ruby/submit',
8 | }
9 |
10 | # Not logging in! :(
11 | def post
12 | raise NotImplementedError
13 | page = agent.get(URL[:login])
14 | login_form = page.forms_with(:action => 'http://www.reddit.com/r/ruby/post/login').first
15 | login_form.user = @login
16 | login_form.passwd = @password
17 | page = login_form.submit
18 | puts page.links_with(:text => 'logout').inspect
19 | page = page.links_with(:text => 'Submit a link').first.click
20 | puts page.inspect
21 |
22 | rescue Mechanize::ResponseCodeError=>e
23 | puts "#{@name} is unavailable for now. Please try in a few minutes. The server gave the following reason:"
24 | puts e.inspect
25 | end
26 |
27 | end
28 | end
29 | end
30 |
--------------------------------------------------------------------------------
/lib/hackershout/provider/rubyflow.rb:
--------------------------------------------------------------------------------
1 | module Hackershout
2 | module Provider
3 | class Rubyflow < Base
4 |
5 | URL = {
6 | :login => 'http://www.rubyflow.com/login'
7 | }
8 |
9 | def post
10 | page = agent.get(URL[:login])
11 | login_form = page.form_with(:action => '/session')
12 | login_form.login = @login
13 | login_form.password = @password
14 | page = login_form.submit
15 | page = page.link_with(:href => /items\/new/).click
16 | submit(page)
17 | end
18 |
19 | private
20 |
21 | def submit(submit_page)
22 | form = submit_page.form_with(:action => '/items')
23 | form['item[title]'] = @title
24 | form['item[content]'] = process(@message)
25 | form.submit
26 | end
27 |
28 | def process(message)
29 | message.gsub!('', "")
30 | message.gsub!('', "")
31 | message
32 | end
33 |
34 | end
35 | end
36 | end
37 |
--------------------------------------------------------------------------------
/lib/hackershout/provider/base.rb:
--------------------------------------------------------------------------------
1 | require 'mechanize'
2 | require 'nokogiri'
3 |
4 | Mechanize.html_parser = Nokogiri::HTML
5 |
6 | module Hackershout
7 | module Provider
8 | class Base
9 | attr_reader :agent
10 |
11 | include Output
12 |
13 | def initialize(options = {})
14 | @name = self.class.name.split("::").last
15 | @url = options[:url] << "&utm_medium=#{@name.downcase}"
16 | @title = options[:title]
17 | @tags = options[:tags]
18 | @message = options[:message]
19 |
20 | creds = YAML.load(File.read(File.join(File.expand_path('~'), '.hackershoutrc')))[@name.downcase]
21 | raise "Can't find credentials on ~/.hackershoutrc for #{@name}" unless creds
22 |
23 | @login = creds["login"]
24 | @password = creds["password"]
25 | @agent = Mechanize.new
26 | end
27 |
28 | def publish
29 | print "Posting to #{@name}..."
30 | post unless ENV['NOSEND']
31 | print "Posted to #{@name}!"
32 | end
33 |
34 | def post
35 | raise NotImplementedError
36 | end
37 |
38 | end
39 | end
40 | end
41 |
--------------------------------------------------------------------------------
/hackershout.gemspec:
--------------------------------------------------------------------------------
1 | # -*- encoding: utf-8 -*-
2 | $:.push File.expand_path("../lib", __FILE__)
3 | require "hackershout/version"
4 |
5 | Gem::Specification.new do |s|
6 | s.name = "hackershout"
7 | s.version = Hackershout::VERSION
8 | s.platform = Gem::Platform::RUBY
9 | s.authors = ["Josep M. Bach", "Josep Jaume Rey", "Oriol Gual"]
10 | s.email = ["info@codegram.com"]
11 | s.homepage = "http://github.com/codegram/hackershout"
12 | s.summary = %q{Shout your hackerness! Promote your work on Reddit, Hackernews and Ruby Flow.}
13 | s.description = %q{Shout your hackerness! Promote your work on Reddit, Hackernews and Ruby Flow.}
14 |
15 | s.rubyforge_project = "hackershout"
16 |
17 | s.add_runtime_dependency 'nokogiri'
18 | s.add_runtime_dependency 'mechanize'
19 |
20 | s.add_development_dependency 'rspec', '~> 2.5.0'
21 | s.add_development_dependency 'guard'
22 | s.add_development_dependency 'guard-rspec'
23 | s.add_development_dependency 'rb-fsevent'
24 | s.add_development_dependency 'vcr'
25 |
26 | s.files = `git ls-files`.split("\n")
27 | s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
28 | s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
29 | s.require_paths = ["lib"]
30 | end
31 |
--------------------------------------------------------------------------------
/spec/hackershout/provider/base_spec.rb:
--------------------------------------------------------------------------------
1 | require 'spec_helper'
2 |
3 | module Hackershout
4 | module Provider
5 | describe Base do
6 |
7 | # Test only base class. Each provider only implements #post with pure Mechanize logic.
8 |
9 | before do
10 | File.stub(:read).and_return """
11 | base:
12 | login: my.email@gmail.com
13 | password: mypassword
14 | """
15 | end
16 |
17 | describe "#initialize" do
18 | it 'reads the credentials and stores them' do
19 | base = Base.new(:url => 'url',
20 | :tags => ['my', 'tags'],
21 | :message => 'message')
22 |
23 | base.instance_variable_get(:@login).should eq('my.email@gmail.com')
24 | base.instance_variable_get(:@password).should eq('mypassword')
25 | base.instance_variable_get(:@agent).should be_a(Mechanize)
26 | base.instance_variable_get(:@url).should == 'url&utm_medium=base'
27 | end
28 | end
29 |
30 | describe "#publish" do
31 | it 'logs in and posts' do
32 | base = Base.new(:url => 'url',
33 | :tags => ['my', 'tags'],
34 | :message => 'message')
35 |
36 | base.should_receive(:post)
37 |
38 | base.publish
39 | end
40 | end
41 |
42 | it 'crap' do
43 | File.stub(:read).and_return """
44 | hackernews:
45 | login: codegram
46 | password: codgamerP90
47 | """
48 | Hackernews.new(:title => 'my title', :message => 'my message', :url => 'http://google.com').post
49 | end
50 |
51 | end
52 | end
53 | end
54 |
--------------------------------------------------------------------------------
/lib/hackershout/provider.rb:
--------------------------------------------------------------------------------
1 | module Hackershout
2 | module Provider
3 | class << self
4 |
5 | include Output
6 |
7 | def list
8 | {
9 | # :reddit => 'Ruby Reddit',
10 | :hackernews => 'Hackernews',
11 | :rubyflow => 'RubyFlow',
12 | }
13 | end
14 |
15 | def wants?(provider)
16 | name = list[provider]
17 | print "\t#{name} (y/n)? "
18 | return case gets.chomp
19 | when 'y'
20 | check_credentials_for(provider)
21 | when 'n'
22 | false
23 | else
24 | blank
25 | print "I don't understand. Just type y for yes and n for no :)"
26 | wants?(provider)
27 | end
28 | end
29 |
30 | private
31 |
32 | def check_credentials_for(provider)
33 | credentials = if File.exists?(File.join(File.expand_path('~'), '.hackershoutrc'))
34 | YAML.load(File.read(File.join(File.expand_path('~'), '.hackershoutrc')))
35 | else
36 | ask_for_credentials(provider)
37 | end
38 |
39 | if credentials[provider.to_s] &&
40 | credentials[provider.to_s]["login"] &&
41 | credentials[provider.to_s]["password"]
42 | true
43 | else
44 | ask_for_credentials(provider)
45 | end
46 | end
47 |
48 | def ask_for_credentials(provider)
49 | print "Sorry, I don't have your #{list[provider]} credentials."
50 | print "\tLogin: "
51 | login = gets.chomp.strip
52 | system('stty -echo')
53 | print "\tPassword: "
54 | password = gets.chomp.strip
55 | system('stty echo')
56 | File.open(File.join(File.expand_path('~'), '.hackershoutrc'), 'a') do |file|
57 | file.write "\n#{provider}:"
58 | file.write "\n login: #{login}"
59 | file.write "\n password: #{password}"
60 | file.write "\n"
61 | end
62 | { provider => { "login" => login, "password" => password } }
63 | end
64 |
65 | end
66 | end
67 | end
68 |
--------------------------------------------------------------------------------
/lib/hackershout/base.rb:
--------------------------------------------------------------------------------
1 | require 'hackershout/output'
2 |
3 | module Hackershout
4 | class Base
5 | include Output
6 |
7 | def initialize(options = {})
8 | @url = options[:url]
9 | @title = options[:title]
10 | @message = options[:message]
11 | @tags = options[:tags] || []
12 | @providers = options[:providers] || []
13 | end
14 |
15 | def run
16 | welcome_banner
17 | @url = ask_for_url
18 | @title = ask_for_title
19 | @message = ask_for_message
20 | @tags = ask_for_tags
21 | providers_banner
22 |
23 | @providers = ask_for_providers
24 | post_to_providers
25 | end
26 |
27 | def welcome_banner
28 | print ":: Welcome to hackershout! ::"
29 | blank
30 | end
31 |
32 | def ask_for_url
33 | print "Type the URL you want to share: "
34 | gets.chomp.strip << "?utm_source=hackershout"
35 | end
36 |
37 | def ask_for_title
38 | print "Enter a brief, descriptive title: "
39 | gets.chomp.strip
40 | end
41 |
42 | def ask_for_message
43 | print "Bear in mind that some services may require a more extended text aside from the title."
44 | print "Type your message (two ENTERs to finish): "
45 | $/ = "\n\n"
46 | gets.chomp.strip.tap do
47 | # Restore EOM char
48 | $/ = "\n"
49 | end
50 | end
51 |
52 | def ask_for_tags
53 | print "Type some tags separated by comma (i.e. ruby, rails, bdd): "
54 | gets.chomp.strip.split(',').map(&:strip)
55 | end
56 |
57 | def providers_banner
58 | print "...Got it! Now where would you want to spread the word?"
59 | end
60 |
61 | def ask_for_providers
62 | Provider.list.keys.select do |provider|
63 | Provider.wants?(provider)
64 | end
65 | end
66 |
67 | def post_to_providers
68 | print "Fine."
69 | @providers.map do |provider|
70 | eval("Provider::#{provider.capitalize}").new({
71 | url: @url,
72 | title: @title,
73 | message: @message,
74 | tags: @tags,
75 | })
76 | end.each do |provider|
77 | provider.publish
78 | end
79 | puts "Done. Happy hacking! :)\n"
80 | end
81 |
82 | end
83 | end
84 |
--------------------------------------------------------------------------------
/spec/hackershout/provider_spec.rb:
--------------------------------------------------------------------------------
1 | require 'spec_helper'
2 |
3 | module Hackershout
4 | describe Provider do
5 |
6 | before do
7 | subject.stub(:list).and_return({
8 | :reddit => 'Ruby Reddit',
9 | :hackernews => 'Hackernews',
10 | :rubyflow => 'RubyFlow',
11 | })
12 | end
13 |
14 | describe "#wants?(provider)" do
15 | before do
16 | subject.should_receive(:print).with("\tRuby Reddit (y/n)? ")
17 | end
18 | context 'if the user wants to publish on a provider' do
19 | it 'checks the credentials' do
20 | subject.should_receive(:gets).and_return 'y'
21 | subject.should_receive(:check_credentials_for).with(:reddit)
22 | subject.wants?(:reddit)
23 | end
24 | end
25 | context 'if the user doesn\'t want' do
26 | it 'returns false' do
27 | subject.should_receive(:gets).and_return 'n'
28 | subject.wants?(:reddit).should be_false
29 | end
30 | end
31 | end
32 |
33 | describe "#check_credentials_for(provider)" do
34 |
35 | context 'if the credentials exist' do
36 | it 'returns true' do
37 | File.stub(:read).and_return "reddit:\n login: my.email@gmail.com\n password: mypassword"
38 | subject.should_not_receive(:ask_for_credentials)
39 | subject.send(:check_credentials_for, :reddit).should be_true
40 | end
41 | end
42 |
43 | context 'otherwise' do
44 | it 'asks for them' do
45 | File.stub(:read).and_return "hackernews:\n login: my.email@gmail.com\n password: mypassword"
46 | subject.should_receive(:ask_for_credentials).with(:reddit)
47 | subject.send(:check_credentials_for, :reddit)
48 | end
49 | end
50 |
51 | context "if the file doesn't even exist" do
52 | it 'asks for the credentials as well' do
53 | File.stub(:exists?).and_return false
54 | subject.should_receive(:ask_for_credentials).with(:reddit).and_return({"reddit" => {"login" => "login", "password" => "password"}})
55 | subject.send(:check_credentials_for, :reddit)
56 | end
57 | end
58 |
59 | end
60 |
61 | describe "#ask_for_credentials(provider)" do
62 | it 'asks for the credentials and saves them into ~/.hackershoutrc' do
63 | subject.stub(:print)
64 | file = double :file
65 | subject.should_receive(:gets).and_return 'my.email@gmail.com'
66 | subject.should_receive(:gets).and_return 'mypassword'
67 | File.should_receive(:open).and_yield file
68 |
69 | file.should_receive(:write).with "\nreddit:"
70 | file.should_receive(:write).with "\n login: my.email@gmail.com"
71 | file.should_receive(:write).with "\n password: mypassword"
72 | file.should_receive(:write).with "\n"
73 |
74 | subject.send(:ask_for_credentials, :reddit)
75 | end
76 | end
77 |
78 | end
79 | end
80 |
--------------------------------------------------------------------------------
/Readme.md:
--------------------------------------------------------------------------------
1 | #Hackershout
2 |
3 | Shout your hackerness to the world!
4 |
5 | Hackershout lets you promote your open-source work on the major Ruby (and geek
6 | related) community blogs (Reddit, Hackernews and RubyFlow) via a nice command
7 | line interface.
8 |
9 | ##Install
10 |
11 | $ gem install hackershout
12 |
13 | ##Known caveats
14 |
15 | Publishing to Reddit is not available yet.
16 |
17 | ##Notes
18 |
19 | Through hackershout you publish an **URL** and a **text**. To link the URL from
20 | the text you just have to use the special `` tag. Note that for certain
21 | sites, such as RubyFlow, you _have to link_ the URL from the text, since there
22 | is no separate URL field. Hackershout will omit the special tag where it
23 | doesn't need it (for example, in Reddit).
24 |
25 | You can add additional links with normal HTML `` tags.
26 |
27 | Given `http://rubygems.org/gems/my_gem` as an URL, an example of a message
28 | would be:
29 |
30 | Hey! I have released some awesome open-source gem that is
31 | going to save the world. Check it out! You can also grab the source code on
32 | Github if you want.
33 |
34 | This will publish in Reddit like this:
35 |
36 | URL: http://rubygems.org/gems/my_gem
37 | TEXT: Hey! I have released some awesome open-source gem that is going to
38 | save the world. Check it out! You can also grab the source code on
39 | Github if you want.
40 |
41 | And on RubyFlow (where there is no separate URL field) like this:
42 |
43 | TEXT: Hey! I have released some
44 | awesome open-source gem that is going to save the world. Check it out!
45 | You can also grab the source code on
46 | Github if you want.
47 |
48 | ##Usage
49 |
50 | $ hackershout
51 |
52 | :: Welcome to hackershout! ::
53 |
54 | Type the URL you want to share: http://rubygems.com/gems/my_gem
55 | Enter a brief, descriptive title: Released MyGem 1.0!
56 |
57 | Bear in mind that some services may require a more extended text aside from the title.
58 | Type your message (two ENTERs to finish):
59 | Hey! I have released some awesome open-source gem that is
60 | going to save the world. Check it out! You can also grab the source code
61 | on Github if you want.(enter)
62 | (enter)
63 | Type some tags separated by comma (i.e. ruby, rails, bdd): ruby, parsing
64 |
65 | ...Got it! Now where would you want to spread the word?
66 | Ruby Reddit (y/n)? y
67 | Sorry, I don't have your Ruby Reddit credentials.
68 | E-mail: my.email@gmail.com
69 | Password: ********
70 | Saved! You won't have to enter your credentials for Ruby Reddit again.
71 | Hackernews (y/n)? y
72 | RubyFlow (y/n)? n
73 | Fine.
74 | Posting to Ruby Reddit...........ok
75 | Posting to Hackernews............ok
76 |
77 | Done. Happy hacking! :)
78 |
79 | ##Contribute!
80 |
81 | * Fork the project.
82 | * Make your feature addition or bug fix.
83 | * Add specs for it. This is important so I don't break it in a future
84 | version unintentionally.
85 | * Commit, do not mess with rakefile, version, or history.
86 | If you want to have your own version, that is fine but bump version
87 | in a commit by itself I can ignore when I pull.
88 | * Send me a pull request. Bonus points for topic branches.
89 |
90 | ## Copyright
91 |
92 | Copyright (c) 2011 Codegram. See LICENSE for details.
93 |
--------------------------------------------------------------------------------
/spec/hackershout/base_spec.rb:
--------------------------------------------------------------------------------
1 | require 'spec_helper'
2 |
3 | module Hackershout
4 | describe Base do
5 |
6 | describe ".run" do
7 | before do
8 | subject.stub(:welcome_banner)
9 | subject.stub(:ask_for_url)
10 | subject.stub(:ask_for_message)
11 | subject.stub(:ask_for_title)
12 | subject.stub(:ask_for_tags)
13 | subject.stub(:providers_banner)
14 | subject.stub(:ask_for_providers)
15 | subject.stub(:post_to_providers)
16 | end
17 | it 'calls welcome banner' do
18 | subject.should_receive(:welcome_banner)
19 | subject.run
20 | end
21 | it 'calls ask_for_url' do
22 | subject.should_receive(:ask_for_url)
23 | subject.run
24 | end
25 | it 'calls ask_for_title' do
26 | subject.should_receive(:ask_for_title)
27 | subject.run
28 | end
29 | it 'calls ask_for_message' do
30 | subject.should_receive(:ask_for_message)
31 | subject.run
32 | end
33 | it 'calls ask_for_tags' do
34 | subject.should_receive(:ask_for_tags)
35 | subject.run
36 | end
37 | it 'calls providers_banner' do
38 | subject.should_receive(:providers_banner)
39 | subject.run
40 | end
41 | it 'calls ask_for_providers' do
42 | subject.should_receive(:ask_for_providers)
43 | subject.run
44 | end
45 | end
46 |
47 | describe "#welcome_banner" do
48 | it 'prints the welcome banner' do
49 | subject.should_receive(:blank).any_number_of_times
50 | subject.should_receive(:print).with(":: Welcome to hackershout! ::")
51 | subject.welcome_banner
52 | end
53 | end
54 |
55 | describe "#ask_for_url" do
56 | it 'asks for the url and returns it with appended metainformation' do
57 | subject.should_receive(:print).with("Type the URL you want to share: ")
58 | subject.should_receive(:gets).and_return ' http://rubygems.org/gems/my_gem '
59 | subject.ask_for_url.should == 'http://rubygems.org/gems/my_gem?utm_source=hackershout'
60 | end
61 | end
62 |
63 | describe "#ask_for_title" do
64 | it 'asks for the title and returns it' do
65 | subject.should_receive(:print).with("Enter a brief, descriptive title: ")
66 | subject.should_receive(:gets).and_return ' Released my gem: a nifty gem to eradicate hunger! '
67 | subject.ask_for_title.should == 'Released my gem: a nifty gem to eradicate hunger!'
68 | end
69 | end
70 |
71 | describe "#ask_for_message" do
72 | it 'asks for the message and returns it' do
73 | subject.should_receive(:print).with("Bear in mind that some services may require a more extended text aside from the title.")
74 | subject.should_receive(:print).with("Type your message (two ENTERs to finish): ")
75 | subject.should_receive(:gets).and_return("""
76 | Hey! I have released some awesome open-source gem that is
77 | going to save the world.\nCheck it out! You can also grab the source code
78 | on Github if you want.
79 |
80 | """)
81 | subject.ask_for_message
82 | end
83 | end
84 |
85 | describe "#ask_for_tags" do
86 | it 'asks for the tags and returns them' do
87 | subject.should_receive(:print).with("Type some tags separated by comma (i.e. ruby, rails, bdd): ")
88 | subject.should_receive(:gets).and_return ' ruby , bdd, rails, parsing '
89 | subject.ask_for_tags.should == %w( ruby bdd rails parsing )
90 | end
91 | end
92 |
93 | describe "#providers_banner" do
94 | it 'prints the providers banner' do
95 | subject.should_receive(:print).with("...Got it! Now where would you want to spread the word?")
96 | subject.providers_banner
97 | end
98 | end
99 |
100 | describe "#ask_for_providers" do
101 | it 'asks for providers' do
102 | providers = [:reddit, :hackernews, :rubyflow]
103 | Provider.stub_chain('list.keys').and_return providers
104 | Provider.should_receive(:wants?).with(:reddit).and_return true
105 | Provider.should_receive(:wants?).with(:hackernews).and_return false
106 | Provider.should_receive(:wants?).with(:rubyflow).and_return true
107 |
108 | subject.ask_for_providers.should == [:reddit, :rubyflow]
109 | end
110 | end
111 |
112 | describe "#post_to_providers" do
113 | it 'instantiates each provider and calls #publish on it' do
114 | args = {
115 | :url => 'http://rubygems.org/gems/my_gem',
116 | :title => 'Released MyGem!',
117 | :tags => ['ruby', 'bdd'],
118 | :message => 'Hello!',
119 | }
120 | base = Base.new({:providers => [:reddit, :hackernews]}.update(args))
121 | base.stub(:print)
122 |
123 | hackernews = double :provider
124 | reddit = double :provider
125 |
126 | Provider::Hackernews.should_receive(:new).with(args).and_return hackernews
127 | Provider::Reddit.should_receive(:new).with(args).and_return reddit
128 |
129 | hackernews.should_receive(:publish)
130 | reddit.should_receive(:publish)
131 |
132 | base.post_to_providers
133 | end
134 | end
135 |
136 | end
137 | end
138 |
--------------------------------------------------------------------------------