atnd4r 0.0.6
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 +4 -0
- data/.gitignore +5 -0
- data/ChangeLog +9 -0
- data/README.rdoc +57 -0
- data/Rakefile +50 -0
- data/VERSION +1 -0
- data/atnd4r.gemspec +46 -0
- data/lib/atnd4r.rb +257 -0
- data/spec/atnd4r_spec.rb +331 -0
- data/spec/spec_helper.rb +22 -0
- metadata +69 -0
data/.document
ADDED
data/ChangeLog
ADDED
data/README.rdoc
ADDED
@@ -0,0 +1,57 @@
|
|
1
|
+
= atnd4r
|
2
|
+
|
3
|
+
ATND WebAPI wrapper for Ruby.
|
4
|
+
* Project Website - http://github.com/sugamasao/atnd4r/tree/master
|
5
|
+
|
6
|
+
== Developers
|
7
|
+
* {sugamasao}[http://sugamasao.dip.jp/] <sugamasao@gmail.com>
|
8
|
+
|
9
|
+
== Features/Problems
|
10
|
+
|
11
|
+
* Ruby 1.8.7 での動作確認を行っています
|
12
|
+
|
13
|
+
== Synopsis
|
14
|
+
|
15
|
+
使用例
|
16
|
+
|
17
|
+
require 'rubygems'
|
18
|
+
require 'atnd4r'
|
19
|
+
|
20
|
+
=== 入力データについて
|
21
|
+
|
22
|
+
検索用メソッドとして、下記の二つを用意しています。
|
23
|
+
|
24
|
+
* Atnd4r.get_event_list
|
25
|
+
* Atnd4r.get_user_list
|
26
|
+
|
27
|
+
引数は、検索条件を Hash で渡せば良いです。
|
28
|
+
例えば、 event_id が 1 の情報を調べる為には、
|
29
|
+
|
30
|
+
irb(main):002:0> Atnd4r.get_event_list({:event_id => 1})
|
31
|
+
|
32
|
+
のような形式になります。
|
33
|
+
一つの KEY に対して、複数の値を渡す場合は配列に入れて渡してください。
|
34
|
+
|
35
|
+
irb(main):003:0> Atnd4r.get_event_list({:event_id => [1,2]})
|
36
|
+
|
37
|
+
詳細な検索の仕様は{ATND API の公式ページ}[http://api.atnd.org] をご覧ください。
|
38
|
+
なお、ATND API における、format パラメータのみ、XML固定となっていますので、format パラメータを Atnd4R へ渡しても無視されます。
|
39
|
+
|
40
|
+
=== 出力データについて
|
41
|
+
|
42
|
+
受け取ったデータは以下の形式のAtnd4r::AtndAPIというオブジェクトでラッピングされて返却されます。
|
43
|
+
|
44
|
+
基本的には XML データを Ruby 用のオブジェクトに変換したものですので、XMLのプロパティなどはほぼそのままです(ただし、ハイフンの名前のものはアンダースコアにしています)。
|
45
|
+
|
46
|
+
また、各プロパティは XML の属性にしたがったオブジェクトに変換されています。例えば、Integer とあれば Fixnum 型のように。
|
47
|
+
|
48
|
+
==== Atnd4Rの戻り値のオブジェクトについて
|
49
|
+
|
50
|
+
XMLに記載されている属性に従い、 String や Fixnum のようなRubyの型になっています。
|
51
|
+
詳細は{Atnd4R解説エントリ}[http://d.hatena.ne.jp/seiunsky/20090730/1248972545] をご覧ください。
|
52
|
+
|
53
|
+
== Copyright
|
54
|
+
|
55
|
+
Author:: sugamasao <sugamasao@gmail.com>
|
56
|
+
License:: Ruby's
|
57
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,50 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
|
4
|
+
begin
|
5
|
+
require 'jeweler'
|
6
|
+
Jeweler::Tasks.new do |gem|
|
7
|
+
gem.name = "atnd4r"
|
8
|
+
gem.summary = %Q{ATND の API を Ruby から使用するたのラッパークラスです}
|
9
|
+
gem.email = "sugamasao@gmail.com"
|
10
|
+
gem.homepage = "http://github.com/sugamasao/atnd4r"
|
11
|
+
gem.authors = ["sugamasao"]
|
12
|
+
# gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
|
13
|
+
end
|
14
|
+
|
15
|
+
rescue LoadError
|
16
|
+
puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
|
17
|
+
end
|
18
|
+
|
19
|
+
require 'spec/rake/spectask'
|
20
|
+
Spec::Rake::SpecTask.new(:spec) do |spec|
|
21
|
+
spec.libs << 'lib' << 'spec'
|
22
|
+
spec.spec_files = FileList['spec/**/*_spec.rb']
|
23
|
+
end
|
24
|
+
|
25
|
+
Spec::Rake::SpecTask.new(:rcov) do |spec|
|
26
|
+
spec.libs << 'lib' << 'spec'
|
27
|
+
spec.pattern = 'spec/**/*_spec.rb'
|
28
|
+
spec.rcov = true
|
29
|
+
end
|
30
|
+
|
31
|
+
|
32
|
+
task :default => :spec
|
33
|
+
|
34
|
+
require 'rake/rdoctask'
|
35
|
+
Rake::RDocTask.new do |rdoc|
|
36
|
+
if File.exist?('VERSION.yml')
|
37
|
+
config = YAML.load(File.read('VERSION.yml'))
|
38
|
+
version = "#{config[:major]}.#{config[:minor]}.#{config[:patch]}"
|
39
|
+
else
|
40
|
+
version = ""
|
41
|
+
end
|
42
|
+
|
43
|
+
rdoc.rdoc_dir = 'rdoc'
|
44
|
+
rdoc.title = "atnd4r #{version}"
|
45
|
+
rdoc.rdoc_files.include('README*')
|
46
|
+
rdoc.rdoc_files.include('Changelog')
|
47
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
48
|
+
rdoc.options = ["--charset", "utf-8", "--line-numbers"]
|
49
|
+
end
|
50
|
+
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.0.6
|
data/atnd4r.gemspec
ADDED
@@ -0,0 +1,46 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
Gem::Specification.new do |s|
|
4
|
+
s.name = %q{atnd4r}
|
5
|
+
s.version = "0.0.6"
|
6
|
+
|
7
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
8
|
+
s.authors = ["sugamasao"]
|
9
|
+
s.date = %q{2009-07-28}
|
10
|
+
s.email = %q{sugamasao@gmail.com}
|
11
|
+
s.extra_rdoc_files = [
|
12
|
+
"ChangeLog",
|
13
|
+
"README.rdoc"
|
14
|
+
]
|
15
|
+
s.files = [
|
16
|
+
".document",
|
17
|
+
".gitignore",
|
18
|
+
"ChangeLog",
|
19
|
+
"README.rdoc",
|
20
|
+
"Rakefile",
|
21
|
+
"VERSION",
|
22
|
+
"atnd4r.gemspec",
|
23
|
+
"lib/atnd4r.rb",
|
24
|
+
"spec/atnd4r_spec.rb",
|
25
|
+
"spec/spec_helper.rb"
|
26
|
+
]
|
27
|
+
s.homepage = %q{http://github.com/sugamasao/atnd4r}
|
28
|
+
s.rdoc_options = ["--charset=UTF-8"]
|
29
|
+
s.require_paths = ["lib"]
|
30
|
+
s.rubygems_version = %q{1.3.4}
|
31
|
+
s.summary = %q{ATND の API を Ruby から使用するたのラッパークラスです}
|
32
|
+
s.test_files = [
|
33
|
+
"spec/atnd4r_spec.rb",
|
34
|
+
"spec/spec_helper.rb"
|
35
|
+
]
|
36
|
+
|
37
|
+
if s.respond_to? :specification_version then
|
38
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
39
|
+
s.specification_version = 3
|
40
|
+
|
41
|
+
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
42
|
+
else
|
43
|
+
end
|
44
|
+
else
|
45
|
+
end
|
46
|
+
end
|
data/lib/atnd4r.rb
ADDED
@@ -0,0 +1,257 @@
|
|
1
|
+
require 'net/http'
|
2
|
+
require 'rexml/document'
|
3
|
+
|
4
|
+
module Atnd4r
|
5
|
+
@atnd_api_url = 'api.atnd.org'
|
6
|
+
@atnd_api_port = 80
|
7
|
+
@atnd_api_events = '/events/'
|
8
|
+
@atnd_api_users = '/events/users/'
|
9
|
+
|
10
|
+
# ATND へのリクエストで 400 番台や 500 番台の応答コードが返された時に出力されます
|
11
|
+
class ATNDHTTPError < StandardError; end
|
12
|
+
|
13
|
+
# ATND へのリクエスト時のパラメータが不正(もしくは何も無かった場合)
|
14
|
+
class ATNDParameterError < StandardError; end;
|
15
|
+
|
16
|
+
########################
|
17
|
+
# アクセッサメソッド
|
18
|
+
########################
|
19
|
+
|
20
|
+
#ATND の HOST名(http:// は不要)を設定します。
|
21
|
+
#万が一 URL に変更がある場合は独自に設定してください
|
22
|
+
def self.atnd_api_url=(val = "")
|
23
|
+
@atnd_api_url = val
|
24
|
+
end
|
25
|
+
|
26
|
+
#ATND の ポート番号を設定します。
|
27
|
+
#万が一 URL に変更がある場合は独自に設定してください
|
28
|
+
def self.atnd_api_port=(val = 0)
|
29
|
+
@atnd_api_port = val.to_i
|
30
|
+
end
|
31
|
+
|
32
|
+
#ATND の イベント情報 API のパスを設定します。(末尾は '/' である必要があります)
|
33
|
+
#万が一 URL に変更がある場合は独自に設定してください
|
34
|
+
def self.atnd_api_events=(val = 0)
|
35
|
+
@atnd_api_events = val.to_i
|
36
|
+
end
|
37
|
+
|
38
|
+
#ATND の 出席情報 API のパスを設定します。(末尾は '/' である必要があります)
|
39
|
+
#万が一 URL に変更がある場合は独自に設定してください
|
40
|
+
def self.atnd_api_users=(val = "")
|
41
|
+
@atnd_api_users = val
|
42
|
+
end
|
43
|
+
|
44
|
+
###################
|
45
|
+
# public method
|
46
|
+
##################
|
47
|
+
|
48
|
+
#== イベントサーチAPI
|
49
|
+
#イベントサーチAPI を実行します
|
50
|
+
#=== 引数
|
51
|
+
#_param_:: Hashのオブジェクト。一つの検索パラメータに対して、複数の値を渡す場合は、value部分を配列にしてください。
|
52
|
+
#例えば、event_id で検索する場合は、下記のようなパラメータを渡してください
|
53
|
+
# {:event_id => 1}
|
54
|
+
#event_id を複数渡したい場合は配列にします。
|
55
|
+
# {:event_id => [1,2]}
|
56
|
+
#=== 戻り値
|
57
|
+
#Atnd4r::AtndAPI:: Atnd4r::AtndAPIオブジェクト
|
58
|
+
#=== 例外
|
59
|
+
#Atnd4r::ATNDHTTPError:: API ヘアクセスした際に、400系や500系の応答コードがかえってきた場合に発生します
|
60
|
+
#Atnd4r::ATNDParameterError:: API 実行結果に Error メッセージが入っていた場合に発生します
|
61
|
+
def self.get_event_list(param = {})
|
62
|
+
xml = get_xml(@atnd_api_events, make_query(param))
|
63
|
+
event = parse_common_xml(xml)
|
64
|
+
event.events = parse_events_xml(xml)
|
65
|
+
|
66
|
+
return event
|
67
|
+
end
|
68
|
+
|
69
|
+
#== 出欠確認API
|
70
|
+
#出欠確認API を実行します
|
71
|
+
#=== 引数
|
72
|
+
#_param_:: Hashのオブジェクト。一つの検索パラメータに対して、複数の値を渡す場合は、value部分を配列にしてください。
|
73
|
+
#例えば、user_id で検索する場合は、下記のようなパラメータを渡してください
|
74
|
+
# {:user_id => 1}
|
75
|
+
#user_id を複数渡したい場合は配列にします。
|
76
|
+
# {:user_id => [1,2]}
|
77
|
+
#=== 戻り値
|
78
|
+
#Atnd4r::AtndAPI:: Atnd4r::AtndAPIオブジェクト
|
79
|
+
#=== 例外
|
80
|
+
#Atnd4r::ATNDHTTPError:: API ヘアクセスした際に、400系や500系の応答コードがかえってきた場合に発生します
|
81
|
+
#Atnd4r::ATNDParameterError:: API 実行結果に Error メッセージが入っていた場合に発生します
|
82
|
+
def self.get_user_list(param = {})
|
83
|
+
xml = get_xml(@atnd_api_users, make_query(param))
|
84
|
+
event = parse_common_xml(xml)
|
85
|
+
event.events = parse_users_xml(xml)
|
86
|
+
|
87
|
+
return event
|
88
|
+
end
|
89
|
+
|
90
|
+
###################
|
91
|
+
# private method
|
92
|
+
##################
|
93
|
+
|
94
|
+
# パラメータから QueryString を作成する。一つの Key に複数の値がある場合、カンマ区切りにする
|
95
|
+
def self.make_query(param = {})
|
96
|
+
query = []
|
97
|
+
param.each do |key, val|
|
98
|
+
if val.nil?
|
99
|
+
val = ""
|
100
|
+
end
|
101
|
+
|
102
|
+
# format のオプションは無視する(XML固定のため)
|
103
|
+
if key.to_s == 'format'
|
104
|
+
next
|
105
|
+
end
|
106
|
+
# key がシンボルの場合に備えて to_s しておく
|
107
|
+
query << key.to_s.strip + "=" + Array(val).map {|value| value.to_s.strip}.join(",")
|
108
|
+
end
|
109
|
+
|
110
|
+
# format を XML にする
|
111
|
+
query << 'format=xml'
|
112
|
+
|
113
|
+
return query.join("&")
|
114
|
+
end
|
115
|
+
|
116
|
+
# 共通の XMLデータのパース
|
117
|
+
def self.parse_common_xml(xml)
|
118
|
+
common = AtndAPI.new(xml.elements['hash'])
|
119
|
+
end
|
120
|
+
|
121
|
+
# AtndEvent の配列を返却する
|
122
|
+
def self.parse_events_xml(xml)
|
123
|
+
events_list = [] # AtndEvent の配列
|
124
|
+
|
125
|
+
# /hash/error/message があったら Error とする
|
126
|
+
raise ATNDParameterError.new("ATND Request Parameter Error : " + xml.elements['/hash/error/message'].text) if xml.elements['/hash/error/message']
|
127
|
+
|
128
|
+
xml.elements.each('/hash/events/event') do |event|
|
129
|
+
events_list << AtndEvent.new(event)
|
130
|
+
end
|
131
|
+
|
132
|
+
return events_list
|
133
|
+
end
|
134
|
+
|
135
|
+
|
136
|
+
# AtndEvent の配列を返却する
|
137
|
+
def self.parse_users_xml(xml)
|
138
|
+
users_list = [] # AtndEvent の配列
|
139
|
+
|
140
|
+
# /hash/error/message があったら Error とする
|
141
|
+
raise ATNDParameterError.new("ATND Request Parameter Error : " + xml.elements['/hash/error/message'].text) if xml.elements['/hash/error/message']
|
142
|
+
|
143
|
+
xml.elements.each('/hash/events/event') do |event|
|
144
|
+
users_list << AtndEvent.new(event)
|
145
|
+
end
|
146
|
+
|
147
|
+
return users_list
|
148
|
+
end
|
149
|
+
|
150
|
+
# ATND API を実行して、XML を取得する
|
151
|
+
def self.get_xml(api_url, query)
|
152
|
+
doc = nil
|
153
|
+
Net::HTTP.version_1_2
|
154
|
+
Net::HTTP.start(@atnd_api_url, @atnd_api_port) do |http|
|
155
|
+
response = http.get(api_url + '?' + query)
|
156
|
+
if response.code =~ /[45]\d\d/
|
157
|
+
raise ATNDHTTPError.new("ATND API Server Error : #{response['status']}")
|
158
|
+
end
|
159
|
+
doc = REXML::Document.new response.body
|
160
|
+
end
|
161
|
+
return doc
|
162
|
+
end
|
163
|
+
|
164
|
+
################
|
165
|
+
# private setting
|
166
|
+
###############
|
167
|
+
private_class_method :get_xml, :parse_common_xml, :parse_events_xml, :parse_users_xml, :make_query
|
168
|
+
|
169
|
+
class AtndAPI
|
170
|
+
def initialize(xml)
|
171
|
+
@results_returned = AtndAPIUtil::to_ruby_type xml.elements['results-returned']
|
172
|
+
@results_available = AtndAPIUtil::to_ruby_type xml.elements['results-available']
|
173
|
+
@results_start = AtndAPIUtil::to_ruby_type xml.elements['results-start']
|
174
|
+
@events = nil
|
175
|
+
end
|
176
|
+
|
177
|
+
attr_reader :results_returned, :results_available, :results_start
|
178
|
+
attr_accessor :events
|
179
|
+
end
|
180
|
+
|
181
|
+
class AtndEvent
|
182
|
+
# XML オブジェクト
|
183
|
+
def initialize(event)
|
184
|
+
# 共通データ
|
185
|
+
@accepted = AtndAPIUtil::to_ruby_type event.elements['accepted']
|
186
|
+
@event_id = AtndAPIUtil::to_ruby_type event.elements['event-id']
|
187
|
+
@updated_at = AtndAPIUtil::to_ruby_type event.elements['updated-at']
|
188
|
+
@title = AtndAPIUtil::to_ruby_type event.elements['title']
|
189
|
+
@waiting = AtndAPIUtil::to_ruby_type event.elements['waiting']
|
190
|
+
@event_url = AtndAPIUtil::to_ruby_type event.elements['event-url']
|
191
|
+
@limit = AtndAPIUtil::to_ruby_type event.elements['limit']
|
192
|
+
|
193
|
+
# 出席情報の場合
|
194
|
+
@users = []
|
195
|
+
event.elements.each('users/user') do |user|
|
196
|
+
@users << AtndUser.new(user)
|
197
|
+
end
|
198
|
+
|
199
|
+
# イベント情報の場合
|
200
|
+
@place = AtndAPIUtil::to_ruby_type event.elements['place']
|
201
|
+
@lon = AtndAPIUtil::to_ruby_type event.elements['lon']
|
202
|
+
@ended_at = AtndAPIUtil::to_ruby_type event.elements['ended-at']
|
203
|
+
@url = AtndAPIUtil::to_ruby_type event.elements['url']
|
204
|
+
@owner_nickname = AtndAPIUtil::to_ruby_type event.elements['owner-nickname']
|
205
|
+
@catch = AtndAPIUtil::to_ruby_type event.elements['catch']
|
206
|
+
@description = AtndAPIUtil::to_ruby_type event.elements['description']
|
207
|
+
@owner_id = AtndAPIUtil::to_ruby_type event.elements['owner-id']
|
208
|
+
@lat = AtndAPIUtil::to_ruby_type event.elements['lat']
|
209
|
+
@address = AtndAPIUtil::to_ruby_type event.elements['address']
|
210
|
+
@started_at = AtndAPIUtil::to_ruby_type event.elements['started-at']
|
211
|
+
end
|
212
|
+
|
213
|
+
attr_reader :accepted, :event_id, :updated_at, :title, :waiting, :event_url, :limit
|
214
|
+
attr_reader :users
|
215
|
+
attr_reader :place, :lon, :ended_at, :url, :owner_nickname, :catch, :description, :owner_id, :lat, :address, :started_at
|
216
|
+
end
|
217
|
+
|
218
|
+
class AtndUser
|
219
|
+
def initialize(user)
|
220
|
+
@status = AtndAPIUtil::to_ruby_type user.elements['status']
|
221
|
+
@nickname = AtndAPIUtil::to_ruby_type user.elements['nickname']
|
222
|
+
@user_id = AtndAPIUtil::to_ruby_type user.elements['user-id']
|
223
|
+
end
|
224
|
+
attr_reader :status, :nickname, :user_id
|
225
|
+
end
|
226
|
+
|
227
|
+
|
228
|
+
require 'time'
|
229
|
+
module AtndAPIUtil
|
230
|
+
# REXML::Element
|
231
|
+
def self.to_ruby_type(element)
|
232
|
+
|
233
|
+
# 子要素が取得できない場合は nil を返す
|
234
|
+
return nil if element.nil?
|
235
|
+
|
236
|
+
# 要素が無い場合、属性に nil が付くので、値が true であれば nil を返す
|
237
|
+
if element.attributes['nil']
|
238
|
+
return nil if element.attributes['nil'] == 'true'
|
239
|
+
end
|
240
|
+
|
241
|
+
val = nil
|
242
|
+
element_type = element.attributes['type']
|
243
|
+
element_type = element_type.downcase if element_type
|
244
|
+
case element_type
|
245
|
+
when 'integer'
|
246
|
+
val = element.text.to_i
|
247
|
+
when 'decimal'
|
248
|
+
val = element.text.to_f
|
249
|
+
when 'datetime'
|
250
|
+
val = Time.parse(element.text)
|
251
|
+
else
|
252
|
+
val = element.text
|
253
|
+
end
|
254
|
+
return val
|
255
|
+
end
|
256
|
+
end
|
257
|
+
end
|
data/spec/atnd4r_spec.rb
ADDED
@@ -0,0 +1,331 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) + '/spec_helper')
|
2
|
+
require 'rexml/document'
|
3
|
+
require 'net/http'
|
4
|
+
require 'time'
|
5
|
+
require 'pp'
|
6
|
+
|
7
|
+
|
8
|
+
module Atnd4r
|
9
|
+
# private methods to public
|
10
|
+
public_class_method :get_xml, :parse_users_xml, :parse_events_xml, :parse_common_xml, :make_query
|
11
|
+
end
|
12
|
+
|
13
|
+
describe Atnd4r, "get_event_list で値を取得した場合" do
|
14
|
+
xml_string =<<-EOF
|
15
|
+
<hash>
|
16
|
+
<results-returned type="integer">9999</results-returned>
|
17
|
+
<results-available type="integer">1</results-available>
|
18
|
+
<events type="array">
|
19
|
+
<event>
|
20
|
+
<accepted type="integer">1</accepted>
|
21
|
+
<event-id type="integer">1</event-id>
|
22
|
+
<updated-at type="datetime">2009-01-01T00:00:00+09:00</updated-at>
|
23
|
+
<title>hoge event</title>
|
24
|
+
<waiting type="integer">0</waiting>
|
25
|
+
<event-url>hoge.com</event-url>
|
26
|
+
<users type="array">
|
27
|
+
<user>
|
28
|
+
<status type="integer">1</status>
|
29
|
+
<nickname>name</nickname>
|
30
|
+
<user-id type="integer">1</user-id>
|
31
|
+
</user>
|
32
|
+
</users>
|
33
|
+
<limit type="integer">1</limit>
|
34
|
+
</event>
|
35
|
+
</events>
|
36
|
+
<results-start type="integer">1</results-start>
|
37
|
+
</hash>
|
38
|
+
EOF
|
39
|
+
before(:each) do
|
40
|
+
@http_mock = create_http_mock(xml_string, "200", "200 Ok")
|
41
|
+
Net::HTTP.stub!(:start).and_yield(@http_mock)
|
42
|
+
end
|
43
|
+
|
44
|
+
it "AtndAPI オブジェクトが取得されること" do
|
45
|
+
event = Atnd4r::get_event_list({:event_id => 1})
|
46
|
+
event.class.should == Atnd4r::AtndAPI
|
47
|
+
event.results_returned.should == 9999
|
48
|
+
event.events[0].title.should == "hoge event"
|
49
|
+
event.events[0].users[0].nickname.should == "name"
|
50
|
+
end
|
51
|
+
|
52
|
+
after do
|
53
|
+
@http_mock = nil
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
describe Atnd4r, "get_user_list で値を取得した場合" do
|
58
|
+
xml_string =<<-EOF
|
59
|
+
<hash>
|
60
|
+
<results-returned type="integer">9999</results-returned>
|
61
|
+
<results-available type="integer">1</results-available>
|
62
|
+
<events type="array">
|
63
|
+
<event>
|
64
|
+
<accepted type="integer">1</accepted>
|
65
|
+
<event-id type="integer">1</event-id>
|
66
|
+
<updated-at type="datetime">2009-01-01T00:00:00+09:00</updated-at>
|
67
|
+
<title>hoge event</title>
|
68
|
+
<waiting type="integer">0</waiting>
|
69
|
+
<event-url>hoge.com</event-url>
|
70
|
+
<users type="array">
|
71
|
+
<user>
|
72
|
+
<status type="integer">1</status>
|
73
|
+
<nickname>name</nickname>
|
74
|
+
<user-id type="integer">1</user-id>
|
75
|
+
</user>
|
76
|
+
</users>
|
77
|
+
<limit type="integer">1</limit>
|
78
|
+
</event>
|
79
|
+
</events>
|
80
|
+
<results-start type="integer">1</results-start>
|
81
|
+
</hash>
|
82
|
+
EOF
|
83
|
+
before(:each) do
|
84
|
+
@http_mock = create_http_mock(xml_string, "200", "200 Ok")
|
85
|
+
Net::HTTP.stub!(:start).and_yield(@http_mock)
|
86
|
+
end
|
87
|
+
|
88
|
+
it "AtndAPI オブジェクトが取得されること" do
|
89
|
+
event = Atnd4r::get_user_list({:user_id => 1})
|
90
|
+
event.class.should == Atnd4r::AtndAPI
|
91
|
+
event.results_returned.should == 9999
|
92
|
+
event.events[0].title.should == "hoge event"
|
93
|
+
event.events[0].users[0].nickname.should == "name"
|
94
|
+
end
|
95
|
+
|
96
|
+
after do
|
97
|
+
@http_mock = nil
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
describe "Atnd4r::get_xml で、サーバーエラー(4xx)が返された)場合" do
|
102
|
+
before(:each) do
|
103
|
+
@http_mock = create_http_mock("body", "400", "400_error")
|
104
|
+
Net::HTTP.stub!(:start).and_yield(@http_mock)
|
105
|
+
end
|
106
|
+
|
107
|
+
it "は、400 ならATNDHTTPError を返す事" do
|
108
|
+
lambda {
|
109
|
+
Atnd4r.get_xml("api", "query")
|
110
|
+
}.should raise_error(Atnd4r::ATNDHTTPError, /400_error/)
|
111
|
+
end
|
112
|
+
|
113
|
+
after do
|
114
|
+
@http_mock = nil
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
describe "Atnd4r::get_xml で、サーバーエラー(4xx)が返された)場合" do
|
119
|
+
before(:each) do
|
120
|
+
@http_mock = create_http_mock("body", "500", "500_error")
|
121
|
+
Net::HTTP.stub!(:start).and_yield(@http_mock)
|
122
|
+
end
|
123
|
+
|
124
|
+
it "は、500 ならATNDHTTPError を返す事" do
|
125
|
+
lambda {
|
126
|
+
Atnd4r.get_xml("api", "query")
|
127
|
+
}.should raise_error(Atnd4r::ATNDHTTPError, /500_error/)
|
128
|
+
end
|
129
|
+
|
130
|
+
after do
|
131
|
+
@http_mock = nil
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
describe "Atnd4r::get_xml でXML が正しく取得できたとき" do
|
136
|
+
before(:each) do
|
137
|
+
xml_string = "<tag>hoge</tag>"
|
138
|
+
@http_mock = create_http_mock(xml_string, "200", "200 Ok")
|
139
|
+
Net::HTTP.stub!(:start).and_yield(@http_mock)
|
140
|
+
end
|
141
|
+
|
142
|
+
it "は、XMLオブジェクトの値として、 hoge を返す事" do
|
143
|
+
doc = Atnd4r.get_xml("api", "query")
|
144
|
+
doc.elements["tag"].text.should == "hoge"
|
145
|
+
end
|
146
|
+
|
147
|
+
after do
|
148
|
+
@http_mock = nil
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
|
153
|
+
describe "Atnd4r::make_query が、引数なしのパラメータを解析するとき" do
|
154
|
+
it "は、文字列を返す事" do
|
155
|
+
query = Atnd4r::make_query()
|
156
|
+
query.class.should == String
|
157
|
+
end
|
158
|
+
|
159
|
+
it "は、内容はformatパラメータ文字列になっていること" do
|
160
|
+
query = Atnd4r::make_query()
|
161
|
+
query.should == "format=xml"
|
162
|
+
end
|
163
|
+
end
|
164
|
+
|
165
|
+
describe "Atnd4r::make_query がひとつのkey&valueのパラメータを解析するとき" do
|
166
|
+
it "は、Keyがシンボルでも文字列を返す事" do
|
167
|
+
query = Atnd4r::make_query({:key => "value"})
|
168
|
+
query.should == "key=value&format=xml"
|
169
|
+
end
|
170
|
+
|
171
|
+
it "は、Keyが文字列でも文字列を返す事" do
|
172
|
+
query = Atnd4r::make_query({"key" => "value"})
|
173
|
+
query.should == "key=value&format=xml"
|
174
|
+
end
|
175
|
+
|
176
|
+
it "は、Keyやvalueにスペースが混じっている場合除去された文字列を返す事" do
|
177
|
+
query = Atnd4r::make_query({" key " => " value "})
|
178
|
+
query.should == "key=value&format=xml"
|
179
|
+
end
|
180
|
+
end
|
181
|
+
|
182
|
+
describe "Atnd4r::make_query がひとつのkey 対して複数valueのパラメータを解析するとき" do
|
183
|
+
it "は、値が複数の場合は、カンマ区切りになるよ" do
|
184
|
+
query = Atnd4r::make_query({"key" => ["value1", "value2"]})
|
185
|
+
query.should == "key=value1,value2&format=xml"
|
186
|
+
end
|
187
|
+
end
|
188
|
+
|
189
|
+
describe "Atnd4r::make_query がひとつのkey 対してvalueが nil のとき" do
|
190
|
+
it "は、値が空文字になるよ" do
|
191
|
+
query = Atnd4r::make_query({"key" => nil})
|
192
|
+
query.should == "key=&format=xml"
|
193
|
+
end
|
194
|
+
end
|
195
|
+
|
196
|
+
describe "Atnd4r::parse_users_xml XML がエラーメッセージだったとき" do
|
197
|
+
xml_string = "<hash><error><message>error!</message></error></hash>"
|
198
|
+
doc = REXML::Document.new xml_string
|
199
|
+
|
200
|
+
it "は、例外 ATNDParameterError が発生する" do
|
201
|
+
lambda {
|
202
|
+
Atnd4r.parse_users_xml(doc)
|
203
|
+
}.should raise_error(Atnd4r::ATNDParameterError, /error!/)
|
204
|
+
end
|
205
|
+
end
|
206
|
+
|
207
|
+
describe "Atnd4r::parse_common_xml が正常に処理したとき" do
|
208
|
+
xml_string =<<-EOF
|
209
|
+
<hash>
|
210
|
+
<results-returned type="integer">1</results-returned>
|
211
|
+
<results-available type="integer">2</results-available>
|
212
|
+
<results-start type="integer">3</results-start>
|
213
|
+
</hash>
|
214
|
+
EOF
|
215
|
+
doc = REXML::Document.new xml_string
|
216
|
+
|
217
|
+
events = Atnd4r::parse_common_xml(doc)
|
218
|
+
it "は、AtndAPIオブジェクトの内容として、result_xxx の値を持っている事" do
|
219
|
+
events.results_returned.should == 1
|
220
|
+
events.results_available.should == 2
|
221
|
+
events.results_start.should == 3
|
222
|
+
end
|
223
|
+
end
|
224
|
+
|
225
|
+
|
226
|
+
describe "Atnd4r::parse_users_xml が正常に処理したとき" do
|
227
|
+
xml_string =<<-EOF
|
228
|
+
<hash>
|
229
|
+
<results-returned type="integer">1</results-returned>
|
230
|
+
<results-available type="integer">1</results-available>
|
231
|
+
<events type="array">
|
232
|
+
<event>
|
233
|
+
<accepted type="integer">1</accepted>
|
234
|
+
<event-id type="integer">1</event-id>
|
235
|
+
<updated-at type="datetime">2009-01-01T00:00:00+09:00</updated-at>
|
236
|
+
<title>hoge event</title>
|
237
|
+
<waiting type="integer">0</waiting>
|
238
|
+
<event-url>hoge.com</event-url>
|
239
|
+
<users type="array">
|
240
|
+
<user>
|
241
|
+
<status type="integer">1</status>
|
242
|
+
<nickname>name</nickname>
|
243
|
+
<user-id type="integer">1</user-id>
|
244
|
+
</user>
|
245
|
+
</users>
|
246
|
+
<limit type="integer">1</limit>
|
247
|
+
</event>
|
248
|
+
</events>
|
249
|
+
<results-start type="integer">1</results-start>
|
250
|
+
</hash>
|
251
|
+
EOF
|
252
|
+
doc = REXML::Document.new xml_string
|
253
|
+
|
254
|
+
it "は、入力されたイベントの値がそのまま取得できる" do
|
255
|
+
events = Atnd4r.parse_users_xml(doc)
|
256
|
+
events.length.should == 1
|
257
|
+
events[0].accepted.should == 1
|
258
|
+
events[0].event_id.should == 1
|
259
|
+
events[0].updated_at.should == Time.parse("2009-01-01T00:00:00+09:00")
|
260
|
+
events[0].title.should == "hoge event"
|
261
|
+
events[0].waiting.should == 0
|
262
|
+
events[0].event_url.should == "hoge.com"
|
263
|
+
events[0].limit.should == 1
|
264
|
+
end
|
265
|
+
|
266
|
+
it "は、入力されたユーザの値がそのまま取得できる" do
|
267
|
+
events = Atnd4r.parse_users_xml(doc)
|
268
|
+
events[0].users.length.should == 1
|
269
|
+
events[0].users[0].status.should == 1
|
270
|
+
events[0].users[0].nickname.should == "name"
|
271
|
+
events[0].users[0].user_id.should == 1
|
272
|
+
end
|
273
|
+
end
|
274
|
+
|
275
|
+
|
276
|
+
describe "Atnd4r::parse_events_xml が正常に処理したとき" do
|
277
|
+
xml_string =<<-EOF
|
278
|
+
<hash>
|
279
|
+
<results-returned type="integer">1</results-returned>
|
280
|
+
<results-available type="integer">1</results-available>
|
281
|
+
<events type="array">
|
282
|
+
<event>
|
283
|
+
<place/>
|
284
|
+
<lon type="decimal">0.0</lon>
|
285
|
+
<accepted type="integer">1</accepted>
|
286
|
+
<event-id type="integer">1</event-id>
|
287
|
+
<updated-at type="datetime">2009-01-01T11:11:11+09:00</updated-at>
|
288
|
+
<title>hoge event</title>
|
289
|
+
<ended-at nil="true"/>
|
290
|
+
<waiting type="integer">0</waiting>
|
291
|
+
<event-url>hoge.com</event-url>
|
292
|
+
<url nil="true"/>
|
293
|
+
<owner-nickname>name</owner-nickname>
|
294
|
+
<catch>catch</catch>
|
295
|
+
<description>description</description>
|
296
|
+
<owner-id type="integer">1</owner-id>
|
297
|
+
<limit type="integer">1</limit>
|
298
|
+
<lat nil="true"/>
|
299
|
+
<address/>
|
300
|
+
<started-at type="datetime">2009-01-01T00:00:00+09:00</started-at>
|
301
|
+
</event>
|
302
|
+
</events>
|
303
|
+
<results-start type="integer">1</results-start>
|
304
|
+
</hash>
|
305
|
+
EOF
|
306
|
+
doc = REXML::Document.new xml_string
|
307
|
+
|
308
|
+
it "は、入力されたイベントの値がそのまま取得できる" do
|
309
|
+
events = Atnd4r.parse_events_xml(doc)
|
310
|
+
events.length.should == 1
|
311
|
+
events[0].lon.should == 0.0
|
312
|
+
events[0].accepted.should == 1
|
313
|
+
events[0].event_id.should == 1
|
314
|
+
events[0].updated_at.should == Time.parse("2009-01-01T11:11:11+09:00")
|
315
|
+
events[0].started_at.should == Time.parse("2009-01-01T00:00:00+09:00")
|
316
|
+
events[0].title.should == "hoge event"
|
317
|
+
events[0].waiting.should == 0
|
318
|
+
events[0].event_url.should == "hoge.com"
|
319
|
+
events[0].url.should == nil
|
320
|
+
events[0].owner_nickname.should == "name"
|
321
|
+
events[0].owner_id.should == 1
|
322
|
+
events[0].description.should == "description"
|
323
|
+
events[0].catch.should == "catch"
|
324
|
+
events[0].lat.should == nil
|
325
|
+
events[0].address.should == nil
|
326
|
+
events[0].limit.should == 1
|
327
|
+
end
|
328
|
+
|
329
|
+
end
|
330
|
+
|
331
|
+
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'spec'
|
2
|
+
|
3
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
4
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
5
|
+
require 'atnd4r'
|
6
|
+
|
7
|
+
Spec::Runner.configure do |config|
|
8
|
+
|
9
|
+
end
|
10
|
+
|
11
|
+
# HTTP MOCK
|
12
|
+
def create_http_mock(body = "", code = "", status = "")
|
13
|
+
@response_mock = mock(Net::HTTPResponse)
|
14
|
+
@response_mock.stub!(:body).and_return(body)
|
15
|
+
@response_mock.stub!(:code).and_return(code)
|
16
|
+
@response_mock.stub!(:[]).and_return(status)
|
17
|
+
@http_mock = mock('http')
|
18
|
+
@http_mock.stub!(:get).and_return(@response_mock)
|
19
|
+
|
20
|
+
return @http_mock
|
21
|
+
end
|
22
|
+
|
metadata
ADDED
@@ -0,0 +1,69 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: atnd4r
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.6
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- sugamasao
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2009-07-28 00:00:00 +09:00
|
13
|
+
default_executable:
|
14
|
+
dependencies: []
|
15
|
+
|
16
|
+
description:
|
17
|
+
email: sugamasao@gmail.com
|
18
|
+
executables: []
|
19
|
+
|
20
|
+
extensions: []
|
21
|
+
|
22
|
+
extra_rdoc_files:
|
23
|
+
- ChangeLog
|
24
|
+
- README.rdoc
|
25
|
+
files:
|
26
|
+
- .document
|
27
|
+
- .gitignore
|
28
|
+
- ChangeLog
|
29
|
+
- README.rdoc
|
30
|
+
- Rakefile
|
31
|
+
- VERSION
|
32
|
+
- atnd4r.gemspec
|
33
|
+
- lib/atnd4r.rb
|
34
|
+
- spec/atnd4r_spec.rb
|
35
|
+
- spec/spec_helper.rb
|
36
|
+
has_rdoc: true
|
37
|
+
homepage: http://github.com/sugamasao/atnd4r
|
38
|
+
licenses: []
|
39
|
+
|
40
|
+
post_install_message:
|
41
|
+
rdoc_options:
|
42
|
+
- --charset=UTF-8
|
43
|
+
require_paths:
|
44
|
+
- lib
|
45
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
46
|
+
requirements:
|
47
|
+
- - ">="
|
48
|
+
- !ruby/object:Gem::Version
|
49
|
+
version: "0"
|
50
|
+
version:
|
51
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
52
|
+
requirements:
|
53
|
+
- - ">="
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
version: "0"
|
56
|
+
version:
|
57
|
+
requirements: []
|
58
|
+
|
59
|
+
rubyforge_project:
|
60
|
+
rubygems_version: 1.3.5
|
61
|
+
signing_key:
|
62
|
+
specification_version: 3
|
63
|
+
summary: !binary |
|
64
|
+
QVRORCDjga4gQVBJIOOCkiBSdWJ5IOOBi+OCieS9v+eUqOOBmeOCi+OBn+OB
|
65
|
+
ruODqeODg+ODkeODvOOCr+ODqeOCueOBp+OBmQ==
|
66
|
+
|
67
|
+
test_files:
|
68
|
+
- spec/atnd4r_spec.rb
|
69
|
+
- spec/spec_helper.rb
|