Skip to content

Instantly share code, notes, and snippets.

@sent-hil
Last active December 10, 2015 14:48
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sent-hil/4449959 to your computer and use it in GitHub Desktop.
Save sent-hil/4449959 to your computer and use it in GitHub Desktop.
Some cowbody coding I did couple weeks ago, totally forgot the design decisions and need to start over. :(
# approach 1
require 'bundler/setup'
require 'open_auth2'
require 'active_support'
require 'active_support/inflector'
require_relative 'saran/config_accessors'
require_relative 'saran/endpoint'
module Saran
def self.included(klass)
klass.extend(ConfigAccessors)
klass.extend(Dsl)
end
class Resource
attr_accessor :name, :collection, :member
def initialize(name)
@name = name
end
end
class Collection
def self.requests
@requests ||= []
end
def self.app=(app)
@app = app
end
def get
endpoint = self.class.requests.find do |e|
e.verb == :get
end
resources = endpoint.fetch
resources.each do |res|
end
end
end
class Member
attr_reader :id
def self.requests
@requests ||= []
end
def initialize(values={})
@id = values[:id]
end
def get
endpoint = self.class.requests.find do |e|
e.verb == :get
end
endpoint.path.gsub!(':id', id.to_s)
endpoint.fetch
end
end
module Dsl
attr_accessor :current_resource, :current_collection,
:current_scope, :current_member
def resources(name, &blk)
self.current_resource = Resource.new(name)
instance_eval(&blk) if block_given?
end
def collection(&blk)
name = self.current_resource.name.to_s.capitalize
self.const_set(name, Class.new(Collection))
const = self.const_get(name)
const.app = self
self.current_collection = const
self.current_resource.collection = const
self.current_scope = const
instance_eval(&blk) if block_given?
end
def member(&blk)
name = self.current_resource.name.to_s.singularize.capitalize
self.const_set(name, Class.new(Member))
const = self.const_get(name)
self.current_member = const
self.current_resource.member = const
self.current_scope = const
instance_eval(&blk) if block_given?
end
def get(path)
full_url = endpoint + path
ep = Endpoint.new(:get, full_url)
self.current_scope.requests << ep
end
end
end
# approach 2
module Saran
class Endpoint
attr_accessor :verb, :path, :collection
def initialize(verb, path, collection)
@verb = verb
@path = path
@collection = collection
end
end
class Collection
attr_accessor :path, :endpoint
def initialize(endpoint)
@endpoint = endpoint
end
def get(path)
@path = path
end
def fetch
resp = Connection.new(endpoint, path).get
collection.new(resp.body)
end
end
class Resource
def initialize(app, name)
coll_name = name.to_s.camelize + "Collection"
@collection = Class.new(Collection).new(app.endpoint)
app.const_set(coll_name, @collection)
end
def collection(&blk)
@collection.instance_eval(&blk)
end
end
module Dsl
def resources(name, &blk)
@current_resource = Resource.new(self, name)
instance_eval(&blk) if block_given?
end
def method_missing(name, *args, &blk)
if @current_resource
@current_resource.send(name, *args, &blk)
else
super
end
end
end
end
# random test file I found in spec dir, guess the above was cowboy coding rather.
require 'spec_helper'
describe Saran, 'resources' do
subject do
rspec = self
klass = Class.new do
include Saran
endpoint rspec.send(:mock_api_endpoint)
provider :default
resources :blogs do
collection do
get '/blogs'
end
member do
get '/blogs/:id'
end
end
end
end
it 'stores resource' do
expect(subject.current_resource.name).to eql(:blogs)
end
it 'stores last resource as current resource' do
subject.resources :posts
expect(subject.current_resource.name).to eql(:posts)
end
context 'collection' do
context 'GET /' do
it 'generates method' do
VCR.use_cassette('get_blogs_collection') do
resp = subject::Blogs.new.get
expect(resp.status).to eq(200)
end
end
it 'returns resource objects' do
VCR.use_cassette('get_blogs_collection') do
blogs = subject::Blogs.new.get
expect(blogs.first).to be_a(subject::Blog)
end
end
end
end
context 'member' do
context 'GET /:id' do
it 'generates method' do
VCR.use_cassette('get_blog_id') do
resp = subject::Blog.new(:id => 1).get
expect(resp.status).to eq(200)
end
end
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment