reptar 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (7) hide show
  1. checksums.yaml +7 -0
  2. data/LICENSE +21 -0
  3. data/README.md +219 -0
  4. data/lib/reptar.rb +70 -0
  5. data/reptar.gemspec +20 -0
  6. data/test/test_reptar.rb +287 -0
  7. metadata +63 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: b697d0d18295900df2f1722cb51d71c0a4ce8365
4
+ data.tar.gz: af8f219da49b99b8ef1fd6d6c09151064e926b8b
5
+ SHA512:
6
+ metadata.gz: 702b20eaab9fab83269f7596d51f4bef7522a3fdd85539834e5c61140e11152690464688b581d71caf4fe8cc93e39941b94198fc321c90c3dffccebe5d21d6a6
7
+ data.tar.gz: 68fff94ebf9cfe8be3a8f0487912d156a574203273941af58eba0d40067c6023335696ad724bd097677befa95a8cdc6c3653e995b5a774600ad618a663d42261
data/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2015 Julio Lopez
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,219 @@
1
+ Reptar
2
+ ====
3
+
4
+ Microlibrary for write representations of objects to your JSON APIs.
5
+
6
+ ![Reptar](http://vignette3.wikia.nocookie.net/godzilla/images/4/4c/Reptar.png)
7
+
8
+ ## Installation
9
+
10
+ Installing Reptar is as simple as running:
11
+
12
+ ```
13
+ $ gem install reptar
14
+ ```
15
+
16
+ Include Reptar in your Gemfile with gem 'reptar' or require it with require 'reptar'.
17
+
18
+ Usage
19
+ -----
20
+
21
+ ### Attributes
22
+
23
+ Inherit `Reptar to build your representation, initialize your Reptar class with your object and get your json output with `to_json`. Declare the fields you want to return with `attribute`
24
+
25
+ ```ruby
26
+ UserRep < Reptar
27
+ attribute :name
28
+ end
29
+
30
+ user = User.new(name: "Julio")
31
+ UserRep.new(user).to_json
32
+ # => "{\"name\":\"Julio\"}"
33
+ ```
34
+
35
+ You can define multiple attributes with `attributes`
36
+
37
+ ```ruby
38
+ UserRep < Reptar
39
+ attributes :first_name, :last_name, :email
40
+ end
41
+
42
+ user = User.new(first_name: "Julio", last_name: "Piero", email: "julio@example.com")
43
+ UserRep.new(user).to_json
44
+
45
+ # => The json output is:
46
+ {
47
+ "first_name": "Julio",
48
+ "last_name": "Piero",
49
+ "email": "julio@example.com"
50
+ }
51
+ ```
52
+
53
+ If you want to rename an attribute to send a different name in the json output you can use the `key` option.
54
+
55
+ ```ruby
56
+ UserRep < Reptar
57
+ attribute :name
58
+ attribute :city, key: :location
59
+ end
60
+
61
+ user = User.new(name: "Julio", city: "Lima")
62
+ UserRep.new(user).to_json
63
+
64
+ # => The json output is:
65
+ {
66
+ "name": "Julio",
67
+ "location": "Lima"
68
+ }
69
+ ```
70
+
71
+ ### Methods
72
+
73
+ Send your custom methods as attributes to return their results to the json output.
74
+
75
+ ```ruby
76
+ PostRep < Reptar
77
+ attributes :title, :slug
78
+
79
+ def slug
80
+ title.downcase.gsub(' ', '-')
81
+ end
82
+ end
83
+
84
+ post = Post.new(title: "My awesome post")
85
+ PostRep.new(post).to_json
86
+
87
+ # => The json output is:
88
+ {
89
+ "title": "My awesome post",
90
+ "slug": "my-awesome-post"
91
+ }
92
+ ```
93
+
94
+ ### Set your root
95
+
96
+ You can specify a root for prepend a keyname to your ouput, use the `root` option for that.
97
+
98
+ ```ruby
99
+ UserRep.new(user).to_json(root: :user)
100
+ # => The json output is:
101
+ {
102
+ "user": {
103
+ "first_name": "Julio",
104
+ "last_name": "Piero",
105
+ "email": "julio@example.com"
106
+ }
107
+ }
108
+ ```
109
+
110
+ ### Start with an array
111
+
112
+ You can initialize your representation class with an array of objects to return the output of each one.
113
+
114
+ ```ruby
115
+ UserRep < Reptar
116
+ attributes :name
117
+ end
118
+
119
+ user1 = User.new(name: "Julio")
120
+ user2 = User.new(name: "Abel")
121
+ user3 = User.new(name: "Piero")
122
+ users = [user1, user2, user3]
123
+ UserRep.new(users).to_json
124
+
125
+ # => The json output is:
126
+ [
127
+ { name: "Julio" },
128
+ { name: "Abel" },
129
+ { name: "Piero" }
130
+ ]
131
+ ```
132
+
133
+ ### Collections
134
+
135
+ `collection` method is available to be more explicit in your representation.
136
+
137
+ ```ruby
138
+ UserRep < Reptar
139
+ attribute :name
140
+ collection :languages
141
+ end
142
+
143
+ user = User.new(name: "Julio", languages: ["Ruby", "Js", "Go"])
144
+ UserRep.new(user).to_json
145
+
146
+ # => The json output is:
147
+ {
148
+ name: "Julio",
149
+ languages: ["Ruby", "Js", "Go"]
150
+ }
151
+ ```
152
+
153
+ ### Associations
154
+
155
+ You can associate your representation class with another using the `with` option, this is useful for return a nested output.
156
+
157
+ ```ruby
158
+ UserRep < Reptar
159
+ attributes :name, :email
160
+ attribute :company, with: "CompanyRep"
161
+ end
162
+
163
+ CompanyRep < Reptar
164
+ attributes :name, :city
165
+ end
166
+
167
+ user = User.new(name: "Julio", email: "julio@example.com")
168
+ user.company = Company.new(name: "Codalot", city: "Lima")
169
+ UserRep.new(user).to_json
170
+
171
+ # => The json output is:
172
+ {
173
+ name: "Julio",
174
+ email: "julio@example.com",
175
+ company: {
176
+ name: "Codalot",
177
+ city: "Lima"
178
+ }
179
+ }
180
+ ```
181
+
182
+ You are free to also use `collection for define your asocciations.
183
+
184
+ ```ruby
185
+ UserRep < Reptar
186
+ attributes :name, :email
187
+ collection :posts, with: "PostRep"
188
+ end
189
+
190
+ PostRep < Reptar
191
+ attributes :title, :content
192
+ end
193
+
194
+ user = User.new(name: "Julio", email: "julio@example.com")
195
+ user.posts << Post.new(title: "Awesome title 1", content: "lorem lipsum")
196
+ user.posts << Post.new(title: "Awesome title 2", content: "lorem lipsum")
197
+ user.posts << Post.new(title: "Awesome title 3", content: "lorem lipsum")
198
+ UserRep.new(user).to_json
199
+
200
+ # => The json output is:
201
+ {
202
+ name: "Julio",
203
+ email: "julio@example.com",
204
+ posts: [
205
+ {
206
+ title: "Awesome title 1",
207
+ content: "lorem lipsum"
208
+ },
209
+ {
210
+ title: "Awesome title 2",
211
+ content: "lorem lipsum"
212
+ },
213
+ {
214
+ title: "Awesome title 3",
215
+ content: "lorem lipsum"
216
+ }
217
+ ]
218
+ }
219
+ ```
data/lib/reptar.rb ADDED
@@ -0,0 +1,70 @@
1
+ # Copyright (c) 2015 Julio Lopez
2
+
3
+ # Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ # of this software and associated documentation files (the "Software"), to deal
5
+ # in the Software without restriction, including without limitation the rights
6
+ # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ # copies of the Software, and to permit persons to whom the Software is
8
+ # furnished to do so, subject to the following conditions:
9
+
10
+ # The above copyright notice and this permission notice shall be included in all
11
+ # copies or substantial portions of the Software.
12
+
13
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
19
+ # SOFTWARE.
20
+ require "json"
21
+
22
+ class Reptar
23
+ VERSION = "1.0.0"
24
+
25
+ class << self; attr_reader :nodes; end
26
+
27
+ def self.inherited(klass)
28
+ klass.instance_variable_set("@nodes", {})
29
+ end
30
+
31
+ def self.attribute(name, options = {})
32
+ @nodes[name] = options
33
+ end
34
+
35
+ def self.attributes(*attributes)
36
+ attributes.each{ |e| @nodes[e] = nil }
37
+ end
38
+
39
+ def self.method_missing(method_name, *args)
40
+ method_name == :collection ? self.send(:attribute, *args) : super
41
+ end
42
+
43
+ def initialize(object)
44
+ @object = object
45
+ end
46
+
47
+ def method_missing(method_name)
48
+ @object.respond_to?(method_name) ? @object.send(method_name) : super
49
+ end
50
+
51
+ def to_json(options = {})
52
+ root = options[:root]
53
+ (root ? { root => representable } : representable).to_json
54
+ end
55
+
56
+ def representable
57
+ return nil unless @object
58
+ @object.is_a?(Array) ? @object.map{|e| self.class.new(e).build_hash } : build_hash
59
+ end
60
+
61
+ def build_hash
62
+ self.class.nodes.each_with_object({}) do |(name, options), hash|
63
+ rep = options[:with] if options
64
+ res = @object.respond_to?(name) ? @object.send(name) : self.send(name)
65
+ res = Object.const_get(rep).new(res).representable if rep
66
+ name = options[:key] if options && options[:key]
67
+ hash[name] = res
68
+ end
69
+ end
70
+ end
data/reptar.gemspec ADDED
@@ -0,0 +1,20 @@
1
+ require "./lib/reptar"
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = "reptar"
5
+ s.version = Reptar::VERSION
6
+ s.summary = "Microlibrary for write representations of objects to your JSON APIs."
7
+ s.description = "Microlibrary for write representations of objects to your JSON APIs."
8
+ s.authors = ["Julio Lopez"]
9
+ s.email = ["ljuliom@gmail.com"]
10
+ s.homepage = "http://github.com/TheBlasfem/reptar"
11
+ s.files = Dir[
12
+ "LICENSE",
13
+ "README.md",
14
+ "lib/**/*.rb",
15
+ "*.gemspec",
16
+ "test/**/*.rb"
17
+ ]
18
+ s.license = "MIT"
19
+ s.add_development_dependency "cutest", "1.1.3"
20
+ end
@@ -0,0 +1,287 @@
1
+ require File.expand_path("../lib/reptar", File.dirname(__FILE__))
2
+ require "ostruct"
3
+
4
+ User = OpenStruct
5
+ Post = OpenStruct
6
+ Company = OpenStruct
7
+
8
+ test "single attribute" do
9
+ UserReptar = Class.new(Reptar) do
10
+ attribute :name
11
+ end
12
+
13
+ user = User.new(name: "Julio")
14
+ result = {name: "Julio"}.to_json
15
+ assert_equal UserReptar.new(user).to_json, result
16
+ end
17
+
18
+ test "nil attribute" do
19
+ UserReptar = Class.new(Reptar) do
20
+ attribute :name
21
+ end
22
+
23
+ user = User.new(name: nil)
24
+ result = {name: nil}.to_json
25
+ assert_equal UserReptar.new(user).to_json, result
26
+ end
27
+
28
+ test "changing the key attribute" do
29
+ PostReptar = Class.new(Reptar) do
30
+ attribute :slug, key: :url
31
+ end
32
+
33
+ post = Post.new(slug: "this-is-cool")
34
+ result = {url: "this-is-cool"}.to_json
35
+ assert_equal PostReptar.new(post).to_json, result
36
+ end
37
+
38
+ test "multiple attributes" do
39
+ UserReptar = Class.new(Reptar) do
40
+ attributes :name, :email
41
+ end
42
+
43
+ user = User.new(name: "Julio", email: "julio@example.com")
44
+ result = {name: "Julio", email: "julio@example.com"}.to_json
45
+ assert_equal UserReptar.new(user).to_json, result
46
+ end
47
+
48
+ test "method as attribute" do
49
+ PostReptar = Class.new(Reptar) do
50
+ attribute :slug
51
+
52
+ def slug
53
+ "#{name}-#{id}"
54
+ end
55
+ end
56
+
57
+ post = Post.new(name: "a-demo-post", id: 1)
58
+ result = {slug: "a-demo-post-1"}.to_json
59
+ assert_equal PostReptar.new(post).to_json, result
60
+ end
61
+
62
+ test "aplying root to single element" do
63
+ UserReptar = Class.new(Reptar) do
64
+ attribute :name
65
+ end
66
+
67
+ user = User.new(name: "Julio")
68
+ result = {user: {name: "Julio"}}.to_json
69
+ assert_equal UserReptar.new(user).to_json(root: :user), result
70
+ end
71
+
72
+ test "aplying root to a multiple elements" do
73
+ UserReptar = Class.new(Reptar) do
74
+ attribute :name
75
+ end
76
+
77
+ users = [User.new(name: "Julio"), User.new(name: "Piero")]
78
+ result = {
79
+ users: [
80
+ { name: "Julio" },
81
+ { name: "Piero" }
82
+ ]
83
+ }.to_json
84
+ assert_equal UserReptar.new(users).to_json(root: :users), result
85
+ end
86
+
87
+ test "initialize with an array" do
88
+ UserReptar = Class.new(Reptar) do
89
+ attribute :name
90
+ end
91
+
92
+ users = [User.new(name: "Julio"), User.new(name: "Piero")]
93
+
94
+ result = [
95
+ { name: "Julio" },
96
+ { name: "Piero" }
97
+ ].to_json
98
+
99
+ assert_equal UserReptar.new(users).to_json, result
100
+ end
101
+
102
+ test "array collection" do
103
+ UserReptar = Class.new(Reptar) do
104
+ attribute :name
105
+ collection :languages
106
+ end
107
+
108
+ user = User.new(name: "Julio", languages: ["Ruby", "Js", "Go"])
109
+
110
+ result = {
111
+ name: "Julio",
112
+ languages: ["Ruby", "Js", "Go"]
113
+ }.to_json
114
+
115
+ assert_equal UserReptar.new(user).to_json, result
116
+ end
117
+
118
+ test "a single representable association" do
119
+ UserReptar = Class.new(Reptar) do
120
+ attribute :name
121
+ attribute :company, with: "CompanyReptar"
122
+ end
123
+
124
+ CompanyReptar = Class.new(Reptar) do
125
+ attribute :name
126
+ end
127
+ user = User.new(name: "Julio")
128
+ user.company = Company.new(name: "Codalot")
129
+
130
+ result = {
131
+ name: "Julio",
132
+ company: {
133
+ name: "Codalot"
134
+ }
135
+ }.to_json
136
+
137
+ assert_equal UserReptar.new(user).to_json, result
138
+ end
139
+
140
+ test "single representable association as nil" do
141
+ UserReptar = Class.new(Reptar) do
142
+ attribute :name
143
+ attribute :company, with: "CompanyReptar"
144
+ end
145
+ user = User.new(name: "Julio")
146
+ user.company = nil
147
+
148
+ result = {
149
+ name: "Julio",
150
+ company: nil
151
+ }.to_json
152
+
153
+ assert_equal UserReptar.new(user).to_json, result
154
+ end
155
+
156
+ test "array with association" do
157
+ UserReptar = Class.new(Reptar) do
158
+ attribute :name
159
+ attribute :company, with: "CompanyReptar"
160
+ end
161
+
162
+ CompanyReptar = Class.new(Reptar) do
163
+ attribute :name
164
+ end
165
+
166
+ users = [
167
+ User.new(name: "Julio", company: Company.new(name: "Codalot")),
168
+ User.new(name: "Piero", company: Company.new(name: "Velocis"))
169
+ ]
170
+
171
+ result = [
172
+ {
173
+ name: "Julio",
174
+ company: {
175
+ name: "Codalot"
176
+ }
177
+ },
178
+ {
179
+ name: "Piero",
180
+ company: {
181
+ name: "Velocis"
182
+ }
183
+ }
184
+ ].to_json
185
+
186
+ assert_equal UserReptar.new(users).to_json, result
187
+ end
188
+
189
+ test "serializes object with collection" do
190
+ UserReptar = Class.new(Reptar) do
191
+ attribute :name
192
+ collection :posts, with: "PostReptar"
193
+ end
194
+
195
+ PostReptar = Class.new(Reptar) do
196
+ attribute :title
197
+ end
198
+
199
+ user = User.new(name: "Julio")
200
+ user.posts = [
201
+ Post.new(title: "Awesome title"),
202
+ Post.new(title: "Cats are dominating the world right now")
203
+ ]
204
+
205
+ result = {
206
+ name: "Julio",
207
+ posts: [
208
+ {
209
+ title: "Awesome title"
210
+ },
211
+ {
212
+ title: "Cats are dominating the world right now"
213
+ }
214
+ ]
215
+ }.to_json
216
+
217
+ assert_equal UserReptar.new(user).to_json, result
218
+ end
219
+
220
+ test "array with representable collections" do
221
+ UserReptar = Class.new(Reptar) do
222
+ attribute :name
223
+ collection :posts, with: "PostReptar"
224
+ end
225
+
226
+ PostReptar = Class.new(Reptar) do
227
+ attribute :title
228
+ end
229
+
230
+ users = [
231
+ User.new(
232
+ name: "Julio",
233
+ posts: [
234
+ Post.new(title: "Hi, I'm a dog")
235
+ ]
236
+ ),
237
+ User.new(
238
+ name: "Piero",
239
+ posts: [
240
+ Post.new(title: "I like turtles"),
241
+ Post.new(title: "Please come back PT!"),
242
+ ]
243
+ )
244
+ ]
245
+
246
+ result = [
247
+ {
248
+ name: "Julio",
249
+ posts: [
250
+ {
251
+ title: "Hi, I'm a dog"
252
+ }
253
+ ]
254
+ },
255
+ {
256
+ name: "Piero",
257
+ posts: [
258
+ {
259
+ title: "I like turtles"
260
+ },
261
+ {
262
+ title: "Please come back PT!"
263
+ }
264
+ ]
265
+ }
266
+ ].to_json
267
+
268
+ assert_equal UserReptar.new(users).to_json, result
269
+ end
270
+
271
+ test "custom association method" do
272
+ PostReptar = Class.new(Reptar) do
273
+ attribute :title
274
+ end
275
+
276
+ UserReptar = Class.new(Reptar) do
277
+ collection :posts, with: "PostReptar"
278
+
279
+ def posts
280
+ [Post.new(title: "I like turtles")]
281
+ end
282
+ end
283
+
284
+ user = User.new
285
+ result = { posts: [{title: "I like turtles" }] }.to_json
286
+ assert_equal UserReptar.new(user).to_json, result
287
+ end
metadata ADDED
@@ -0,0 +1,63 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: reptar
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Julio Lopez
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-05-12 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: cutest
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - '='
18
+ - !ruby/object:Gem::Version
19
+ version: 1.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.1.3
27
+ description: Microlibrary for write representations of objects to your JSON APIs.
28
+ email:
29
+ - ljuliom@gmail.com
30
+ executables: []
31
+ extensions: []
32
+ extra_rdoc_files: []
33
+ files:
34
+ - LICENSE
35
+ - README.md
36
+ - lib/reptar.rb
37
+ - reptar.gemspec
38
+ - test/test_reptar.rb
39
+ homepage: http://github.com/TheBlasfem/reptar
40
+ licenses:
41
+ - MIT
42
+ metadata: {}
43
+ post_install_message:
44
+ rdoc_options: []
45
+ require_paths:
46
+ - lib
47
+ required_ruby_version: !ruby/object:Gem::Requirement
48
+ requirements:
49
+ - - ">="
50
+ - !ruby/object:Gem::Version
51
+ version: '0'
52
+ required_rubygems_version: !ruby/object:Gem::Requirement
53
+ requirements:
54
+ - - ">="
55
+ - !ruby/object:Gem::Version
56
+ version: '0'
57
+ requirements: []
58
+ rubyforge_project:
59
+ rubygems_version: 2.2.2
60
+ signing_key:
61
+ specification_version: 4
62
+ summary: Microlibrary for write representations of objects to your JSON APIs.
63
+ test_files: []