jaysus 0.1.0
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.
- data/.document +5 -0
- data/.rspec +1 -0
- data/Gemfile +19 -0
- data/Gemfile.lock +53 -0
- data/LICENSE.txt +20 -0
- data/README.md +42 -0
- data/Rakefile +50 -0
- data/VERSION +1 -0
- data/jaysus.gemspec +98 -0
- data/lib/jaysus.rb +18 -0
- data/lib/jaysus/base.rb +165 -0
- data/lib/jaysus/local.rb +49 -0
- data/lib/jaysus/remote.rb +72 -0
- data/spec/fixtures/1 +7 -0
- data/spec/fixtures/all.json +9 -0
- data/spec/fixtures/find_site.json +7 -0
- data/spec/fixtures/new_site.json +7 -0
- data/spec/fixtures/update_site.json +7 -0
- data/spec/local_spec.rb +77 -0
- data/spec/remote_spec.rb +90 -0
- data/spec/spec_helper.rb +16 -0
- data/spec/support/debugger.rb +6 -0
- data/spec/support/fakeweb.rb +6 -0
- data/spec/support/jaysus.rb +3 -0
- data/spec/support/site.rb +16 -0
- metadata +237 -0
data/.document
ADDED
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--color
|
data/Gemfile
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
source "http://rubygems.org"
|
2
|
+
# Add dependencies required to use your gem here.
|
3
|
+
# Example:
|
4
|
+
# gem "activesupport", ">= 2.3.5"
|
5
|
+
gem 'activemodel', "~> 3.0.0"
|
6
|
+
gem 'activesupport', "~> 3.0.0"
|
7
|
+
gem 'rest-client', '~> 1.6.1'
|
8
|
+
|
9
|
+
# Add dependencies to develop your gem here.
|
10
|
+
# Include everything needed to run rake, tests, features, etc.
|
11
|
+
group :development do
|
12
|
+
gem "bundler", "~> 1.0.0"
|
13
|
+
gem 'fakeweb', '~> 1.3.0'
|
14
|
+
gem "jeweler", "~> 1.5.2"
|
15
|
+
gem "rcov", ">= 0"
|
16
|
+
gem "rspec", "~> 2.0.0"
|
17
|
+
gem 'ruby-debug'
|
18
|
+
end
|
19
|
+
|
data/Gemfile.lock
ADDED
@@ -0,0 +1,53 @@
|
|
1
|
+
GEM
|
2
|
+
remote: http://rubygems.org/
|
3
|
+
specs:
|
4
|
+
activemodel (3.0.3)
|
5
|
+
activesupport (= 3.0.3)
|
6
|
+
builder (~> 2.1.2)
|
7
|
+
i18n (~> 0.4)
|
8
|
+
activesupport (3.0.3)
|
9
|
+
builder (2.1.2)
|
10
|
+
columnize (0.3.2)
|
11
|
+
diff-lcs (1.1.2)
|
12
|
+
fakeweb (1.3.0)
|
13
|
+
git (1.2.5)
|
14
|
+
i18n (0.5.0)
|
15
|
+
jeweler (1.5.2)
|
16
|
+
bundler (~> 1.0.0)
|
17
|
+
git (>= 1.2.5)
|
18
|
+
rake
|
19
|
+
linecache (0.43)
|
20
|
+
mime-types (1.16)
|
21
|
+
rake (0.8.7)
|
22
|
+
rcov (0.9.9)
|
23
|
+
rest-client (1.6.1)
|
24
|
+
mime-types (>= 1.16)
|
25
|
+
rspec (2.0.0)
|
26
|
+
rspec-core (= 2.0.0)
|
27
|
+
rspec-expectations (= 2.0.0)
|
28
|
+
rspec-mocks (= 2.0.0)
|
29
|
+
rspec-core (2.0.0)
|
30
|
+
rspec-expectations (2.0.0)
|
31
|
+
diff-lcs (>= 1.1.2)
|
32
|
+
rspec-mocks (2.0.0)
|
33
|
+
rspec-core (= 2.0.0)
|
34
|
+
rspec-expectations (= 2.0.0)
|
35
|
+
ruby-debug (0.10.4)
|
36
|
+
columnize (>= 0.1)
|
37
|
+
ruby-debug-base (~> 0.10.4.0)
|
38
|
+
ruby-debug-base (0.10.4)
|
39
|
+
linecache (>= 0.3)
|
40
|
+
|
41
|
+
PLATFORMS
|
42
|
+
ruby
|
43
|
+
|
44
|
+
DEPENDENCIES
|
45
|
+
activemodel (~> 3.0.0)
|
46
|
+
activesupport (~> 3.0.0)
|
47
|
+
bundler (~> 1.0.0)
|
48
|
+
fakeweb (~> 1.3.0)
|
49
|
+
jeweler (~> 1.5.2)
|
50
|
+
rcov
|
51
|
+
rest-client (~> 1.6.1)
|
52
|
+
rspec (~> 2.0.0)
|
53
|
+
ruby-debug
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2011 Paul Campbell
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,42 @@
|
|
1
|
+
# Jaysus #
|
2
|
+
|
3
|
+
Jaysus is a local/remote persistence/sync framework for MacRuby. It's designed for keeping local copies of responses from a remote JSON api.
|
4
|
+
|
5
|
+
## Usage ##
|
6
|
+
|
7
|
+
Jaysus::Local.store_dir = '~/.jaysus/'
|
8
|
+
Jaysus::Remote.base_url = 'https://user:pass@https://dnsimple.com'
|
9
|
+
|
10
|
+
module Domain
|
11
|
+
class Base < Jaysus::Base
|
12
|
+
primary_key :id
|
13
|
+
attribute :name
|
14
|
+
attribute :name_server_status
|
15
|
+
attribute :registrant_id
|
16
|
+
attribute :registration_status
|
17
|
+
attribute :expires_at
|
18
|
+
attribute :created_at
|
19
|
+
attribute :updated_at
|
20
|
+
attribute :user_id
|
21
|
+
end
|
22
|
+
|
23
|
+
class Local < Base
|
24
|
+
include Jaysus::Local
|
25
|
+
end
|
26
|
+
|
27
|
+
class Remote < Base
|
28
|
+
include Jaysus::Remote
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
domain = Site::Remote.new
|
33
|
+
domain.title = "This"
|
34
|
+
domain.user_id = 1
|
35
|
+
domain.save
|
36
|
+
|
37
|
+
|
38
|
+
== Copyright
|
39
|
+
|
40
|
+
Copyright (c) 2011 Paul Campbell. See LICENSE.txt for
|
41
|
+
further details.
|
42
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,50 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'bundler'
|
3
|
+
begin
|
4
|
+
Bundler.setup(:default, :development)
|
5
|
+
rescue Bundler::BundlerError => e
|
6
|
+
$stderr.puts e.message
|
7
|
+
$stderr.puts "Run `bundle install` to install missing gems"
|
8
|
+
exit e.status_code
|
9
|
+
end
|
10
|
+
require 'rake'
|
11
|
+
|
12
|
+
require 'jeweler'
|
13
|
+
Jeweler::Tasks.new do |gem|
|
14
|
+
# gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
|
15
|
+
gem.name = "jaysus"
|
16
|
+
gem.homepage = "http://github.com/paulca/jaysus"
|
17
|
+
gem.license = "MIT"
|
18
|
+
gem.summary = %Q{A Ruby library for managing local / remote JSON store}
|
19
|
+
gem.description = %Q{Persist remote JSON APIs locally and vice versa}
|
20
|
+
gem.email = "paul@rslw.com"
|
21
|
+
gem.authors = ["Paul Campbell"]
|
22
|
+
# Include your dependencies below. Runtime dependencies are required when using your gem,
|
23
|
+
# and development dependencies are only needed for development (ie running rake tasks, tests, etc)
|
24
|
+
# gem.add_runtime_dependency 'jabber4r', '> 0.1'
|
25
|
+
# gem.add_development_dependency 'rspec', '> 1.2.3'
|
26
|
+
end
|
27
|
+
Jeweler::RubygemsDotOrgTasks.new
|
28
|
+
|
29
|
+
require 'rspec/core'
|
30
|
+
require 'rspec/core/rake_task'
|
31
|
+
RSpec::Core::RakeTask.new(:spec) do |spec|
|
32
|
+
spec.pattern = FileList['spec/**/*_spec.rb']
|
33
|
+
end
|
34
|
+
|
35
|
+
RSpec::Core::RakeTask.new(:rcov) do |spec|
|
36
|
+
spec.pattern = 'spec/**/*_spec.rb'
|
37
|
+
spec.rcov = true
|
38
|
+
end
|
39
|
+
|
40
|
+
task :default => :spec
|
41
|
+
|
42
|
+
require 'rake/rdoctask'
|
43
|
+
Rake::RDocTask.new do |rdoc|
|
44
|
+
version = File.exist?('VERSION') ? File.read('VERSION') : ""
|
45
|
+
|
46
|
+
rdoc.rdoc_dir = 'rdoc'
|
47
|
+
rdoc.title = "jaysus #{version}"
|
48
|
+
rdoc.rdoc_files.include('README*')
|
49
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
50
|
+
end
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.1.0
|
data/jaysus.gemspec
ADDED
@@ -0,0 +1,98 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
|
4
|
+
# -*- encoding: utf-8 -*-
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = %q{jaysus}
|
8
|
+
s.version = "0.1.0"
|
9
|
+
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
+
s.authors = ["Paul Campbell"]
|
12
|
+
s.date = %q{2011-01-16}
|
13
|
+
s.description = %q{Persist remote JSON APIs locally and vice versa}
|
14
|
+
s.email = %q{paul@rslw.com}
|
15
|
+
s.extra_rdoc_files = [
|
16
|
+
"LICENSE.txt",
|
17
|
+
"README.md"
|
18
|
+
]
|
19
|
+
s.files = [
|
20
|
+
".document",
|
21
|
+
".rspec",
|
22
|
+
"Gemfile",
|
23
|
+
"Gemfile.lock",
|
24
|
+
"LICENSE.txt",
|
25
|
+
"README.md",
|
26
|
+
"Rakefile",
|
27
|
+
"VERSION",
|
28
|
+
"jaysus.gemspec",
|
29
|
+
"lib/jaysus.rb",
|
30
|
+
"lib/jaysus/base.rb",
|
31
|
+
"lib/jaysus/local.rb",
|
32
|
+
"lib/jaysus/remote.rb",
|
33
|
+
"spec/fixtures/1",
|
34
|
+
"spec/fixtures/all.json",
|
35
|
+
"spec/fixtures/find_site.json",
|
36
|
+
"spec/fixtures/new_site.json",
|
37
|
+
"spec/fixtures/update_site.json",
|
38
|
+
"spec/local_spec.rb",
|
39
|
+
"spec/remote_spec.rb",
|
40
|
+
"spec/spec_helper.rb",
|
41
|
+
"spec/support/debugger.rb",
|
42
|
+
"spec/support/fakeweb.rb",
|
43
|
+
"spec/support/jaysus.rb",
|
44
|
+
"spec/support/site.rb"
|
45
|
+
]
|
46
|
+
s.homepage = %q{http://github.com/paulca/jaysus}
|
47
|
+
s.licenses = ["MIT"]
|
48
|
+
s.require_paths = ["lib"]
|
49
|
+
s.rubygems_version = %q{1.3.7}
|
50
|
+
s.summary = %q{A Ruby library for managing local / remote JSON store}
|
51
|
+
s.test_files = [
|
52
|
+
"spec/local_spec.rb",
|
53
|
+
"spec/remote_spec.rb",
|
54
|
+
"spec/spec_helper.rb",
|
55
|
+
"spec/support/debugger.rb",
|
56
|
+
"spec/support/fakeweb.rb",
|
57
|
+
"spec/support/jaysus.rb",
|
58
|
+
"spec/support/site.rb"
|
59
|
+
]
|
60
|
+
|
61
|
+
if s.respond_to? :specification_version then
|
62
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
63
|
+
s.specification_version = 3
|
64
|
+
|
65
|
+
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
66
|
+
s.add_runtime_dependency(%q<activemodel>, ["~> 3.0.0"])
|
67
|
+
s.add_runtime_dependency(%q<activesupport>, ["~> 3.0.0"])
|
68
|
+
s.add_runtime_dependency(%q<rest-client>, ["~> 1.6.1"])
|
69
|
+
s.add_development_dependency(%q<bundler>, ["~> 1.0.0"])
|
70
|
+
s.add_development_dependency(%q<fakeweb>, ["~> 1.3.0"])
|
71
|
+
s.add_development_dependency(%q<jeweler>, ["~> 1.5.2"])
|
72
|
+
s.add_development_dependency(%q<rcov>, [">= 0"])
|
73
|
+
s.add_development_dependency(%q<rspec>, ["~> 2.0.0"])
|
74
|
+
s.add_development_dependency(%q<ruby-debug>, [">= 0"])
|
75
|
+
else
|
76
|
+
s.add_dependency(%q<activemodel>, ["~> 3.0.0"])
|
77
|
+
s.add_dependency(%q<activesupport>, ["~> 3.0.0"])
|
78
|
+
s.add_dependency(%q<rest-client>, ["~> 1.6.1"])
|
79
|
+
s.add_dependency(%q<bundler>, ["~> 1.0.0"])
|
80
|
+
s.add_dependency(%q<fakeweb>, ["~> 1.3.0"])
|
81
|
+
s.add_dependency(%q<jeweler>, ["~> 1.5.2"])
|
82
|
+
s.add_dependency(%q<rcov>, [">= 0"])
|
83
|
+
s.add_dependency(%q<rspec>, ["~> 2.0.0"])
|
84
|
+
s.add_dependency(%q<ruby-debug>, [">= 0"])
|
85
|
+
end
|
86
|
+
else
|
87
|
+
s.add_dependency(%q<activemodel>, ["~> 3.0.0"])
|
88
|
+
s.add_dependency(%q<activesupport>, ["~> 3.0.0"])
|
89
|
+
s.add_dependency(%q<rest-client>, ["~> 1.6.1"])
|
90
|
+
s.add_dependency(%q<bundler>, ["~> 1.0.0"])
|
91
|
+
s.add_dependency(%q<fakeweb>, ["~> 1.3.0"])
|
92
|
+
s.add_dependency(%q<jeweler>, ["~> 1.5.2"])
|
93
|
+
s.add_dependency(%q<rcov>, [">= 0"])
|
94
|
+
s.add_dependency(%q<rspec>, ["~> 2.0.0"])
|
95
|
+
s.add_dependency(%q<ruby-debug>, [">= 0"])
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
data/lib/jaysus.rb
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
# rubygems
|
2
|
+
require 'rubygems'
|
3
|
+
|
4
|
+
# system dependencies
|
5
|
+
require 'fileutils'
|
6
|
+
require 'pathname'
|
7
|
+
|
8
|
+
# gem dependencies
|
9
|
+
require 'active_support/core_ext/array/wrap'
|
10
|
+
require 'active_support/core_ext/object/blank'
|
11
|
+
require 'active_support/secure_random'
|
12
|
+
require 'active_model'
|
13
|
+
require 'rest_client'
|
14
|
+
|
15
|
+
# library files
|
16
|
+
require 'jaysus/base'
|
17
|
+
require 'jaysus/local'
|
18
|
+
require 'jaysus/remote'
|
data/lib/jaysus/base.rb
ADDED
@@ -0,0 +1,165 @@
|
|
1
|
+
module Jaysus
|
2
|
+
|
3
|
+
class Base
|
4
|
+
extend ActiveModel::Naming
|
5
|
+
include ActiveModel::Serialization
|
6
|
+
include ActiveModel::Serializers::JSON
|
7
|
+
|
8
|
+
def self.attribute(name)
|
9
|
+
self.attributes << name
|
10
|
+
class_eval do
|
11
|
+
define_method(name) do # def title
|
12
|
+
instance_variable_get("@#{name}") # @title
|
13
|
+
end # end
|
14
|
+
|
15
|
+
define_method("#{name}=") do |value| # def title=(value)
|
16
|
+
instance_variable_set("@#{name}", value) # @title = value
|
17
|
+
end # end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.attributes
|
22
|
+
@attributes ||= []
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.create(attrs = {})
|
26
|
+
new(attrs).save
|
27
|
+
end
|
28
|
+
|
29
|
+
def self.find(id, &block)
|
30
|
+
new(decode(id, &block))
|
31
|
+
end
|
32
|
+
|
33
|
+
def self.find_or_create_by_attributes(attributes, *values)
|
34
|
+
search = find_by_attributes(attributes, *values)
|
35
|
+
return search unless search.blank?
|
36
|
+
attrs = {}
|
37
|
+
attributes.zip(values).each do |pair|
|
38
|
+
attrs[pair.first] = pair.last
|
39
|
+
end
|
40
|
+
create(attrs)
|
41
|
+
end
|
42
|
+
|
43
|
+
def self.find_by_attributes(attributes, *values)
|
44
|
+
find_all_by_attributes(attributes, *values).first
|
45
|
+
end
|
46
|
+
|
47
|
+
def self.find_all_by_attributes(attributes, *values)
|
48
|
+
all.each.select do |record|
|
49
|
+
attributes.zip(values).all? do |matcher|
|
50
|
+
record.send(matcher.first) == matcher.last
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def self.decode(id, &block)
|
56
|
+
ActiveSupport::JSON.decode(
|
57
|
+
yield
|
58
|
+
)[self.model_name.singular]
|
59
|
+
end
|
60
|
+
|
61
|
+
def self.model_base
|
62
|
+
"#{model_name}::Base".constantize
|
63
|
+
end
|
64
|
+
|
65
|
+
def self.local_base
|
66
|
+
"#{model_name}::Local".constantize
|
67
|
+
end
|
68
|
+
|
69
|
+
def self.remote_base
|
70
|
+
"#{model_name}::Remote".constantize
|
71
|
+
end
|
72
|
+
|
73
|
+
def self.model_name
|
74
|
+
ActiveModel::Name.new(super.split('::').first.constantize)
|
75
|
+
end
|
76
|
+
|
77
|
+
def self.plural_name
|
78
|
+
model_name.plural
|
79
|
+
end
|
80
|
+
|
81
|
+
def self.singular_name
|
82
|
+
model_name.singular
|
83
|
+
end
|
84
|
+
|
85
|
+
def self.primary_key(name = nil)
|
86
|
+
@primary_key = name if name.present?
|
87
|
+
@primary_key
|
88
|
+
end
|
89
|
+
|
90
|
+
def self.store_file_dir
|
91
|
+
dir = Local.store_dir.join(store_file_dir_name)
|
92
|
+
dir.mkpath unless dir.exist?
|
93
|
+
dir
|
94
|
+
end
|
95
|
+
|
96
|
+
def self.store_file_dir_name
|
97
|
+
self.model_name.plural
|
98
|
+
end
|
99
|
+
|
100
|
+
def self.method_missing(method, *args)
|
101
|
+
if method.to_s.match(/^find_by/)
|
102
|
+
attrs = method.to_s.gsub(/^find_by_/, '').split('_and_')
|
103
|
+
find_by_attributes(attrs, *args)
|
104
|
+
elsif method.to_s.match(/^find_or_create_by/)
|
105
|
+
attrs = method.to_s.gsub(/^find_or_create_by_/, '').split('_and_')
|
106
|
+
find_or_create_by_attributes(attrs, *args)
|
107
|
+
else
|
108
|
+
super
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
def initialize(set_attrs = {})
|
113
|
+
set_attributes(set_attrs)
|
114
|
+
end
|
115
|
+
|
116
|
+
def attributes
|
117
|
+
out = {}
|
118
|
+
self.class.model_base.attributes.each do |attribute|
|
119
|
+
out[attribute.to_s] = send(attribute)
|
120
|
+
end
|
121
|
+
out
|
122
|
+
end
|
123
|
+
|
124
|
+
def attributes=(attrs = {})
|
125
|
+
set_attributes(attrs)
|
126
|
+
end
|
127
|
+
|
128
|
+
def destroy(&block)
|
129
|
+
yield
|
130
|
+
end
|
131
|
+
|
132
|
+
def update_attributes(attrs)
|
133
|
+
set_attributes(attrs)
|
134
|
+
save
|
135
|
+
end
|
136
|
+
|
137
|
+
def set_attributes(attrs)
|
138
|
+
attrs.each_pair do |attr, value|
|
139
|
+
self.send("#{attr}=", value)
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
def save(&block)
|
144
|
+
yield if block_given?
|
145
|
+
end
|
146
|
+
|
147
|
+
def store_file
|
148
|
+
self.class.store_file_dir.join(store_file_name)
|
149
|
+
end
|
150
|
+
|
151
|
+
def store_file_name
|
152
|
+
pk = send(self.class.model_base.primary_key)
|
153
|
+
if pk.blank?
|
154
|
+
pk = ActiveSupport::SecureRandom.hex(32)
|
155
|
+
send("#{self.class.model_base.primary_key}=", pk)
|
156
|
+
end
|
157
|
+
"#{send(self.class.model_base.primary_key)}"
|
158
|
+
end
|
159
|
+
|
160
|
+
def persisted?
|
161
|
+
store_file.exist?
|
162
|
+
end
|
163
|
+
end
|
164
|
+
|
165
|
+
end
|
data/lib/jaysus/local.rb
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
module Jaysus
|
2
|
+
module Local
|
3
|
+
|
4
|
+
def self.store_dir
|
5
|
+
@store_dir ||= Pathname.new('.')
|
6
|
+
end
|
7
|
+
|
8
|
+
def self.store_dir=(dir)
|
9
|
+
@store_dir = Pathname.new(dir)
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.included(base)
|
13
|
+
base.extend(ClassMethods)
|
14
|
+
end
|
15
|
+
|
16
|
+
def destroy
|
17
|
+
super do
|
18
|
+
store_file.delete
|
19
|
+
self
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def save
|
24
|
+
super do
|
25
|
+
store_file.open('w') do |file|
|
26
|
+
file.write(self.to_json)
|
27
|
+
end
|
28
|
+
self
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
module ClassMethods
|
33
|
+
def all
|
34
|
+
records = []
|
35
|
+
Dir[store_file_dir.join('*')].each do |id|
|
36
|
+
records << find(id)
|
37
|
+
end
|
38
|
+
records
|
39
|
+
end
|
40
|
+
|
41
|
+
def find(id)
|
42
|
+
super do
|
43
|
+
store_file_dir.join("#{id}").read
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
module Jaysus
|
2
|
+
module Remote
|
3
|
+
def self.base_url
|
4
|
+
@base_url ||= ''
|
5
|
+
end
|
6
|
+
|
7
|
+
def self.base_url=(url)
|
8
|
+
@base_url = url
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.included(base)
|
12
|
+
base.extend(ClassMethods)
|
13
|
+
end
|
14
|
+
|
15
|
+
def destroy
|
16
|
+
super do
|
17
|
+
RestClient.delete(remote_url,{
|
18
|
+
'Accept' => 'application/json'
|
19
|
+
})
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def save
|
24
|
+
super do
|
25
|
+
response = if pk = self.send(self.class.model_base.primary_key)
|
26
|
+
RestClient.put("#{self.class.model_url}/#{pk}", self.to_json, {
|
27
|
+
'Content-Type' => 'application/json'
|
28
|
+
})
|
29
|
+
else
|
30
|
+
RestClient.post(self.class.model_url, self.to_json, {
|
31
|
+
'Content-Type' => 'application/json'
|
32
|
+
})
|
33
|
+
end
|
34
|
+
decoded_response = ActiveSupport::JSON.decode(
|
35
|
+
response
|
36
|
+
)[self.class.singular_name]
|
37
|
+
self.set_attributes(decoded_response)
|
38
|
+
self
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def remote_url
|
43
|
+
pk = self.send(self.class.model_base.primary_key)
|
44
|
+
return if pk.blank?
|
45
|
+
"#{self.class.model_url}/#{pk}"
|
46
|
+
end
|
47
|
+
|
48
|
+
module ClassMethods
|
49
|
+
def model_url
|
50
|
+
"#{Jaysus::Remote.base_url}/#{self.plural_name}"
|
51
|
+
end
|
52
|
+
|
53
|
+
def all
|
54
|
+
records = []
|
55
|
+
ActiveSupport::JSON.decode(RestClient.get(model_url,{
|
56
|
+
'Accept' => 'application/json'
|
57
|
+
})).each do |raw_record|
|
58
|
+
records << new(raw_record[self.singular_name])
|
59
|
+
end
|
60
|
+
records
|
61
|
+
end
|
62
|
+
|
63
|
+
def find(id)
|
64
|
+
super do
|
65
|
+
RestClient.get("#{model_url}/#{id}",{
|
66
|
+
'Accept' => 'application/json'
|
67
|
+
})
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
data/spec/fixtures/1
ADDED
data/spec/local_spec.rb
ADDED
@@ -0,0 +1,77 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
+
|
3
|
+
describe Jaysus::Local do
|
4
|
+
let(:site) { Site::Local.new({ :title => "New Site", :user_id => 1 }) }
|
5
|
+
|
6
|
+
describe Site::Local do
|
7
|
+
subject { Site::Local }
|
8
|
+
its(:model_name) { should == 'Site' }
|
9
|
+
its(:store_file_dir_name) { should == 'sites' }
|
10
|
+
end
|
11
|
+
|
12
|
+
describe "finder methods" do
|
13
|
+
before(:each) { FileUtils.cp('spec/fixtures/1', Site::Local.store_file_dir) }
|
14
|
+
|
15
|
+
describe ".all" do
|
16
|
+
subject { Site::Local.all }
|
17
|
+
its(:length) { should == 1}
|
18
|
+
its(:first) { should be_a_kind_of(Site::Local) }
|
19
|
+
end
|
20
|
+
|
21
|
+
describe ".find" do
|
22
|
+
subject { Site::Local.find(1) }
|
23
|
+
it { should_not be_nil }
|
24
|
+
its(:title) { should == "A nice fixture" }
|
25
|
+
end
|
26
|
+
|
27
|
+
describe ".find_by_x" do
|
28
|
+
subject { Site::Local.find_by_title("A nice fixture") }
|
29
|
+
it { should_not be_nil }
|
30
|
+
its(:title) { should == "A nice fixture" }
|
31
|
+
end
|
32
|
+
|
33
|
+
describe ".find_or_create_by_x" do
|
34
|
+
subject { Site::Local.find_or_create_by_id(2) }
|
35
|
+
it { should_not be_nil }
|
36
|
+
its(:title) { should be_blank }
|
37
|
+
its(:id) { should == 2 }
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
describe ".new" do
|
42
|
+
subject { site }
|
43
|
+
|
44
|
+
its(:title) { should == "New Site"}
|
45
|
+
its(:user_id) { should == 1 }
|
46
|
+
end
|
47
|
+
|
48
|
+
describe "#to_json" do
|
49
|
+
let(:decoded_site) { ActiveSupport::JSON.decode(site.to_json)['site'] }
|
50
|
+
|
51
|
+
it("should have a title") { decoded_site['title'].should == "New Site" }
|
52
|
+
it("should have a user id"){ decoded_site['user_id'].should == 1 }
|
53
|
+
end
|
54
|
+
|
55
|
+
describe "#save" do
|
56
|
+
subject { site }
|
57
|
+
|
58
|
+
before do
|
59
|
+
site.save
|
60
|
+
end
|
61
|
+
|
62
|
+
it { should be_persisted }
|
63
|
+
its(:id) { should be_a_kind_of(String) }
|
64
|
+
end
|
65
|
+
|
66
|
+
describe "#update_attributes" do
|
67
|
+
subject { site.update_attributes(:title => "Newer Site")}
|
68
|
+
its(:title) { should == "Newer Site" }
|
69
|
+
end
|
70
|
+
|
71
|
+
describe "#destroy" do
|
72
|
+
before { site.save; site.destroy }
|
73
|
+
subject { site.store_file }
|
74
|
+
it { should_not exist }
|
75
|
+
end
|
76
|
+
|
77
|
+
end
|
data/spec/remote_spec.rb
ADDED
@@ -0,0 +1,90 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
+
|
3
|
+
describe Jaysus::Remote do
|
4
|
+
let(:site) { Site::Remote.new({ :title => "New Site" }) }
|
5
|
+
|
6
|
+
describe ".all" do
|
7
|
+
before do
|
8
|
+
RestClient.should_receive(:get).with(
|
9
|
+
'http://testapi/sites',
|
10
|
+
{
|
11
|
+
'Accept' => 'application/json'
|
12
|
+
}
|
13
|
+
).and_return(File.read('spec/fixtures/all.json'))
|
14
|
+
end
|
15
|
+
subject { Site::Remote.all.first }
|
16
|
+
it { should_not be_nil }
|
17
|
+
its(:title) { should == "I'm from all" }
|
18
|
+
end
|
19
|
+
|
20
|
+
describe ".find" do
|
21
|
+
before do
|
22
|
+
RestClient.should_receive(:get).with(
|
23
|
+
'http://testapi/sites/42',
|
24
|
+
{
|
25
|
+
'Accept' => 'application/json'
|
26
|
+
}
|
27
|
+
).and_return(File.read('spec/fixtures/find_site.json'))
|
28
|
+
end
|
29
|
+
subject { Site::Remote.find(42) }
|
30
|
+
it { should_not be_nil }
|
31
|
+
its(:title) { should == 'The Answer to Life, the Universe and Everything'}
|
32
|
+
its(:user_id) { should == 42 }
|
33
|
+
end
|
34
|
+
|
35
|
+
describe "#save" do
|
36
|
+
before do
|
37
|
+
RestClient.should_receive(:post).with(
|
38
|
+
'http://testapi/sites',
|
39
|
+
site.to_json,
|
40
|
+
{
|
41
|
+
'Content-Type' => 'application/json'
|
42
|
+
}
|
43
|
+
).and_return(File.read('spec/fixtures/new_site.json'))
|
44
|
+
site.save
|
45
|
+
end
|
46
|
+
|
47
|
+
subject { site }
|
48
|
+
its(:id) { should == 2 }
|
49
|
+
its(:title) { should == "New Site" }
|
50
|
+
end
|
51
|
+
|
52
|
+
describe "#update_attributes" do
|
53
|
+
before do
|
54
|
+
RestClient.should_receive(:get).with(
|
55
|
+
'http://testapi/sites/42',
|
56
|
+
{
|
57
|
+
'Accept' => 'application/json'
|
58
|
+
}
|
59
|
+
).and_return(File.read('spec/fixtures/find_site.json'))
|
60
|
+
|
61
|
+
RestClient.should_receive(:put).with(
|
62
|
+
'http://testapi/sites/42',
|
63
|
+
"{\"site\":{\"title\":\"Monster!\",\"id\":42,\"user_id\":42}}",
|
64
|
+
{
|
65
|
+
'Content-Type' => 'application/json'
|
66
|
+
}
|
67
|
+
).and_return(File.read('spec/fixtures/update_site.json'))
|
68
|
+
end
|
69
|
+
|
70
|
+
let(:site) { Site::Remote.find(42) }
|
71
|
+
subject { site.update_attributes(:title => 'Monster!') }
|
72
|
+
|
73
|
+
its(:title){ should == 'Monster!'}
|
74
|
+
end
|
75
|
+
|
76
|
+
describe "#destroy" do
|
77
|
+
before do
|
78
|
+
RestClient.should_receive(:delete).with(
|
79
|
+
'http://testapi/sites/42',
|
80
|
+
{
|
81
|
+
'Accept' => 'application/json'
|
82
|
+
}
|
83
|
+
)
|
84
|
+
end
|
85
|
+
let(:site) { Site::Remote.find(42) }
|
86
|
+
it "should be gone" do
|
87
|
+
site.destroy
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
2
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
3
|
+
require 'rspec'
|
4
|
+
require 'jaysus'
|
5
|
+
|
6
|
+
# Requires supporting files with custom matchers and macros, etc,
|
7
|
+
# in ./support/ and its subdirectories.
|
8
|
+
Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f}
|
9
|
+
|
10
|
+
RSpec.configure do |config|
|
11
|
+
config.after(:all) do
|
12
|
+
Dir[File.expand_path(File.dirname(__FILE__) + '/store/*')].each do |file|
|
13
|
+
FileUtils.rm_rf(file)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
metadata
ADDED
@@ -0,0 +1,237 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: jaysus
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 27
|
5
|
+
prerelease: false
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 1
|
9
|
+
- 0
|
10
|
+
version: 0.1.0
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- Paul Campbell
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2011-01-16 00:00:00 +00:00
|
19
|
+
default_executable:
|
20
|
+
dependencies:
|
21
|
+
- !ruby/object:Gem::Dependency
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
name: activemodel
|
25
|
+
version_requirements: &id001 !ruby/object:Gem::Requirement
|
26
|
+
none: false
|
27
|
+
requirements:
|
28
|
+
- - ~>
|
29
|
+
- !ruby/object:Gem::Version
|
30
|
+
hash: 7
|
31
|
+
segments:
|
32
|
+
- 3
|
33
|
+
- 0
|
34
|
+
- 0
|
35
|
+
version: 3.0.0
|
36
|
+
requirement: *id001
|
37
|
+
- !ruby/object:Gem::Dependency
|
38
|
+
type: :runtime
|
39
|
+
prerelease: false
|
40
|
+
name: activesupport
|
41
|
+
version_requirements: &id002 !ruby/object:Gem::Requirement
|
42
|
+
none: false
|
43
|
+
requirements:
|
44
|
+
- - ~>
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
hash: 7
|
47
|
+
segments:
|
48
|
+
- 3
|
49
|
+
- 0
|
50
|
+
- 0
|
51
|
+
version: 3.0.0
|
52
|
+
requirement: *id002
|
53
|
+
- !ruby/object:Gem::Dependency
|
54
|
+
type: :runtime
|
55
|
+
prerelease: false
|
56
|
+
name: rest-client
|
57
|
+
version_requirements: &id003 !ruby/object:Gem::Requirement
|
58
|
+
none: false
|
59
|
+
requirements:
|
60
|
+
- - ~>
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
hash: 13
|
63
|
+
segments:
|
64
|
+
- 1
|
65
|
+
- 6
|
66
|
+
- 1
|
67
|
+
version: 1.6.1
|
68
|
+
requirement: *id003
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
type: :development
|
71
|
+
prerelease: false
|
72
|
+
name: bundler
|
73
|
+
version_requirements: &id004 !ruby/object:Gem::Requirement
|
74
|
+
none: false
|
75
|
+
requirements:
|
76
|
+
- - ~>
|
77
|
+
- !ruby/object:Gem::Version
|
78
|
+
hash: 23
|
79
|
+
segments:
|
80
|
+
- 1
|
81
|
+
- 0
|
82
|
+
- 0
|
83
|
+
version: 1.0.0
|
84
|
+
requirement: *id004
|
85
|
+
- !ruby/object:Gem::Dependency
|
86
|
+
type: :development
|
87
|
+
prerelease: false
|
88
|
+
name: fakeweb
|
89
|
+
version_requirements: &id005 !ruby/object:Gem::Requirement
|
90
|
+
none: false
|
91
|
+
requirements:
|
92
|
+
- - ~>
|
93
|
+
- !ruby/object:Gem::Version
|
94
|
+
hash: 27
|
95
|
+
segments:
|
96
|
+
- 1
|
97
|
+
- 3
|
98
|
+
- 0
|
99
|
+
version: 1.3.0
|
100
|
+
requirement: *id005
|
101
|
+
- !ruby/object:Gem::Dependency
|
102
|
+
type: :development
|
103
|
+
prerelease: false
|
104
|
+
name: jeweler
|
105
|
+
version_requirements: &id006 !ruby/object:Gem::Requirement
|
106
|
+
none: false
|
107
|
+
requirements:
|
108
|
+
- - ~>
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
hash: 7
|
111
|
+
segments:
|
112
|
+
- 1
|
113
|
+
- 5
|
114
|
+
- 2
|
115
|
+
version: 1.5.2
|
116
|
+
requirement: *id006
|
117
|
+
- !ruby/object:Gem::Dependency
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
name: rcov
|
121
|
+
version_requirements: &id007 !ruby/object:Gem::Requirement
|
122
|
+
none: false
|
123
|
+
requirements:
|
124
|
+
- - ">="
|
125
|
+
- !ruby/object:Gem::Version
|
126
|
+
hash: 3
|
127
|
+
segments:
|
128
|
+
- 0
|
129
|
+
version: "0"
|
130
|
+
requirement: *id007
|
131
|
+
- !ruby/object:Gem::Dependency
|
132
|
+
type: :development
|
133
|
+
prerelease: false
|
134
|
+
name: rspec
|
135
|
+
version_requirements: &id008 !ruby/object:Gem::Requirement
|
136
|
+
none: false
|
137
|
+
requirements:
|
138
|
+
- - ~>
|
139
|
+
- !ruby/object:Gem::Version
|
140
|
+
hash: 15
|
141
|
+
segments:
|
142
|
+
- 2
|
143
|
+
- 0
|
144
|
+
- 0
|
145
|
+
version: 2.0.0
|
146
|
+
requirement: *id008
|
147
|
+
- !ruby/object:Gem::Dependency
|
148
|
+
type: :development
|
149
|
+
prerelease: false
|
150
|
+
name: ruby-debug
|
151
|
+
version_requirements: &id009 !ruby/object:Gem::Requirement
|
152
|
+
none: false
|
153
|
+
requirements:
|
154
|
+
- - ">="
|
155
|
+
- !ruby/object:Gem::Version
|
156
|
+
hash: 3
|
157
|
+
segments:
|
158
|
+
- 0
|
159
|
+
version: "0"
|
160
|
+
requirement: *id009
|
161
|
+
description: Persist remote JSON APIs locally and vice versa
|
162
|
+
email: paul@rslw.com
|
163
|
+
executables: []
|
164
|
+
|
165
|
+
extensions: []
|
166
|
+
|
167
|
+
extra_rdoc_files:
|
168
|
+
- LICENSE.txt
|
169
|
+
- README.md
|
170
|
+
files:
|
171
|
+
- .document
|
172
|
+
- .rspec
|
173
|
+
- Gemfile
|
174
|
+
- Gemfile.lock
|
175
|
+
- LICENSE.txt
|
176
|
+
- README.md
|
177
|
+
- Rakefile
|
178
|
+
- VERSION
|
179
|
+
- jaysus.gemspec
|
180
|
+
- lib/jaysus.rb
|
181
|
+
- lib/jaysus/base.rb
|
182
|
+
- lib/jaysus/local.rb
|
183
|
+
- lib/jaysus/remote.rb
|
184
|
+
- spec/fixtures/1
|
185
|
+
- spec/fixtures/all.json
|
186
|
+
- spec/fixtures/find_site.json
|
187
|
+
- spec/fixtures/new_site.json
|
188
|
+
- spec/fixtures/update_site.json
|
189
|
+
- spec/local_spec.rb
|
190
|
+
- spec/remote_spec.rb
|
191
|
+
- spec/spec_helper.rb
|
192
|
+
- spec/support/debugger.rb
|
193
|
+
- spec/support/fakeweb.rb
|
194
|
+
- spec/support/jaysus.rb
|
195
|
+
- spec/support/site.rb
|
196
|
+
has_rdoc: true
|
197
|
+
homepage: http://github.com/paulca/jaysus
|
198
|
+
licenses:
|
199
|
+
- MIT
|
200
|
+
post_install_message:
|
201
|
+
rdoc_options: []
|
202
|
+
|
203
|
+
require_paths:
|
204
|
+
- lib
|
205
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
206
|
+
none: false
|
207
|
+
requirements:
|
208
|
+
- - ">="
|
209
|
+
- !ruby/object:Gem::Version
|
210
|
+
hash: 3
|
211
|
+
segments:
|
212
|
+
- 0
|
213
|
+
version: "0"
|
214
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
215
|
+
none: false
|
216
|
+
requirements:
|
217
|
+
- - ">="
|
218
|
+
- !ruby/object:Gem::Version
|
219
|
+
hash: 3
|
220
|
+
segments:
|
221
|
+
- 0
|
222
|
+
version: "0"
|
223
|
+
requirements: []
|
224
|
+
|
225
|
+
rubyforge_project:
|
226
|
+
rubygems_version: 1.3.7
|
227
|
+
signing_key:
|
228
|
+
specification_version: 3
|
229
|
+
summary: A Ruby library for managing local / remote JSON store
|
230
|
+
test_files:
|
231
|
+
- spec/local_spec.rb
|
232
|
+
- spec/remote_spec.rb
|
233
|
+
- spec/spec_helper.rb
|
234
|
+
- spec/support/debugger.rb
|
235
|
+
- spec/support/fakeweb.rb
|
236
|
+
- spec/support/jaysus.rb
|
237
|
+
- spec/support/site.rb
|