mochi 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/app/models/mochi/feed.rb +48 -0
- data/app/models/mochi/game.rb +83 -0
- data/lib/mochi.rb +5 -0
- data/lib/mochi/engine.rb +9 -0
- data/spec/feed_spec.rb +107 -0
- data/spec/spec_helper.rb +9 -0
- metadata +77 -0
@@ -0,0 +1,48 @@
|
|
1
|
+
module Mochi
|
2
|
+
|
3
|
+
class Feed
|
4
|
+
include HappyMapper
|
5
|
+
tag 'feed'
|
6
|
+
|
7
|
+
attr_accessor :url
|
8
|
+
|
9
|
+
element :id, String
|
10
|
+
element :title, String
|
11
|
+
element :subtitle, String
|
12
|
+
element :icon, String
|
13
|
+
element :updated, Time
|
14
|
+
|
15
|
+
has_many :games, "Mochi::Game", :tag => "entry"
|
16
|
+
has_one :link, "Mochi::Link"
|
17
|
+
has_one :author, "Mochi::Author"
|
18
|
+
|
19
|
+
after_parse(&:set_url)
|
20
|
+
|
21
|
+
protected
|
22
|
+
|
23
|
+
def set_url
|
24
|
+
self.url = self.link.url if self.link.url
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
28
|
+
|
29
|
+
class Link
|
30
|
+
include HappyMapper
|
31
|
+
tag 'link'
|
32
|
+
|
33
|
+
attribute :url, String, :tag => "href"
|
34
|
+
attribute :rel, String
|
35
|
+
attribute :file_type, String, :tag => "type"
|
36
|
+
end
|
37
|
+
|
38
|
+
class Author
|
39
|
+
include HappyMapper
|
40
|
+
tag 'author'
|
41
|
+
|
42
|
+
element :email, String
|
43
|
+
element :name, String
|
44
|
+
element :url, String, :tag => "uri"
|
45
|
+
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
@@ -0,0 +1,83 @@
|
|
1
|
+
module Mochi
|
2
|
+
|
3
|
+
NAMESPACES = {
|
4
|
+
:media => 'http://search.yahoo.com/mrss/',
|
5
|
+
:summary => 'http://www.w3.org/1999/xhtml'
|
6
|
+
}
|
7
|
+
|
8
|
+
class Game
|
9
|
+
include HappyMapper
|
10
|
+
tag 'entry'
|
11
|
+
|
12
|
+
attr_accessor :summary
|
13
|
+
|
14
|
+
element :id, String
|
15
|
+
element :title, String
|
16
|
+
element :description, String, :namespace => NAMESPACES[:media]
|
17
|
+
element :updated, Time
|
18
|
+
element :published, Time
|
19
|
+
element :thumbnail, String, :namespace => NAMESPACES[:media], :attributes => { :height => Integer, :width => Integer, :url => String }
|
20
|
+
element :keywords, String, :namespace => NAMESPACES[:media]
|
21
|
+
element :player, String, :namespace => NAMESPACES[:media], :attributes => {:height => Integer, :width => Integer, :url => String}
|
22
|
+
element :category, String
|
23
|
+
|
24
|
+
has_one :author, 'Mochi::Author'
|
25
|
+
has_many :links, 'Mochi::Link'
|
26
|
+
has_many :categories, 'Mochi::GameCategory' #TODO http://agilezen.com/project/6997/story/82
|
27
|
+
has_many :details, 'Mochi::GameDetail'
|
28
|
+
|
29
|
+
after_parse(&:format_keywords)
|
30
|
+
after_parse(&:parse_categories)
|
31
|
+
after_parse(&:create_summary_hash)
|
32
|
+
|
33
|
+
protected
|
34
|
+
|
35
|
+
def format_keywords
|
36
|
+
self.keywords = keywords.nil? ? [] : keywords.split(',').map(&:strip).compact
|
37
|
+
end
|
38
|
+
|
39
|
+
def parse_categories
|
40
|
+
self.categories = categories.map{|category| category.term}.compact
|
41
|
+
end
|
42
|
+
|
43
|
+
def create_summary_hash
|
44
|
+
self.summary = details.map(&:to_hash).inject({}){|sum, detail| sum.merge detail}
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
48
|
+
|
49
|
+
class GameCategory
|
50
|
+
include HappyMapper
|
51
|
+
tag 'category'
|
52
|
+
|
53
|
+
attribute :term, String
|
54
|
+
end
|
55
|
+
|
56
|
+
class GameDetail
|
57
|
+
include HappyMapper
|
58
|
+
tag 'dd'
|
59
|
+
namespace NAMESPACES[:summary]
|
60
|
+
content :value
|
61
|
+
|
62
|
+
element :embed, String, :tag => 'code'
|
63
|
+
attribute :detail_type, String, :tag => "class"
|
64
|
+
|
65
|
+
after_parse(&:check_embed)
|
66
|
+
|
67
|
+
def to_hash
|
68
|
+
{ detail_type.to_sym => value }
|
69
|
+
end
|
70
|
+
|
71
|
+
protected
|
72
|
+
|
73
|
+
def check_embed
|
74
|
+
self.detail_type, self.value = 'embed', embed if detail_type == "" && embed != ""
|
75
|
+
end
|
76
|
+
|
77
|
+
end
|
78
|
+
|
79
|
+
end
|
80
|
+
|
81
|
+
|
82
|
+
|
83
|
+
|
data/lib/mochi.rb
ADDED
data/lib/mochi/engine.rb
ADDED
data/spec/feed_spec.rb
ADDED
@@ -0,0 +1,107 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/spec_helper.rb'
|
2
|
+
|
3
|
+
describe Mochi::Feed do
|
4
|
+
|
5
|
+
describe "Feed" do
|
6
|
+
before(:all) do
|
7
|
+
@xml = fixture_file("feed.xml")
|
8
|
+
@games = Mochi::Game.parse(@xml)
|
9
|
+
@feed = Mochi::Feed.parse(@xml)
|
10
|
+
@game = @games.first
|
11
|
+
end
|
12
|
+
|
13
|
+
it "game entries should equall game feed entries" do
|
14
|
+
@games == @feed.games
|
15
|
+
end
|
16
|
+
|
17
|
+
it "should contains 5 games" do
|
18
|
+
@games.size.should == 5
|
19
|
+
end
|
20
|
+
|
21
|
+
it "should include valid feed elements from xml" do
|
22
|
+
@feed.id.should == "urn:uuid:6b91fc41-ef25-4e91-ae40-f98a1e7b802a"
|
23
|
+
@feed.title.should == "Mochi Games"
|
24
|
+
@feed.subtitle.should == "Free Games for Portals"
|
25
|
+
@feed.icon.should == "http://www.mochimedia.com/favicon.ico"
|
26
|
+
@feed.updated.to_s.should == "Tue Aug 03 19:19:58 UTC 2010"
|
27
|
+
end
|
28
|
+
|
29
|
+
it "should include valid author" do
|
30
|
+
@feed.author.name.should == "Mochi Media, Inc."
|
31
|
+
@feed.author.email.should == "team@mochimedia.com"
|
32
|
+
@feed.author.url.should == "team.mochimedia.com"
|
33
|
+
end
|
34
|
+
|
35
|
+
it "should include valid link" do
|
36
|
+
@feed.link.url.should == "http://www.mochimedia.com/feeds/games"
|
37
|
+
@feed.url.should == @feed.link.url
|
38
|
+
@feed.link.rel.should == "self"
|
39
|
+
end
|
40
|
+
|
41
|
+
describe "game entrie" do
|
42
|
+
|
43
|
+
it "should include valid elements from xml" do
|
44
|
+
@game.title.should == "cling"
|
45
|
+
@game.updated.to_s.should == "Tue Aug 03 11:44:36 +0200 2010"
|
46
|
+
@game.published.to_s.should == "Tue Aug 03 11:44:36 +0200 2010"
|
47
|
+
@game.description.should == "Welcome to cling! Your goal is to help Edgar the electric spider to the goal at the end of each level."
|
48
|
+
@game.id.should == "urn:uuid:6591f99d-642f-3415-971e-98cd79f57998"
|
49
|
+
end
|
50
|
+
|
51
|
+
it "should has one thumbnail element with valid attributes" do
|
52
|
+
thumbnail = @game.thumbnail
|
53
|
+
thumbnail.should == ""
|
54
|
+
[thumbnail.height,thumbnail.width,thumbnail.url].should == [100,120,"http://thumbs.mochiads.com/c/g/cling/_thumb_100x100.png"]
|
55
|
+
end
|
56
|
+
|
57
|
+
it "should has one media player element with valid attributes" do
|
58
|
+
player = @game.player
|
59
|
+
player.should == ""
|
60
|
+
[player.height,player.width,player.url].should == [600,620,"http://games.mochiads.com/c/g/cling/cling.swf"]
|
61
|
+
end
|
62
|
+
|
63
|
+
it "should has one keywords array" do
|
64
|
+
@game.keywords.should == %w(cling edgar electric)
|
65
|
+
@games[1].keywords.should be_empty # tag blank
|
66
|
+
@games[2].keywords.should be_empty # tag doesn't exists
|
67
|
+
end
|
68
|
+
|
69
|
+
it "should have 2 links with different types" do
|
70
|
+
@game.links.should have(2).links
|
71
|
+
end
|
72
|
+
|
73
|
+
it "should have links with valid attributes" do
|
74
|
+
link_attributes = @game.links.map{|link| [link.url, link.rel, link.file_type] }
|
75
|
+
link_attributes.first.should == ["http://www.mochimedia.com/games/cling",'alternate','']
|
76
|
+
link_attributes[1].should == ["http://games.mochiads.com/c/g/cling/cling.swf",'enclosure','application/x-shockwave-flash']
|
77
|
+
end
|
78
|
+
|
79
|
+
it "should have parsed categories array" do
|
80
|
+
@game.categories.should == %w(Action Other)
|
81
|
+
@games[1].categories.should be_empty # tag doesn't exists
|
82
|
+
end
|
83
|
+
|
84
|
+
it "should have parsed game details array " do
|
85
|
+
@game.details.class.should == Array
|
86
|
+
@game.details.should have(15).elements
|
87
|
+
@game.details.first.detail_type.should == "tag"
|
88
|
+
@game.details.first.value.should == "17466d6f69a60aa2"
|
89
|
+
end
|
90
|
+
|
91
|
+
it "shouldn't have detail without value" do
|
92
|
+
@game.details.each {|detail| detail.detail_type.should_not == "" }
|
93
|
+
end
|
94
|
+
|
95
|
+
it "should have valid parsed detail 'embed'" do
|
96
|
+
embed = @game.details.find{|detail| detail.detail_type == 'embed'}
|
97
|
+
embed.should_not be_nil
|
98
|
+
embed.value.should == 'Embed code'
|
99
|
+
end
|
100
|
+
|
101
|
+
it "should create summary hash from details" do
|
102
|
+
@game.summary.map{|k,v| k}.size.should == 15
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
end
|
107
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,9 @@
|
|
1
|
+
require 'spec'
|
2
|
+
require File.dirname(__FILE__) + '/../lib/mochi.rb'
|
3
|
+
require File.expand_path("../../app/models/mochi/game.rb", __FILE__)
|
4
|
+
require File.expand_path("../../app/models/mochi/feed.rb", __FILE__)
|
5
|
+
|
6
|
+
def fixture_file(filename)
|
7
|
+
File.read(File.dirname(__FILE__) + "/fixtures/#{filename}")
|
8
|
+
end
|
9
|
+
|
metadata
ADDED
@@ -0,0 +1,77 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: mochi
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease: false
|
5
|
+
segments:
|
6
|
+
- 0
|
7
|
+
- 1
|
8
|
+
- 0
|
9
|
+
version: 0.1.0
|
10
|
+
platform: ruby
|
11
|
+
authors:
|
12
|
+
- Damian Nurzynski (dnurzynski)
|
13
|
+
autorequire:
|
14
|
+
bindir: bin
|
15
|
+
cert_chain: []
|
16
|
+
|
17
|
+
date: 2010-08-12 00:00:00 +02:00
|
18
|
+
default_executable:
|
19
|
+
dependencies:
|
20
|
+
- !ruby/object:Gem::Dependency
|
21
|
+
name: happymapper
|
22
|
+
prerelease: false
|
23
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
24
|
+
requirements:
|
25
|
+
- - ">="
|
26
|
+
- !ruby/object:Gem::Version
|
27
|
+
segments:
|
28
|
+
- 0
|
29
|
+
version: "0"
|
30
|
+
type: :runtime
|
31
|
+
version_requirements: *id001
|
32
|
+
description: Mochi api for Rails (www.mochimedia.com)
|
33
|
+
email: dnurzynski@gmail.com
|
34
|
+
executables: []
|
35
|
+
|
36
|
+
extensions: []
|
37
|
+
|
38
|
+
extra_rdoc_files: []
|
39
|
+
|
40
|
+
files:
|
41
|
+
- app/models/mochi/feed.rb
|
42
|
+
- app/models/mochi/game.rb
|
43
|
+
- lib/mochi.rb
|
44
|
+
- lib/mochi/engine.rb
|
45
|
+
has_rdoc: true
|
46
|
+
homepage: http://github.com/dnurzynski/mochi
|
47
|
+
licenses: []
|
48
|
+
|
49
|
+
post_install_message:
|
50
|
+
rdoc_options:
|
51
|
+
- --charset=UTF-8
|
52
|
+
require_paths:
|
53
|
+
- lib
|
54
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
55
|
+
requirements:
|
56
|
+
- - ">="
|
57
|
+
- !ruby/object:Gem::Version
|
58
|
+
segments:
|
59
|
+
- 0
|
60
|
+
version: "0"
|
61
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
62
|
+
requirements:
|
63
|
+
- - ">="
|
64
|
+
- !ruby/object:Gem::Version
|
65
|
+
segments:
|
66
|
+
- 0
|
67
|
+
version: "0"
|
68
|
+
requirements: []
|
69
|
+
|
70
|
+
rubyforge_project:
|
71
|
+
rubygems_version: 1.3.6
|
72
|
+
signing_key:
|
73
|
+
specification_version: 3
|
74
|
+
summary: Mochi api for Rails3 (www.mochimedia.com)
|
75
|
+
test_files:
|
76
|
+
- spec/feed_spec.rb
|
77
|
+
- spec/spec_helper.rb
|