basuco 0.0.3
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 +24 -0
- data/Gemfile +4 -0
- data/LICENSE +20 -0
- data/README.textile +318 -0
- data/Rakefile +1 -0
- data/basuco.gemspec +23 -0
- data/examples/artist.rb +20 -0
- data/examples/artist_links.rb +38 -0
- data/lib/basuco.rb +30 -0
- data/lib/basuco/api.rb +26 -0
- data/lib/basuco/attribute.rb +67 -0
- data/lib/basuco/collection.rb +7 -0
- data/lib/basuco/property.rb +91 -0
- data/lib/basuco/request.rb +86 -0
- data/lib/basuco/resource.rb +215 -0
- data/lib/basuco/search.rb +100 -0
- data/lib/basuco/topic.rb +192 -0
- data/lib/basuco/trans.rb +36 -0
- data/lib/basuco/type.rb +53 -0
- data/lib/basuco/util.rb +17 -0
- data/lib/basuco/version.rb +3 -0
- data/lib/basuco/view.rb +54 -0
- data/rails/init.rb +2 -0
- data/stats.sh +30 -0
- data/tasks/ken.rb +4 -0
- data/tasks/spec.rb +25 -0
- data/test/fixtures/music_artist.json +103 -0
- data/test/fixtures/the_police.json +937 -0
- data/test/fixtures/the_police_topic.json +751 -0
- data/test/integration/ken_test.rb +75 -0
- data/test/test_helper.rb +59 -0
- data/test/unit/attribute_test.rb +49 -0
- data/test/unit/property_test.rb +27 -0
- data/test/unit/resource_test.rb +58 -0
- data/test/unit/session_test.rb +44 -0
- data/test/unit/topic_test.rb +92 -0
- data/test/unit/type_test.rb +35 -0
- data/test/unit/view_test.rb +48 -0
- metadata +94 -0
@@ -0,0 +1,75 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class KenTest < Test::Unit::TestCase
|
4
|
+
context "Ken.get" do
|
5
|
+
setup do
|
6
|
+
Ken::Session.new('http://www.freebase.com', 'ma', 'xxxxx')
|
7
|
+
end
|
8
|
+
|
9
|
+
should 'return a Ken::Resource' do
|
10
|
+
the_police = Ken.get("/en/the_police")
|
11
|
+
the_police.should be_kind_of(Ken::Resource)
|
12
|
+
end
|
13
|
+
|
14
|
+
should 'raise a Ken::ResourceNotFound error if id does not exist' do
|
15
|
+
lambda { Ken.get("/en/non_existent_resource") }.should raise_error(Ken::ResourceNotFound)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
context "Ken.all" do
|
20
|
+
should "return a Ken::Collection of Ken::Resources" do
|
21
|
+
resources = Ken.all(:name => "Apple")
|
22
|
+
resources.should be_kind_of(Ken::Collection)
|
23
|
+
resources.first.should be_kind_of(Ken::Resource)
|
24
|
+
end
|
25
|
+
|
26
|
+
should "work with a limit specified" do
|
27
|
+
resources = Ken.all(:name => "Apple", :limit => 3)
|
28
|
+
resources.length.should == 3
|
29
|
+
end
|
30
|
+
|
31
|
+
should "be able to return more than 100 resources (using cursored queries) " do
|
32
|
+
Ken.all({:type => '/chemistry/chemical_element'}).length.should > 100
|
33
|
+
end
|
34
|
+
|
35
|
+
should "work with a type specified" do
|
36
|
+
resources = Ken.all(:name => "Apple", :type => "/music/album")
|
37
|
+
resources.length.should >= 1
|
38
|
+
resources.each {|r| r.types.select {|t| t.id == "/music/album"}.length.should == 1 }
|
39
|
+
end
|
40
|
+
|
41
|
+
should "understand nested queries" do
|
42
|
+
query = {
|
43
|
+
:directed_by => "George Lucas",
|
44
|
+
:starring => [
|
45
|
+
{
|
46
|
+
:actor => "Harrison Ford"
|
47
|
+
}
|
48
|
+
],
|
49
|
+
:type => "/film/film"
|
50
|
+
}
|
51
|
+
|
52
|
+
resources = Ken.all(query)
|
53
|
+
resources.length.should == 3
|
54
|
+
resources.first.name.should == "Star Wars Episode IV: A New Hope"
|
55
|
+
resources.last.name.should == "The Star Wars Holiday Special"
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
context "A Ken::Resource Instance" do
|
60
|
+
setup do
|
61
|
+
@the_police = Ken.get("/en/the_police")
|
62
|
+
end
|
63
|
+
|
64
|
+
should "provide attributes" do
|
65
|
+
@the_police.attributes.length.should >= 1
|
66
|
+
@the_police.attributes.first.should be_kind_of(Ken::Attribute)
|
67
|
+
end
|
68
|
+
|
69
|
+
should "have views" do
|
70
|
+
@the_police.views.length.should >= 1
|
71
|
+
@the_police.views.first.should be_kind_of(Ken::View)
|
72
|
+
@the_police.views.first.type.should be_kind_of(Ken::Type)
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
data/test/test_helper.rb
ADDED
@@ -0,0 +1,59 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'test/unit'
|
3
|
+
require 'shoulda'
|
4
|
+
require 'pathname'
|
5
|
+
require 'json'
|
6
|
+
require 'matchy'
|
7
|
+
|
8
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
9
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
10
|
+
|
11
|
+
TEST_ROOT = Pathname(__FILE__).dirname.expand_path
|
12
|
+
require TEST_ROOT.parent + 'lib/ken'
|
13
|
+
|
14
|
+
def load_fixture(fixture_name)
|
15
|
+
fname = "#{File.dirname(__FILE__)}/fixtures/#{fixture_name}.json"
|
16
|
+
unless File.exists?(fname)
|
17
|
+
open(fname, "w") do |file|
|
18
|
+
puts "WARNING: Fixtures could not be loaded."
|
19
|
+
end
|
20
|
+
end
|
21
|
+
JSON.parse open(fname,"r").read
|
22
|
+
end
|
23
|
+
|
24
|
+
class Test::Unit::TestCase
|
25
|
+
custom_matcher :be_nil do |receiver, matcher, args|
|
26
|
+
matcher.positive_failure_message = "Expected #{receiver} to be nil but it wasn't"
|
27
|
+
matcher.negative_failure_message = "Expected #{receiver} not to be nil but it was"
|
28
|
+
receiver.nil?
|
29
|
+
end
|
30
|
+
|
31
|
+
custom_matcher :have do |receiver, matcher, args|
|
32
|
+
count = args[0]
|
33
|
+
something = matcher.chained_messages[0].name
|
34
|
+
actual = receiver.send(something).size
|
35
|
+
actual == count
|
36
|
+
end
|
37
|
+
|
38
|
+
custom_matcher :be_true do |receiver, matcher, args|
|
39
|
+
matcher.positive_failure_message = "Expected #{receiver} to be true but it wasn't"
|
40
|
+
matcher.negative_failure_message = "Expected #{receiver} not to be true but it was"
|
41
|
+
receiver.eql?(true)
|
42
|
+
end
|
43
|
+
|
44
|
+
custom_matcher :be_false do |receiver, matcher, args|
|
45
|
+
matcher.positive_failure_message = "Expected #{receiver} to be false but it wasn't"
|
46
|
+
matcher.negative_failure_message = "Expected #{receiver} not to be false but it was"
|
47
|
+
receiver.eql?(false)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
class Object
|
52
|
+
# nice for debugging
|
53
|
+
# usage: print_call_stack(:method_name, 2, 10)
|
54
|
+
def print_call_stack(from = 2, to = nil, html = false)
|
55
|
+
(from..(to ? to : caller.length)).each do |idx|
|
56
|
+
p "[#{idx}]: #{caller[idx]}#{html ? '<br />' : ''}"
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class AttributeTest < Test::Unit::TestCase
|
4
|
+
context "An Attribute instance" do
|
5
|
+
setup do
|
6
|
+
data = load_fixture('the_police')
|
7
|
+
@the_police = Ken::Resource.new(data)
|
8
|
+
|
9
|
+
@attribute = @unique_value_attribute = @the_police.views[0].active_start
|
10
|
+
@unique_object_attribute = @the_police.views[0].origin
|
11
|
+
@unique_object_attribute.unique?
|
12
|
+
@non_unique_value_attribute = @the_police.views[1].alias
|
13
|
+
@non_unique_object_attribute = @the_police.views[0].album
|
14
|
+
end
|
15
|
+
|
16
|
+
should "should have values" do
|
17
|
+
@attribute.should have(1).values
|
18
|
+
@non_unique_object_attribute.should have(14).values
|
19
|
+
end
|
20
|
+
|
21
|
+
context "with unique value type" do
|
22
|
+
should "be unique and no object_type" do
|
23
|
+
@unique_value_attribute.unique?.should == true
|
24
|
+
@unique_value_attribute.object_type?.should == false
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
context "with unique object type" do
|
29
|
+
should "be unique and an object type" do
|
30
|
+
@unique_object_attribute.unique?.should == true
|
31
|
+
@unique_object_attribute.object_type?.should == true
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
context "with non-unique value type" do
|
36
|
+
should "not be unique and not an object type" do
|
37
|
+
@non_unique_value_attribute.unique?.should == false
|
38
|
+
@non_unique_value_attribute.object_type?.should == false
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
context "with non-unique object type" do
|
43
|
+
should "be unique and an object type" do
|
44
|
+
@non_unique_object_attribute.unique?.should == false
|
45
|
+
@non_unique_object_attribute.object_type?.should == true
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end # context
|
49
|
+
end # AttributeTest
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class PropertyTest < Test::Unit::TestCase
|
4
|
+
context "A Property instance" do
|
5
|
+
setup do
|
6
|
+
data = load_fixture('music_artist')
|
7
|
+
@type = Ken::Type.new(data)
|
8
|
+
@value_property = @type.properties[1]
|
9
|
+
@object_property = @type.properties[3]
|
10
|
+
end
|
11
|
+
|
12
|
+
should 'be a valid property instance' do
|
13
|
+
@value_property.should be_kind_of(Ken::Property)
|
14
|
+
@object_property.should be_kind_of(Ken::Property)
|
15
|
+
end
|
16
|
+
|
17
|
+
should 'have a type' do
|
18
|
+
@value_property.type.should be_kind_of(Ken::Type)
|
19
|
+
@object_property.type.should be_kind_of(Ken::Type)
|
20
|
+
end
|
21
|
+
|
22
|
+
should 'distinguish wheter it is an object or value type' do
|
23
|
+
@value_property.object_type?.should == false
|
24
|
+
@object_property.object_type?.should == true
|
25
|
+
end
|
26
|
+
end # context
|
27
|
+
end # PropertyTest
|
@@ -0,0 +1,58 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class ResourceTest < Test::Unit::TestCase
|
4
|
+
context "A Resource instance" do
|
5
|
+
setup do
|
6
|
+
data = load_fixture('the_police')
|
7
|
+
@the_police = Ken::Resource.new(data)
|
8
|
+
end
|
9
|
+
|
10
|
+
should "have types" do
|
11
|
+
@the_police.should have(6).types
|
12
|
+
@the_police.types.first.should be_kind_of(Ken::Type)
|
13
|
+
end
|
14
|
+
|
15
|
+
should "have views" do
|
16
|
+
@the_police.should have(6).views
|
17
|
+
@the_police.views.first.should be_kind_of(Ken::View)
|
18
|
+
@the_police.views.first.type.should be_kind_of(Ken::Type)
|
19
|
+
end
|
20
|
+
|
21
|
+
should "return individual view based requested type id" do
|
22
|
+
@the_police.view('/music/artist').should be_kind_of(Ken::View)
|
23
|
+
@the_police.view('/location/location').should be_nil # not existent view
|
24
|
+
end
|
25
|
+
|
26
|
+
should "return individual type based requested type id" do
|
27
|
+
@the_police.type('/music/artist').should be_kind_of(Ken::Type)
|
28
|
+
@the_police.type('/location/location').should be_nil # not existent type
|
29
|
+
end
|
30
|
+
|
31
|
+
should 'have a full set of attributes' do
|
32
|
+
@the_police.attributes.should_not be_nil
|
33
|
+
end
|
34
|
+
|
35
|
+
should "have id and name properties" do
|
36
|
+
@the_police.id.should be_kind_of(String)
|
37
|
+
@the_police.name.should be_kind_of(String)
|
38
|
+
end
|
39
|
+
|
40
|
+
should 'load attributes only on demand' do
|
41
|
+
@the_police.attributes_loaded?.should == false
|
42
|
+
@the_police.attributes
|
43
|
+
@the_police.attributes_loaded?.should == true
|
44
|
+
end
|
45
|
+
|
46
|
+
should 'load schema only on demand when calling types' do
|
47
|
+
@the_police.schema_loaded?.should == false
|
48
|
+
@the_police.types
|
49
|
+
@the_police.schema_loaded?.should == true
|
50
|
+
end
|
51
|
+
|
52
|
+
should 'load schema only on demand when calling views' do
|
53
|
+
@the_police.schema_loaded?.should == false
|
54
|
+
@the_police.views
|
55
|
+
@the_police.schema_loaded?.should == true
|
56
|
+
end
|
57
|
+
end # context
|
58
|
+
end # ResourceTest
|
@@ -0,0 +1,44 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class SessionTest < Test::Unit::TestCase
|
4
|
+
context "A Session instance" do
|
5
|
+
setup do
|
6
|
+
# Ken::Logger.new(STDOUT, :info)
|
7
|
+
Ken::Session.new('http://www.freebase.com', 'ma', 'xxxxx')
|
8
|
+
end
|
9
|
+
|
10
|
+
should 'return the correct set of types' do
|
11
|
+
result = Ken.session.mqlread({:id => "/en/the_police", :type => []})
|
12
|
+
result['type'].length.should >= 1
|
13
|
+
end
|
14
|
+
|
15
|
+
should 'raise a Ken::MqlReadError if node does not exist' do
|
16
|
+
lambda { Ken.session.mqlread({:id => "/en/the_police", :evil_property => []}) }.should raise_error(Ken::ReadError)
|
17
|
+
end
|
18
|
+
|
19
|
+
should 'do uncursored queries' do
|
20
|
+
Ken.session.mqlread([{:type => '/chemistry/chemical_element'}]).length == 100
|
21
|
+
end
|
22
|
+
|
23
|
+
should 'do cursored queries' do
|
24
|
+
Ken.session.mqlread([{:type => '/chemistry/chemical_element'}], :cursor => true).length.should >= 117
|
25
|
+
end
|
26
|
+
|
27
|
+
should 'do raw content requests' do
|
28
|
+
Ken.session.raw_content("/guid/9202a8c04000641f800000000002c4f3").length.should >= 50
|
29
|
+
end
|
30
|
+
|
31
|
+
should 'do blurb content requests' do
|
32
|
+
Ken.session.blurb_content("/guid/9202a8c04000641f800000000002c4f3", :maxlength => 200).length.should >= 50
|
33
|
+
end
|
34
|
+
|
35
|
+
should 'do topic requests' do
|
36
|
+
Ken.session.topic("/en/the_police")
|
37
|
+
end
|
38
|
+
|
39
|
+
should 'do search requests' do
|
40
|
+
Ken.session.search("the police").length.should >= 1
|
41
|
+
end
|
42
|
+
|
43
|
+
end # context
|
44
|
+
end # SessionTest
|
@@ -0,0 +1,92 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class TopicTest < Test::Unit::TestCase
|
4
|
+
context "A Topic instance" do
|
5
|
+
setup do
|
6
|
+
data = load_fixture('the_police_topic')
|
7
|
+
@the_police = Ken::Topic.new(data)
|
8
|
+
end
|
9
|
+
|
10
|
+
should "have an id" do
|
11
|
+
@the_police.id.should == "/en/the_police"
|
12
|
+
end
|
13
|
+
|
14
|
+
should "have aliases" do
|
15
|
+
@the_police.aliases.length.should >= 1
|
16
|
+
end
|
17
|
+
|
18
|
+
should "have a text/name" do
|
19
|
+
@the_police.text.should == "The Police"
|
20
|
+
@the_police.name.should == "The Police"
|
21
|
+
end
|
22
|
+
|
23
|
+
should "have a thumbnail" do
|
24
|
+
@the_police.thumbnail.should == "http://api.freebase.com/api/trans/image_thumb/en/the_police"
|
25
|
+
end
|
26
|
+
|
27
|
+
should "have webpages" do
|
28
|
+
@the_police.webpages.length.should == 5
|
29
|
+
end
|
30
|
+
|
31
|
+
should "have types" do
|
32
|
+
@the_police.types.length.should == 7
|
33
|
+
@the_police.types.first.should be_kind_of(Ken::Type)
|
34
|
+
end
|
35
|
+
|
36
|
+
should "have properties" do
|
37
|
+
@the_police.properties.length.should >= 1
|
38
|
+
@the_police.properties.first.should be_kind_of(Ken::Property)
|
39
|
+
end
|
40
|
+
|
41
|
+
should "have attributes" do
|
42
|
+
@the_police.attributes.first.should be_kind_of(Ken::Attribute)
|
43
|
+
|
44
|
+
# TODO support mediator properties (CVT's)
|
45
|
+
# @the_police.attributes.length.should == @the_police.properties.length
|
46
|
+
end
|
47
|
+
|
48
|
+
should "have views" do
|
49
|
+
@the_police.should have(7).views
|
50
|
+
@the_police.views.first.should be_kind_of(Ken::View)
|
51
|
+
@the_police.views.first.type.should be_kind_of(Ken::Type)
|
52
|
+
end
|
53
|
+
|
54
|
+
should "return individual view based requested type id" do
|
55
|
+
@the_police.view('/music/artist').should be_kind_of(Ken::View)
|
56
|
+
@the_police.view('/music/artist').attributes.length.should == 9
|
57
|
+
@the_police.view('/location/location').should be_nil # not existent view
|
58
|
+
end
|
59
|
+
|
60
|
+
should "return individual type based requested type id" do
|
61
|
+
@the_police.type('/music/artist').should be_kind_of(Ken::Type)
|
62
|
+
@the_police.type('/location/location').should be_nil # not existent type
|
63
|
+
end
|
64
|
+
|
65
|
+
should 'have a full set of attributes' do
|
66
|
+
@the_police.attributes.should_not be_nil
|
67
|
+
end
|
68
|
+
|
69
|
+
should "have id and name properties" do
|
70
|
+
@the_police.id.should be_kind_of(String)
|
71
|
+
@the_police.name.should be_kind_of(String)
|
72
|
+
end
|
73
|
+
|
74
|
+
should 'load attributes only on demand' do
|
75
|
+
@the_police.attributes_loaded?.should == false
|
76
|
+
@the_police.attributes
|
77
|
+
@the_police.attributes_loaded?.should == true
|
78
|
+
end
|
79
|
+
|
80
|
+
should 'load schema only on demand when calling types' do
|
81
|
+
@the_police.schema_loaded?.should == false
|
82
|
+
@the_police.types
|
83
|
+
@the_police.schema_loaded?.should == true
|
84
|
+
end
|
85
|
+
|
86
|
+
should 'load schema only on demand when calling views' do
|
87
|
+
@the_police.schema_loaded?.should == false
|
88
|
+
@the_police.views
|
89
|
+
@the_police.schema_loaded?.should == true
|
90
|
+
end
|
91
|
+
end # context
|
92
|
+
end # TopicTest
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class TypeTest < Test::Unit::TestCase
|
4
|
+
context "A Session instance" do
|
5
|
+
setup do
|
6
|
+
data = load_fixture('the_police')
|
7
|
+
@type = Ken::Resource.new(data).types.first
|
8
|
+
end
|
9
|
+
|
10
|
+
should 'have an id and a name' do
|
11
|
+
@type.id.should be_kind_of(String)
|
12
|
+
@type.name.should be_kind_of(String)
|
13
|
+
end
|
14
|
+
|
15
|
+
should 'have properties' do
|
16
|
+
@type.should have(16).properties
|
17
|
+
end
|
18
|
+
|
19
|
+
context "when accessing a property directly" do
|
20
|
+
setup do
|
21
|
+
@genre = @type.genre
|
22
|
+
@album = @type.album
|
23
|
+
end
|
24
|
+
|
25
|
+
should "be kind of Ken::Property" do
|
26
|
+
@genre.should be_kind_of(Ken::Property)
|
27
|
+
@album.should be_kind_of(Ken::Property)
|
28
|
+
end
|
29
|
+
|
30
|
+
should "raise AttributeNotFound when invalid propertyname is supplied" do
|
31
|
+
lambda { @type.not_existing_property }.should raise_error(Ken::PropertyNotFound)
|
32
|
+
end
|
33
|
+
end # context
|
34
|
+
end # context
|
35
|
+
end # TypeTest
|