promocode_generator 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.
- checksums.yaml +15 -0
- data/.gitignore +17 -0
- data/.rspec +1 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +44 -0
- data/Rakefile +5 -0
- data/lib/promocode_generator/model_additions.rb +14 -0
- data/lib/promocode_generator/version.rb +3 -0
- data/lib/promocode_generator.rb +11 -0
- data/promocode_generator.gemspec +25 -0
- data/spec/promocode_generator/model_additions_spec.rb +40 -0
- data/spec/promocode_generator_spec.rb +13 -0
- data/spec/spec_helper.rb +2 -0
- metadata +116 -0
checksums.yaml
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
---
|
2
|
+
!binary "U0hBMQ==":
|
3
|
+
metadata.gz: !binary |-
|
4
|
+
Mjg4Y2M2NTJlZmI2MjVmNzczMDk5NDc1ZjdkZTRhNDRmYTYxNDI2Zg==
|
5
|
+
data.tar.gz: !binary |-
|
6
|
+
ZTU3ZjgwZWQ0ZmI1ZWY3ZjBkOTkzYmYzZjZlMjJmN2ZjNzkxZGNmZQ==
|
7
|
+
!binary "U0hBNTEy":
|
8
|
+
metadata.gz: !binary |-
|
9
|
+
YzM2YWI5ZTQzZjE1YjgwMmI2NGJhMTEzOWUxNWU4MmE0NWQ2NWRkNmQ5NDJk
|
10
|
+
MDhhOGNkNTY1NjMxOGI5YmY0N2UzYTQ0NGU4MTk2YjFlN2ExOTRkODQ0Mjlh
|
11
|
+
MWJhY2JiMmE5OGQ5MDI1N2I2YmEyNGMwMWJlN2MyNzExYzRjODU=
|
12
|
+
data.tar.gz: !binary |-
|
13
|
+
ZjY3MWNkZTIxMzM5ZjAwNmY2Yjg1MDY5MjYwMGExZjBhOTQwM2E5MTJmN2Vm
|
14
|
+
MGUxNzRlOTgwZDhkMmYyMjVmZjRhM2IwYjNjYjA0ZWFlZTZiODZlZjVkNWU3
|
15
|
+
YmZkZjgyZjc3YzgyNjJlNDc2N2M2Yjg1ZWQ2MzUxY2I2OGMwMTc=
|
data/.gitignore
ADDED
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--color
|
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2013 Pascal Ehlert
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,44 @@
|
|
1
|
+
# Promocode Generator
|
2
|
+
|
3
|
+
Generates save and unique (when used with AR) codes which can be handed to customers for promotional campaigns.
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
gem 'promocode_generator'
|
10
|
+
|
11
|
+
And then execute:
|
12
|
+
|
13
|
+
$ bundle
|
14
|
+
|
15
|
+
Or install it yourself as:
|
16
|
+
|
17
|
+
$ gem install promocode_generator
|
18
|
+
|
19
|
+
## Usage
|
20
|
+
|
21
|
+
Without Rails:
|
22
|
+
|
23
|
+
Use PromocodeGenerator.generate(length) to produce a promotional code of the desired length.
|
24
|
+
|
25
|
+
With Rails:
|
26
|
+
|
27
|
+
In your model, use the promocode_attribute method to automatically generate a promotional code of length 8 in the before_save hook:
|
28
|
+
|
29
|
+
```ruby
|
30
|
+
class Campaign < ActiveRecord::Base
|
31
|
+
promocode_attribute :code
|
32
|
+
end
|
33
|
+
```
|
34
|
+
|
35
|
+
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:
|
36
|
+
`promocode_attribute :code, :reject_if => Proc.new { |code| ModelA.where(:code => code).any? }`
|
37
|
+
|
38
|
+
## Contributing
|
39
|
+
|
40
|
+
1. Fork it
|
41
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
42
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
43
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
44
|
+
5. Create new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
module PromocodeGenerator
|
2
|
+
module ModelAdditions
|
3
|
+
def promocode_attribute(attribute, options = {})
|
4
|
+
options[:reject_if] ||= Proc.new { |code| self.where(attribute => code).any? }
|
5
|
+
|
6
|
+
before_save do
|
7
|
+
# Make sure not to generate the same code twice!
|
8
|
+
begin
|
9
|
+
self.code = PromocodeGenerator.generate
|
10
|
+
end while options[:reject_if].call(code)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
require "promocode_generator/version"
|
2
|
+
require "promocode_generator/model_additions"
|
3
|
+
|
4
|
+
module PromocodeGenerator
|
5
|
+
# Generates an 8 character random code of uppercase letters and numbers
|
6
|
+
# It explicitly excludes the letters I, L, O and the number 0 to avoid
|
7
|
+
# confusion
|
8
|
+
def self.generate(length = 8)
|
9
|
+
[('A'..'Z').to_a - ['I', 'L', 'O'], ('1'..'9').to_a].flatten.shuffle[0,length].join
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'promocode_generator/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "promocode_generator"
|
8
|
+
spec.version = PromocodeGenerator::VERSION
|
9
|
+
spec.authors = ["Pascal Ehlert"]
|
10
|
+
spec.email = ["pascal@hacksrus.net"]
|
11
|
+
spec.description = %q{}
|
12
|
+
spec.summary = %q{Generates a safe, unique and easy to quote promotional code}
|
13
|
+
spec.homepage = ""
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files`.split($/)
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_development_dependency "bundler", "~> 1.3"
|
22
|
+
spec.add_development_dependency "rake"
|
23
|
+
spec.add_development_dependency "rspec"
|
24
|
+
spec.add_development_dependency "supermodel"
|
25
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
# Dummy reject condition that can be stubbed in the tests below
|
4
|
+
module RejectCondition
|
5
|
+
def self.check(code)
|
6
|
+
false
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
class Campaign < SuperModel::Base
|
11
|
+
include ActiveModel::Validations::Callbacks
|
12
|
+
extend PromocodeGenerator::ModelAdditions
|
13
|
+
promocode_attribute :code, :reject_if => Proc.new { |code| RejectCondition.check(code) }
|
14
|
+
end
|
15
|
+
|
16
|
+
describe PromocodeGenerator::ModelAdditions do
|
17
|
+
let(:campaign) { Campaign.new(:name => "foo") }
|
18
|
+
|
19
|
+
context "when the model is saved" do
|
20
|
+
it "generates a code" do
|
21
|
+
expect(PromocodeGenerator).to receive(:generate).once.and_return('ABCDEFG')
|
22
|
+
campaign.save!
|
23
|
+
end
|
24
|
+
|
25
|
+
it "assigns the code to the model" do
|
26
|
+
campaign.save!
|
27
|
+
expect(campaign.code).not_to be_nil
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
context "when the reject_if block returns false" do
|
32
|
+
before { RejectCondition.stub(:check).and_return(true, false) }
|
33
|
+
after { RejectCondition.unstub(:check) }
|
34
|
+
|
35
|
+
it "generates a new code" do
|
36
|
+
expect(PromocodeGenerator).to receive(:generate).exactly(2).times
|
37
|
+
campaign.save!
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe PromocodeGenerator do
|
4
|
+
describe ".generate" do
|
5
|
+
it "generates a code of the given length" do
|
6
|
+
expect(PromocodeGenerator.generate(10).length).to eq(10)
|
7
|
+
end
|
8
|
+
|
9
|
+
it "generates a code with default length" do
|
10
|
+
expect(PromocodeGenerator.generate.length).to be > 0
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
data/spec/spec_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,116 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: promocode_generator
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Pascal Ehlert
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2013-12-28 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ~>
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '1.3'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ~>
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '1.3'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ! '>='
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ! '>='
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rspec
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ! '>='
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ! '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: supermodel
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ! '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ! '>='
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
description: ''
|
70
|
+
email:
|
71
|
+
- pascal@hacksrus.net
|
72
|
+
executables: []
|
73
|
+
extensions: []
|
74
|
+
extra_rdoc_files: []
|
75
|
+
files:
|
76
|
+
- .gitignore
|
77
|
+
- .rspec
|
78
|
+
- Gemfile
|
79
|
+
- LICENSE.txt
|
80
|
+
- README.md
|
81
|
+
- Rakefile
|
82
|
+
- lib/promocode_generator.rb
|
83
|
+
- lib/promocode_generator/model_additions.rb
|
84
|
+
- lib/promocode_generator/version.rb
|
85
|
+
- promocode_generator.gemspec
|
86
|
+
- spec/promocode_generator/model_additions_spec.rb
|
87
|
+
- spec/promocode_generator_spec.rb
|
88
|
+
- spec/spec_helper.rb
|
89
|
+
homepage: ''
|
90
|
+
licenses:
|
91
|
+
- MIT
|
92
|
+
metadata: {}
|
93
|
+
post_install_message:
|
94
|
+
rdoc_options: []
|
95
|
+
require_paths:
|
96
|
+
- lib
|
97
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
98
|
+
requirements:
|
99
|
+
- - ! '>='
|
100
|
+
- !ruby/object:Gem::Version
|
101
|
+
version: '0'
|
102
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
103
|
+
requirements:
|
104
|
+
- - ! '>='
|
105
|
+
- !ruby/object:Gem::Version
|
106
|
+
version: '0'
|
107
|
+
requirements: []
|
108
|
+
rubyforge_project:
|
109
|
+
rubygems_version: 2.0.3
|
110
|
+
signing_key:
|
111
|
+
specification_version: 4
|
112
|
+
summary: Generates a safe, unique and easy to quote promotional code
|
113
|
+
test_files:
|
114
|
+
- spec/promocode_generator/model_additions_spec.rb
|
115
|
+
- spec/promocode_generator_spec.rb
|
116
|
+
- spec/spec_helper.rb
|