Skip to content

Instantly share code, notes, and snippets.

@spllr
Created October 26, 2012 17:40
Show Gist options
  • Save spllr/3960153 to your computer and use it in GitHub Desktop.
Save spllr/3960153 to your computer and use it in GitHub Desktop.
InnoViz SF Database mapper
#!/usr/bin/env ruby -wKU
##
# Runtime options
#
require "optparse"
options = { :spec => false }
ARGV.options do |opts|
opts.banner = "Usage: #{File.basename($PROGRAM_NAME)}"
opts.on( "-s", "--[no-]spec", "Run specs") do |v|
options[:spec] = v
end
end.parse!
##
# Implementation
#
require "json"
module InnoViz
module Resource
module ClassMethods
def resource_name(*args)
@resource_name = args[0] unless args.empty?
@resource_name.to_s.split(/[ -]/).map { |w| w.capitalize }.join
end
def slot(name)
self.class_eval { attr_accessor name }
slots << name
end
def slots
@slots ||= []
end
def resource_path
resource_name
end
def resource_slots_path
File.join(resource_path, 'slots')
end
def parse(data)
obj = new
JSON.parse(data).each do |k,v|
obj.send "#{k}=", v
end
obj
end
def migrate
Dir.mkdir resource_path unless File.exists?(resource_path)
Dir.mkdir resource_slots_path unless File.exists?(resource_slots_path)
end
end
module InstanceMethods
alias_method :id, :object_id
def save
File.open("#{id}.json", "w+") { |f| f.write to_json }
end
def to_json
obj = {}
self.class.slots.each do |s|
obj[s] = send(s)
end
obj.to_json
end
end
def self.included(receiver)
receiver.extend ClassMethods
receiver.send :include, InstanceMethods
end
end
end
##
# Specs
#
# To run the test:
#
# %> ruby innovizdb.rb -s
#
require "minitest/spec"
require "minitest/autorun" if options[:spec]
describe "InnoViz::Resource" do
require "tmpdir"
def sandbox
Dir.mktmpdir do |dir|
Dir.chdir(dir) { yield }
end
end
let(:resource) do
Class.new do
include InnoViz::Resource
resource_name :account
slot :name
slot :age
end
end
describe ".migrate" do
it 'creates the correct folder name' do
sandbox do
resource.migrate
File.directory?('Account').must_equal true
end
end
it 'creates the slots dir' do
sandbox do
resource.migrate
File.directory?('Account/slots').must_equal true
end
end
it 'can be run multiple times' do
sandbox do
lambda { resource.migrate }.must_be_silent
lambda { resource.migrate }.must_be_silent
lambda { resource.migrate }.must_be_silent
end
end
end
describe "slots" do
it 'creates a accesor for each slot' do
obj = resource.new
obj.must_respond_to :name=
obj.must_respond_to :name
obj.must_respond_to :age=
obj.must_respond_to :age
end
end
describe "#save" do
it 'saves the instance to a file using the id as the name' do
sandbox do
resource.migrate
obj = resource.new
obj.name = "Emma"
obj.age = 21
obj.save
File.exists?("#{obj.id}.json").must_equal true
end
end
it 'saves the instance as a json representation' do
sandbox do
resource.migrate
obj = resource.new
obj.name = "Emma"
obj.age = 21
obj.save
File.open("#{obj.id}.json") { |f|
the_json = JSON.parse(f.read)
the_json["name"].must_equal obj.name
the_json["age"].must_equal obj.age
}
end
end
end
describe ".parse" do
it 'can serialize itself from a json representation' do
obj = resource.parse(%({ "name": "Pipo", "age": 21 }))
obj.name.must_equal "Pipo"
obj.age.must_equal 21
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment