Skip to content

Commit

Permalink
feat: Basic features
Browse files Browse the repository at this point in the history
  • Loading branch information
schpet committed Aug 16, 2024
1 parent 6c5b45c commit 0f6879f
Show file tree
Hide file tree
Showing 4 changed files with 166 additions and 5 deletions.
39 changes: 39 additions & 0 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,46 @@ PATH
remote: .
specs:
cool_id (0.1.0)
activerecord (>= 6.0)
activesupport (>= 6.0)
nanoid (~> 2.0)

GEM
remote: https://rubygems.org/
specs:
activemodel (7.2.0)
activesupport (= 7.2.0)
activerecord (7.2.0)
activemodel (= 7.2.0)
activesupport (= 7.2.0)
timeout (>= 0.4.0)
activesupport (7.2.0)
base64
bigdecimal
concurrent-ruby (~> 1.0, >= 1.3.1)
connection_pool (>= 2.2.5)
drb
i18n (>= 1.6, < 2)
logger (>= 1.4.2)
minitest (>= 5.1)
securerandom (>= 0.3)
tzinfo (~> 2.0, >= 2.0.5)
ast (2.4.2)
base64 (0.2.0)
bigdecimal (3.1.8)
concurrent-ruby (1.3.4)
connection_pool (2.4.1)
diff-lcs (1.5.1)
drb (2.2.1)
i18n (1.14.5)
concurrent-ruby (~> 1.0)
json (2.7.2)
language_server-protocol (3.17.0.3)
lint_roller (1.1.0)
logger (1.6.0)
mini_portile2 (2.8.7)
minitest (5.25.0)
nanoid (2.0.0)
parallel (1.26.2)
parser (3.3.4.2)
ast (~> 2.4.1)
Expand Down Expand Up @@ -51,6 +82,10 @@ GEM
rubocop (>= 1.48.1, < 2.0)
rubocop-ast (>= 1.31.1, < 2.0)
ruby-progressbar (1.13.0)
securerandom (0.3.1)
sqlite3 (1.7.3)
mini_portile2 (~> 2.8.0)
sqlite3 (1.7.3-arm64-darwin)
standard (1.40.0)
language_server-protocol (~> 3.17.0.2)
lint_roller (~> 1.0)
Expand All @@ -64,6 +99,9 @@ GEM
lint_roller (~> 1.1)
rubocop-performance (~> 1.21.0)
strscan (3.1.0)
timeout (0.4.1)
tzinfo (2.0.6)
concurrent-ruby (~> 1.0)
unicode-display_width (2.5.0)

PLATFORMS
Expand All @@ -74,6 +112,7 @@ DEPENDENCIES
cool_id!
rake (~> 13.0)
rspec (~> 3.0)
sqlite3 (~> 1.4)
standard (~> 1.3)

BUNDLED WITH
Expand Down
7 changes: 5 additions & 2 deletions cool_id.gemspec
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,11 @@ Gem::Specification.new do |spec|
spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
spec.require_paths = ["lib"]

# Uncomment to register a new dependency of your gem
# spec.add_dependency "example-gem", "~> 1.0"
spec.add_dependency "nanoid", "~> 2.0"
spec.add_dependency "activerecord", ">= 6.0"
spec.add_dependency "activesupport", ">= 6.0"

spec.add_development_dependency "sqlite3", "~> 1.4"

# For more information and examples about making a new gem, check out our
# guide at: https://bundler.io/guides/creating_gem.html
Expand Down
42 changes: 41 additions & 1 deletion lib/cool_id.rb
Original file line number Diff line number Diff line change
@@ -1,8 +1,48 @@
# frozen_string_literal: true

require_relative "cool_id/version"
require "nanoid"
require "active_support/concern"
require "active_record"

module CoolId
class Error < StandardError; end
# Your code goes here...

# defaults copped from
# https://planetscale.com/blog/why-we-chose-nanoids-for-planetscales-api
DEFAULT_ALPHABET = "0123456789abcdefghijklmnopqrstuvwxyz"
DEFAULT_SEPARATOR = "_"
DEFAULT_LENGTH = 12

def self.generate_id(prefix: "", separator: DEFAULT_SEPARATOR, length: DEFAULT_LENGTH, alphabet: DEFAULT_ALPHABET)
id = Nanoid.generate(size: length, alphabet: alphabet)
[prefix, id].reject(&:empty?).join(separator)
end

module Model
extend ActiveSupport::Concern

class_methods do
attr_accessor :cool_id_prefix, :cool_id_separator, :cool_id_alphabet, :cool_id_length

def generate_cool_id
CoolId.generate_id(
prefix: cool_id_prefix,
separator: cool_id_separator || DEFAULT_SEPARATOR,
length: cool_id_length || DEFAULT_LENGTH,
alphabet: cool_id_alphabet || DEFAULT_ALPHABET
)
end
end

included do
before_create :set_cool_id

private

def set_cool_id
self.id = self.class.generate_cool_id if id.blank?
end
end
end
end
83 changes: 81 additions & 2 deletions spec/cool_id_spec.rb
Original file line number Diff line number Diff line change
@@ -1,11 +1,90 @@
# frozen_string_literal: true

require "active_record"

# frozen_string_literal: true

class User < ActiveRecord::Base
include CoolId::Model
self.cool_id_prefix = "usr"
end

class CustomUser < ActiveRecord::Base
include CoolId::Model
self.cool_id_prefix = "cus"
self.cool_id_separator = "-"
self.cool_id_alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
self.cool_id_length = 8
end

RSpec.describe CoolId do
it "has a version number" do
expect(CoolId::VERSION).not_to be nil
end

it "does something useful" do
expect(false).to eq(true)
describe ".generate_id" do
it "generates an ID with default parameters" do
id = CoolId.generate_id
expect(id).to match(/^[0-9a-z]{12}$/)
end

it "generates an ID with custom prefix, separator, and length" do
id = CoolId.generate_id(prefix: "test", separator: "-", length: 10)
expect(id).to match(/^test-[0-9a-z]{10}$/)
end

it "generates an ID without prefix when prefix is empty" do
id = CoolId.generate_id(prefix: "", length: 15)
expect(id).to match(/^[0-9a-z]{15}$/)
end

it "generates an ID with custom alphabet" do
id = CoolId.generate_id(alphabet: "ABCDEFGHIJKLMNOPQRSTUVWXYZ", length: 10)
expect(id).to match(/^[A-Z]{10}$/)
end
end

describe CoolId::Model do
before(:all) do
ActiveRecord::Base.establish_connection(adapter: "sqlite3", database: ":memory:")
end

before(:each) do
ActiveRecord::Schema.define do
create_table :users, id: false do |t|
t.string :id, primary_key: true
t.string :name
end

create_table :custom_users, id: false do |t|
t.string :id, primary_key: true
t.string :name
end
end
end

after(:each) do
ActiveRecord::Base.connection.drop_table :users
ActiveRecord::Base.connection.drop_table :custom_users
end

after(:all) do
ActiveRecord::Base.connection.close
end

it "generates a cool_id for a new record" do
user = User.create(name: "John Doe")
expect(user.id).to match(/^usr_[0-9a-z]{12}$/)
end

it "does not overwrite an existing id" do
user = User.create(id: "custom-id", name: "Jane Doe")
expect(user.id).to eq("custom-id")
end

it "generates a cool_id with custom settings" do
custom_user = CustomUser.create(name: "Alice")
expect(custom_user.id).to match(/^cus-[A-Z]{8}$/)
end
end
end

0 comments on commit 0f6879f

Please sign in to comment.