Skip to content

Instantly share code, notes, and snippets.

@releu
Created April 8, 2012 17:59
Show Gist options
  • Save releu/2338770 to your computer and use it in GitHub Desktop.
Save releu/2338770 to your computer and use it in GitHub Desktop.
Replaceable review
class Replaceable
BASE_REGEXP = '(^|\W){1}%s(\b|\.|,|:|;|\?|!|\(|\)|$){1}'
attr_accessor :body
alias to_s body
def initialize(body)
self.body = body
end
def replace_gists!
self.body.gsub!(Regexp.new(BASE_REGEXP % 'gist:(\d+)')) do |match|
"#{$1}[gist:#{$2}](https://gist.github.com/#{$2})#{$3}"
end
self
end
def replace_usernames!
self.body.gsub!(Regexp.new(BASE_REGEXP % '@(\w+)')) do |match|
if User.where(:username => $2).exists?
"#{$1}[@#{$2}](/users/#{$2})#{$3}"
else
match
end
end
self
end
def replace_tags!
self.body.gsub!(Regexp.new(BASE_REGEXP % '#(\w+)')) do |match|
"#{$1}[##{$2}](/tags/#{$2})#{$3}"
end
self
end
def tagnames
body.scan(Regexp.new(BASE_REGEXP % '#(\w+)')).map do |match|
match[1]
end.uniq
end
def usernames
body.scan(Regexp.new(BASE_REGEXP % '@(\w+)')).map do |match|
match[1]
end.uniq
end
end
require 'spec_helper'
PUNCTUATION = ['.', ',', ':', ';', '?', '!', '(', ')']
describe Replaceable do
describe '#replace_gists' do
let(:replaceable) { Replaceable.new('gist:1, gist:2') }
before { replaceable.replace_gists! }
subject { replaceable.to_s }
it 'should replace gists to links' do
should == '[gist:1](https://gist.github.com/1), [gist:2](https://gist.github.com/2)'
end
PUNCTUATION.each do |char|
context "end with #{char}" do
let(:replaceable) { Replaceable.new("gist:1#{char}") }
it { should == "[gist:1](https://gist.github.com/1)#{char}" }
end
end
end
describe '#replace_tags!' do
let(:replaceable) { Replaceable.new('#tag1, #tag2') }
before { replaceable.replace_tags! }
subject { replaceable.to_s }
it 'should replace tags to links' do
should == '[#tag1](/tags/tag1), [#tag2](/tags/tag2)'
end
PUNCTUATION.each do |char|
context "end with #{char}" do
let(:replaceable) { Replaceable.new("#tag#{char}") }
it { should == "[#tag](/tags/tag)#{char}" }
end
end
end
describe '#replace_usernames' do
before { replaceable.replace_usernames! }
subject { replaceable.to_s }
context 'unexisted user' do
let(:replaceable) { Replaceable.new(' @username ') }
it 'should not replace it' do
should == ' @username '
end
end
context 'existed user' do
before do
FactoryGirl.create(:user, :username => 'username')
replaceable.replace_usernames!
end
context 'wrapped @usename' do
let(:replaceable) { Replaceable.new(' @username ') }
it { should == ' [@username](/users/username) ' }
end
context 'two usernames' do
let(:replaceable) { Replaceable.new('@username @username') }
it { should == '[@username](/users/username) [@username](/users/username)' }
end
context 'started with @username' do
let(:replaceable) { Replaceable.new('@username ') }
it { should == '[@username](/users/username) ' }
end
context 'at the end of the line' do
let(:replaceable) { Replaceable.new(' @username') }
it { should == ' [@username](/users/username)' }
end
context 'a part of email' do
let(:replaceable) { Replaceable.new('foo@username') }
it { should == 'foo@username' }
end
context 'a double @username@username' do
let(:replaceable) { Replaceable.new('@username@username') }
it do
# should == '@username@username'
pending "Is it really needed?"
end
end
PUNCTUATION.each do |char|
context "end with #{char}" do
let(:replaceable) { Replaceable.new("@username#{char}") }
it { should == "[@username](/users/username)#{char}" }
end
end
end
end
describe '#tagnames' do
let(:replaceable) { Replaceable.new('#tag1, #tag2, #tag3') }
subject { replaceable.tagnames }
it { should == %w(tag1 tag2 tag3) }
end
describe '#usernames' do
let(:replaceable) { Replaceable.new('@username1, @username2, @username3') }
subject { replaceable.usernames }
it { should == %w(username1 username2 username3) }
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment