activegist 0.6.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/.gitignore +6 -0
- data/.travis.yml +9 -0
- data/CHANGELOG +2 -0
- data/Gemfile +7 -0
- data/LICENSE +20 -0
- data/README.rdoc +96 -0
- data/Rakefile +15 -0
- data/activegist.gemspec +29 -0
- data/lib/active_gist.rb +134 -0
- data/lib/active_gist/api.rb +33 -0
- data/lib/active_gist/attributes.rb +107 -0
- data/lib/active_gist/class_methods.rb +42 -0
- data/lib/active_gist/errors/invalid.rb +5 -0
- data/lib/active_gist/files.rb +40 -0
- data/lib/active_gist/version.rb +8 -0
- data/lib/activegist.rb +1 -0
- data/spec/fixtures/all_gists.json +87 -0
- data/spec/fixtures/gist_1.json +78 -0
- data/spec/fixtures/gist_1_star.json +4 -0
- data/spec/fixtures/gist_1_updated.json +71 -0
- data/spec/fixtures/gist_2.json +65 -0
- data/spec/fixtures/gist_2_star.json +4 -0
- data/spec/fixtures/gist_delete_star.json +4 -0
- data/spec/fixtures/gist_destroy.json +4 -0
- data/spec/fixtures/gist_forked.json +33 -0
- data/spec/fixtures/gist_put_star.json +4 -0
- data/spec/fixtures/new_gist.json +63 -0
- data/spec/fixtures/public_gists.json +61 -0
- data/spec/fixtures/starred_gists.json +35 -0
- data/spec/lib/active_gist/files_spec.rb +16 -0
- data/spec/lib/active_gist_spec.rb +308 -0
- data/spec/spec_helper.rb +7 -0
- data/spec/support/fakeweb.rb +20 -0
- metadata +173 -0
@@ -0,0 +1,63 @@
|
|
1
|
+
HTTP/1.1 201 Created
|
2
|
+
Location: https://api.github.com/gists/1
|
3
|
+
X-RateLimit-Limit: 5000
|
4
|
+
X-RateLimit-Remaining: 4999
|
5
|
+
|
6
|
+
{
|
7
|
+
"url": "https://api.github.com/gists/1",
|
8
|
+
"id": "1",
|
9
|
+
"description": "description of gist",
|
10
|
+
"public": true,
|
11
|
+
"user": {
|
12
|
+
"login": "octocat",
|
13
|
+
"id": 1,
|
14
|
+
"avatar_url": "https://github.com/images/error/octocat_happy.gif",
|
15
|
+
"gravatar_id": "somehexcode",
|
16
|
+
"url": "https://api.github.com/users/octocat"
|
17
|
+
},
|
18
|
+
"files": {
|
19
|
+
"ring.erl": {
|
20
|
+
"size": 932,
|
21
|
+
"filename": "ring.erl",
|
22
|
+
"raw_url": "https://gist.github.com/raw/365370/8c4d2d43d178df44f4c03a7f2ac0ff512853564e/ring.erl",
|
23
|
+
"content": "contents of gist"
|
24
|
+
}
|
25
|
+
},
|
26
|
+
"comments": 0,
|
27
|
+
"html_url": "https://gist.github.com/1",
|
28
|
+
"git_pull_url": "git://gist.github.com/1.git",
|
29
|
+
"git_push_url": "git@gist.github.com:1.git",
|
30
|
+
"created_at": "2010-04-14T02:15:15Z",
|
31
|
+
"forks": [
|
32
|
+
{
|
33
|
+
"user": {
|
34
|
+
"login": "octocat",
|
35
|
+
"id": 1,
|
36
|
+
"avatar_url": "https://github.com/images/error/octocat_happy.gif",
|
37
|
+
"gravatar_id": "somehexcode",
|
38
|
+
"url": "https://api.github.com/users/octocat"
|
39
|
+
},
|
40
|
+
"url": "https://api.github.com/gists/5",
|
41
|
+
"created_at": "2011-04-14T16:00:49Z"
|
42
|
+
}
|
43
|
+
],
|
44
|
+
"history": [
|
45
|
+
{
|
46
|
+
"url": "https://api.github.com/gists/1/57a7f021a713b1c5a6a199b54cc514735d2d462f",
|
47
|
+
"version": "57a7f021a713b1c5a6a199b54cc514735d2d462f",
|
48
|
+
"user": {
|
49
|
+
"login": "octocat",
|
50
|
+
"id": 1,
|
51
|
+
"avatar_url": "https://github.com/images/error/octocat_happy.gif",
|
52
|
+
"gravatar_id": "somehexcode",
|
53
|
+
"url": "https://api.github.com/users/octocat"
|
54
|
+
},
|
55
|
+
"change_status": {
|
56
|
+
"deletions": 0,
|
57
|
+
"additions": 180,
|
58
|
+
"total": 180
|
59
|
+
},
|
60
|
+
"committed_at": "2010-04-14T02:15:15Z"
|
61
|
+
}
|
62
|
+
]
|
63
|
+
}
|
@@ -0,0 +1,61 @@
|
|
1
|
+
HTTP/1.1 200 OK
|
2
|
+
Link: <https://api.github.com/resource?page=2>; rel="next",
|
3
|
+
<https://api.github.com/resource?page=5>; rel="last"
|
4
|
+
X-RateLimit-Limit: 5000
|
5
|
+
X-RateLimit-Remaining: 4999
|
6
|
+
Content-type: application/json; charset=utf-8
|
7
|
+
|
8
|
+
[
|
9
|
+
{
|
10
|
+
"url": "https://api.github.com/gists/1",
|
11
|
+
"id": "1",
|
12
|
+
"description": "description of gist",
|
13
|
+
"public": true,
|
14
|
+
"user": {
|
15
|
+
"login": "octocat",
|
16
|
+
"id": 1,
|
17
|
+
"avatar_url": "https://github.com/images/error/octocat_happy.gif",
|
18
|
+
"gravatar_id": "somehexcode",
|
19
|
+
"url": "https://api.github.com/users/octocat"
|
20
|
+
},
|
21
|
+
"files": {
|
22
|
+
"ring.erl": {
|
23
|
+
"size": 932,
|
24
|
+
"filename": "ring.erl",
|
25
|
+
"raw_url": "https://gist.github.com/raw/365370/8c4d2d43d178df44f4c03a7f2ac0ff512853564e/ring.erl",
|
26
|
+
"content": "contents of gist"
|
27
|
+
}
|
28
|
+
},
|
29
|
+
"comments": 0,
|
30
|
+
"html_url": "https://gist.github.com/1",
|
31
|
+
"git_pull_url": "git://gist.github.com/1.git",
|
32
|
+
"git_push_url": "git@gist.github.com:1.git",
|
33
|
+
"created_at": "2010-04-14T02:15:15Z"
|
34
|
+
},
|
35
|
+
{
|
36
|
+
"url": "https://api.github.com/gists/2",
|
37
|
+
"id": "2",
|
38
|
+
"description": "description of gist",
|
39
|
+
"public": true,
|
40
|
+
"user": {
|
41
|
+
"login": "octocat",
|
42
|
+
"id": 1,
|
43
|
+
"avatar_url": "https://github.com/images/error/octocat_happy.gif",
|
44
|
+
"gravatar_id": "somehexcode",
|
45
|
+
"url": "https://api.github.com/users/octocat"
|
46
|
+
},
|
47
|
+
"files": {
|
48
|
+
"ring.erl": {
|
49
|
+
"size": 932,
|
50
|
+
"filename": "ring.erl",
|
51
|
+
"raw_url": "https://gist.github.com/raw/365370/8c4d2d43d178df44f4c03a7f2ac0ff512853564e/ring.erl",
|
52
|
+
"content": "contents of gist"
|
53
|
+
}
|
54
|
+
},
|
55
|
+
"comments": 0,
|
56
|
+
"html_url": "https://gist.github.com/2",
|
57
|
+
"git_pull_url": "git://gist.github.com/2.git",
|
58
|
+
"git_push_url": "git@gist.github.com:2.git",
|
59
|
+
"created_at": "2010-04-14T02:15:15Z"
|
60
|
+
}
|
61
|
+
]
|
@@ -0,0 +1,35 @@
|
|
1
|
+
HTTP/1.1 200 OK
|
2
|
+
Link: <https://api.github.com/resource?page=2>; rel="next",
|
3
|
+
<https://api.github.com/resource?page=5>; rel="last"
|
4
|
+
X-RateLimit-Limit: 5000
|
5
|
+
X-RateLimit-Remaining: 4999
|
6
|
+
Content-type: application/json; charset=utf-8
|
7
|
+
|
8
|
+
[
|
9
|
+
{
|
10
|
+
"url": "https://api.github.com/gists/3",
|
11
|
+
"id": "3",
|
12
|
+
"description": "description of gist",
|
13
|
+
"public": false,
|
14
|
+
"user": {
|
15
|
+
"login": "octocat",
|
16
|
+
"id": 1,
|
17
|
+
"avatar_url": "https://github.com/images/error/octocat_happy.gif",
|
18
|
+
"gravatar_id": "somehexcode",
|
19
|
+
"url": "https://api.github.com/users/octocat"
|
20
|
+
},
|
21
|
+
"files": {
|
22
|
+
"ring.erl": {
|
23
|
+
"size": 932,
|
24
|
+
"filename": "ring.erl",
|
25
|
+
"raw_url": "https://gist.github.com/raw/365370/8c4d2d43d178df44f4c03a7f2ac0ff512853564e/ring.erl",
|
26
|
+
"content": "contents of gist"
|
27
|
+
}
|
28
|
+
},
|
29
|
+
"comments": 0,
|
30
|
+
"html_url": "https://gist.github.com/3",
|
31
|
+
"git_pull_url": "git://gist.github.com/3.git",
|
32
|
+
"git_push_url": "git@gist.github.com:3.git",
|
33
|
+
"created_at": "2010-04-14T02:15:15Z"
|
34
|
+
}
|
35
|
+
]
|
@@ -0,0 +1,16 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe ActiveGist::Files do
|
4
|
+
describe "with no files" do
|
5
|
+
it "should produce empty json" do
|
6
|
+
subject.as_json.should == {}.as_json
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
describe "with 1 file" do
|
11
|
+
before { subject['file1.txt'] = { :content => 'data' } }
|
12
|
+
it "should produce json with a file" do
|
13
|
+
subject.as_json.should == { 'file1.txt' => { :content => 'data' } }.as_json
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,308 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'test/unit'
|
3
|
+
|
4
|
+
describe ActiveGist do
|
5
|
+
let(:valid_attributes) do { :files => { "file1.txt" => { :content => 'String file contents' } } } end
|
6
|
+
|
7
|
+
def expect_request(method, path, data = nil, headers = { :accept => 'application/json' }, return_val = {:id=>1})
|
8
|
+
RestClient::Request.should_receive(:execute) do |options|
|
9
|
+
expectation = [method, File.join("https://api.github.com", path)]
|
10
|
+
actual = [options[:method], options[:url]]
|
11
|
+
case data
|
12
|
+
when NilClass then expectation << nil; actual << options[:payload]
|
13
|
+
when String then expectation << data; actual << options[:payload]
|
14
|
+
when Hash then expectation << JSON.parse(data.to_json); actual << JSON.parse(options[:payload])
|
15
|
+
else raise "Don't know how to handle data format: #{data.inspect}"
|
16
|
+
end
|
17
|
+
options[:headers].each { |k,v| headers[k] = v unless headers.key?(k) }
|
18
|
+
expectation << headers
|
19
|
+
actual << options[:headers]
|
20
|
+
|
21
|
+
actual.should == expectation
|
22
|
+
return_val.to_json
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
it "should not be 'equal' to another object with same id" do
|
27
|
+
obj = Object.new
|
28
|
+
def obj.id; '1'; end
|
29
|
+
ActiveGist.new(:id => '1').should_not == obj
|
30
|
+
end
|
31
|
+
|
32
|
+
describe "a new gist" do
|
33
|
+
it "assign a file and validate" do
|
34
|
+
a = ActiveGist.new
|
35
|
+
a.files['file1.txt'] = { :content => "this is test content" }
|
36
|
+
a.should be_valid
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
describe "an existing gist" do
|
41
|
+
describe "that is starred" do
|
42
|
+
subject { ActiveGist.find(1) }
|
43
|
+
|
44
|
+
it "check if it is starred" do
|
45
|
+
subject.should be_starred
|
46
|
+
end
|
47
|
+
|
48
|
+
it "check valid request" do
|
49
|
+
subject
|
50
|
+
expect_request(:get, "/gists/1/star")
|
51
|
+
subject.starred?
|
52
|
+
end
|
53
|
+
|
54
|
+
describe "unstarring it" do
|
55
|
+
it { subject.unstar!; should_not be_starred }
|
56
|
+
it "check valid request" do
|
57
|
+
subject
|
58
|
+
expect_request :delete, "gists/1/star"
|
59
|
+
subject.unstar!
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
describe "that is not starred" do
|
65
|
+
subject { ActiveGist.find(2) }
|
66
|
+
|
67
|
+
it "check if it is not starred" do
|
68
|
+
subject.should_not be_starred
|
69
|
+
end
|
70
|
+
|
71
|
+
it "check valid request" do
|
72
|
+
subject
|
73
|
+
expect_request :get, "/gists/2/star"
|
74
|
+
subject.starred?
|
75
|
+
end
|
76
|
+
|
77
|
+
describe "starring it" do
|
78
|
+
it { subject.star!; should be_starred }
|
79
|
+
it "check valid request" do
|
80
|
+
subject
|
81
|
+
expect_request :put, "/gists/2/star", ""
|
82
|
+
subject.star!
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
describe "destroying it" do
|
88
|
+
subject { ActiveGist.find 1 }
|
89
|
+
|
90
|
+
it "should destroy properly" do
|
91
|
+
subject.destroy
|
92
|
+
subject.should_not be_persisted
|
93
|
+
subject.should_not be_new_record
|
94
|
+
subject.should be_destroyed
|
95
|
+
end
|
96
|
+
|
97
|
+
it "should send correct request" do
|
98
|
+
subject
|
99
|
+
expect_request :delete, "gists/1"
|
100
|
+
subject.destroy
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
describe "forking it" do
|
105
|
+
subject { ActiveGist.find 1 }
|
106
|
+
|
107
|
+
it "should return the forked gist" do
|
108
|
+
subject.fork.should_not == subject
|
109
|
+
end
|
110
|
+
|
111
|
+
it "should send the correct request" do
|
112
|
+
subject
|
113
|
+
expect_request :post, "/gists/1/fork", ""
|
114
|
+
subject.fork
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
describe "validation" do
|
120
|
+
before { subject.valid? }
|
121
|
+
|
122
|
+
it "should not validate presence of description" do
|
123
|
+
subject.errors[:description].should_not include("can't be blank")
|
124
|
+
end
|
125
|
+
|
126
|
+
it "should not validate presence of public" do
|
127
|
+
# github requires this but we're just going to default it to false
|
128
|
+
subject.errors[:public].should_not include("can't be blank")
|
129
|
+
end
|
130
|
+
|
131
|
+
it "should validate presence of files" do
|
132
|
+
subject.errors[:files].should include("can't be blank")
|
133
|
+
end
|
134
|
+
end
|
135
|
+
|
136
|
+
describe "creating a valid gist with arrays and hashes" do
|
137
|
+
subject { ActiveGist.create!(valid_attributes) }
|
138
|
+
|
139
|
+
it "should return the new gist" do
|
140
|
+
subject.id.should == '1'
|
141
|
+
subject.url.should == 'https://api.github.com/gists/1'
|
142
|
+
subject.should be_public # this would default to false but our fake response returns true
|
143
|
+
end
|
144
|
+
|
145
|
+
it "should be persisted" do
|
146
|
+
subject.should be_persisted
|
147
|
+
end
|
148
|
+
|
149
|
+
it "should send proper request" do
|
150
|
+
expect_request :post, "/gists", valid_attributes.merge(:description => nil, :public => false)
|
151
|
+
subject
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
describe 'changing just files' do
|
156
|
+
subject { ActiveGist.find(1) }
|
157
|
+
before { subject.files['file1.txt'][:content] = 'updated' }
|
158
|
+
it { should_not be_persisted }
|
159
|
+
end
|
160
|
+
|
161
|
+
describe "changing an existing gist" do
|
162
|
+
subject { ActiveGist.find(1) }
|
163
|
+
before do
|
164
|
+
subject.description = "updated description"
|
165
|
+
subject.files['old_name.txt'][:filename] = 'new_name.txt'
|
166
|
+
subject.files['deleted.txt'] = nil
|
167
|
+
subject.files['file1.txt'][:content] = "updated file contents"
|
168
|
+
end
|
169
|
+
|
170
|
+
it { should_not be_persisted }
|
171
|
+
|
172
|
+
it "should send proper request to save" do
|
173
|
+
expect_request :patch, "/gists/1", {
|
174
|
+
:description => "updated description",
|
175
|
+
:files => subject.files
|
176
|
+
}
|
177
|
+
subject.save!
|
178
|
+
end
|
179
|
+
|
180
|
+
describe "saving" do
|
181
|
+
before { subject.save! }
|
182
|
+
|
183
|
+
it "should store the new description" do
|
184
|
+
subject.description.should == 'returned updated description'
|
185
|
+
end
|
186
|
+
|
187
|
+
it "should remove the renamed file's old filename" do
|
188
|
+
subject.files.should_not have_key('old_name.txt')
|
189
|
+
end
|
190
|
+
|
191
|
+
it "should add the renamed file's new filename" do
|
192
|
+
subject.files.should have_key('new_name.txt')
|
193
|
+
end
|
194
|
+
|
195
|
+
it "should remove the deleted file" do
|
196
|
+
subject.files.should_not have_key('deleted.txt')
|
197
|
+
end
|
198
|
+
|
199
|
+
it "should update the modified file contents" do
|
200
|
+
subject.files['file1.txt'][:content].should == 'returned updated file contents'
|
201
|
+
end
|
202
|
+
end
|
203
|
+
end
|
204
|
+
|
205
|
+
describe "saving a valid gist" do
|
206
|
+
subject { ActiveGist.new(valid_attributes) }
|
207
|
+
before { subject.save }
|
208
|
+
|
209
|
+
it '#save should return true' do
|
210
|
+
subject.save.should be_true
|
211
|
+
end
|
212
|
+
|
213
|
+
it "should be persisted" do
|
214
|
+
subject.should be_persisted
|
215
|
+
end
|
216
|
+
end
|
217
|
+
|
218
|
+
describe "creating an invalid gist" do
|
219
|
+
it "::create! should raise an error" do
|
220
|
+
proc { ActiveGist.create! }.should raise_error
|
221
|
+
end
|
222
|
+
|
223
|
+
it "::create should return a record that is not persisted" do
|
224
|
+
ActiveGist.create.should_not be_persisted
|
225
|
+
end
|
226
|
+
end
|
227
|
+
|
228
|
+
describe "saving an invalid gist" do
|
229
|
+
it '#save! should raise an error' do
|
230
|
+
proc { ActiveGist.new.save! }.should raise_error
|
231
|
+
end
|
232
|
+
|
233
|
+
it '#save should return false' do
|
234
|
+
ActiveGist.new.save.should be_false
|
235
|
+
end
|
236
|
+
end
|
237
|
+
|
238
|
+
it "should have a count of all gists" do
|
239
|
+
ActiveGist.count.should == 3
|
240
|
+
end
|
241
|
+
|
242
|
+
it "should have a count of public gists" do
|
243
|
+
ActiveGist.count(:public).should == 2
|
244
|
+
end
|
245
|
+
|
246
|
+
it "should have a count of starred gists" do
|
247
|
+
ActiveGist.count(:starred).should == 1
|
248
|
+
end
|
249
|
+
|
250
|
+
it "should return the last gist" do
|
251
|
+
ActiveGist.last.id.should == '3'
|
252
|
+
end
|
253
|
+
|
254
|
+
it "should return the first gist" do
|
255
|
+
ActiveGist.first.id.should == '1'
|
256
|
+
end
|
257
|
+
|
258
|
+
it "should find a gist by id" do
|
259
|
+
ActiveGist.find(2).should == ActiveGist.all[1]
|
260
|
+
|
261
|
+
# check request
|
262
|
+
expect_request(:get, "/gists/2")
|
263
|
+
ActiveGist.find(2)
|
264
|
+
end
|
265
|
+
|
266
|
+
describe "a gist returned by github" do
|
267
|
+
subject { ActiveGist.first }
|
268
|
+
it { should respond_to(:url) }
|
269
|
+
it { should respond_to(:id) }
|
270
|
+
it { should respond_to(:description) }
|
271
|
+
it { should respond_to(:public?) }
|
272
|
+
it { should respond_to(:user) }
|
273
|
+
it { should respond_to(:files) }
|
274
|
+
it { should respond_to(:comments) }
|
275
|
+
it { should respond_to(:html_url) }
|
276
|
+
it { should respond_to(:git_pull_url) }
|
277
|
+
it { should respond_to(:git_push_url) }
|
278
|
+
it { should respond_to(:created_at) }
|
279
|
+
it { should be_persisted }
|
280
|
+
end
|
281
|
+
|
282
|
+
describe "fetching all gists" do
|
283
|
+
subject { ActiveGist.all }
|
284
|
+
|
285
|
+
it { should have(3).gists }
|
286
|
+
|
287
|
+
it "should request the gist properly" do
|
288
|
+
expect_request(:get, "/gists", nil, {:accept => 'application/json'}, [])
|
289
|
+
subject
|
290
|
+
end
|
291
|
+
end
|
292
|
+
|
293
|
+
describe "active model lint tests" do
|
294
|
+
include Test::Unit::Assertions
|
295
|
+
include ActiveModel::Lint::Tests
|
296
|
+
|
297
|
+
def model
|
298
|
+
subject
|
299
|
+
end
|
300
|
+
|
301
|
+
# to_s is to support ruby-1.9
|
302
|
+
ActiveModel::Lint::Tests.public_instance_methods.map{|m| m.to_s}.grep(/^test/).each do |m|
|
303
|
+
example m.gsub('_',' ') do
|
304
|
+
send m
|
305
|
+
end
|
306
|
+
end
|
307
|
+
end
|
308
|
+
end
|