atnd4r 0.0.6

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,4 @@
1
+ README.rdoc
2
+ lib/**/*.rb
3
+ bin/*
4
+ features/**/*.feature
@@ -0,0 +1,5 @@
1
+ *.sw?
2
+ .DS_Store
3
+ coverage
4
+ rdoc
5
+ pkg
@@ -0,0 +1,9 @@
1
+ = ChangeLog
2
+
3
+ == 2009-07-27 sugamasao@gmail.com
4
+
5
+ * 1st release
6
+
7
+ == 2009-07-23 sugamasao@gmail.com
8
+
9
+ * add by spec cases.
@@ -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
+
@@ -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
@@ -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
@@ -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
@@ -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
+
@@ -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