Skip to content

Commit

Permalink
Adds specs and documentation
Browse files Browse the repository at this point in the history
  • Loading branch information
Pascal Ehlert committed Dec 28, 2013
1 parent f9e3858 commit b7b0ceb
Show file tree
Hide file tree
Showing 10 changed files with 106 additions and 12 deletions.
25 changes: 20 additions & 5 deletions README.md
@@ -1,24 +1,39 @@
# Promocode # Promocode Generator


TODO: Write a gem description Generates save and unique (when used with AR) codes which can be handed to customers for promotional campaigns.


## Installation ## Installation


Add this line to your application's Gemfile: Add this line to your application's Gemfile:


gem 'promocode' gem 'promocode_generator'


And then execute: And then execute:


$ bundle $ bundle


Or install it yourself as: Or install it yourself as:


$ gem install promocode $ gem install promocode_generator


## Usage ## Usage


TODO: Write usage instructions here Without Rails:

Use PromocodeGenerator.generate(length) to produce a promotional code of the desired length.

With Rails:

In your model, use the promocode_attribute method to automatically generate a promotional code of length 8 in the before_save hook:

```ruby
class Campaign < ActiveRecord::Base
promocode_attribute :code
end
```

Basic uniqueness validation comes by default so that codes are generated until a non-existing code is found in the db. Provide the :reject_if option to customize:
`promocode_attribute :code, :reject_if => Proc.new { |code| ModelA.where(:code => code).any? }`


## Contributing ## Contributing


Expand Down
4 changes: 4 additions & 0 deletions Rakefile
@@ -1 +1,5 @@
require "bundler/gem_tasks" require "bundler/gem_tasks"
require 'rspec/core/rake_task'

RSpec::Core::RakeTask.new(:spec)
task default: :spec
3 changes: 0 additions & 3 deletions lib/promocode/version.rb

This file was deleted.

12 changes: 9 additions & 3 deletions lib/promocode_generator.rb
@@ -1,5 +1,11 @@
require "promocode/version" require "promocode_generator/version"
require "promocode_generator/model_additions"


module Promocode module PromocodeGenerator
# Your code goes here... # Generates an 8 character random code of uppercase letters and numbers
# It explicitly excludes the letters I, L, O and the number 0 to avoid
# confusion
def self.generate(length = 8)
[('A'..'Z').to_a - ['I', 'L', 'O'], ('1'..'9').to_a].flatten.shuffle[0,length].join
end
end end
14 changes: 14 additions & 0 deletions lib/promocode_generator/model_additions.rb
@@ -0,0 +1,14 @@
module PromocodeGenerator
module ModelAdditions
def promocode_attribute(attribute, options = {})
options[:reject_if] ||= Proc.new { |code| self.where(attribute => code).any? }

before_save do
# Make sure not to generate the same code twice!
begin
self.code = PromocodeGenerator.generate
end while options[:reject_if].call(code)
end
end
end
end
3 changes: 3 additions & 0 deletions lib/promocode_generator/version.rb
@@ -0,0 +1,3 @@
module PromocodeGenerator
VERSION = "0.0.1"
end
1 change: 1 addition & 0 deletions promocode_generator.gemspec
Expand Up @@ -21,4 +21,5 @@ Gem::Specification.new do |spec|
spec.add_development_dependency "bundler", "~> 1.3" spec.add_development_dependency "bundler", "~> 1.3"
spec.add_development_dependency "rake" spec.add_development_dependency "rake"
spec.add_development_dependency "rspec" spec.add_development_dependency "rspec"
spec.add_development_dependency "supermodel"
end end
40 changes: 40 additions & 0 deletions spec/promocode_generator/model_additions_spec.rb
@@ -0,0 +1,40 @@
require 'spec_helper'

# Dummy reject condition that can be stubbed in the tests below
module RejectCondition
def self.check(code)
false
end
end

class Campaign < SuperModel::Base
include ActiveModel::Validations::Callbacks
extend PromocodeGenerator::ModelAdditions
promocode_attribute :code, :reject_if => Proc.new { |code| RejectCondition.check(code) }
end

describe PromocodeGenerator::ModelAdditions do
let(:campaign) { Campaign.new(:name => "foo") }

context "when the model is saved" do
it "generates a code" do
expect(PromocodeGenerator).to receive(:generate).once.and_return('ABCDEFG')
campaign.save!
end

it "assigns the code to the model" do
campaign.save!
expect(campaign.code).not_to be_nil
end
end

context "when the reject_if block returns false" do
before { RejectCondition.stub(:check).and_return(true, false) }
after { RejectCondition.unstub(:check) }

it "generates a new code" do
expect(PromocodeGenerator).to receive(:generate).exactly(2).times
campaign.save!
end
end
end
13 changes: 13 additions & 0 deletions spec/promocode_generator_spec.rb
@@ -0,0 +1,13 @@
require 'spec_helper'

describe PromocodeGenerator do
describe ".generate" do
it "generates a code of the given length" do
expect(PromocodeGenerator.generate(10).length).to eq(10)
end

it "generates a code with default length" do
expect(PromocodeGenerator.generate.length).to be > 0
end
end
end
3 changes: 2 additions & 1 deletion spec/spec_helper.rb
@@ -1 +1,2 @@
require 'promocode' require 'promocode_generator'
require 'supermodel'

0 comments on commit b7b0ceb

Please sign in to comment.