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.
@@ -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