ape 1.5.1 → 1.6.0

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.
@@ -57,6 +57,10 @@ module Ape
57
57
  end
58
58
  return false
59
59
  end
60
+
61
+ def code
62
+ @response.code
63
+ end
60
64
 
61
65
  def getBody contentType
62
66
 
@@ -66,15 +70,27 @@ module Ape
66
70
  if @contentType =~ /^([^;]*);/
67
71
  @contentType = $1
68
72
  end
69
-
73
+
70
74
  if contentType != @contentType
71
- @last_error = "Content-type must be '#{contentType}', not '#{@contentType}'"
75
+ @response = Net::HTTPGone.new('1.1', '409',
76
+ "Content-type must be '#{contentType}', not '#{@contentType}'")
77
+ @body = ""
72
78
  end
73
79
  end
74
80
 
75
81
  @body = @response.body
76
82
  return true
77
83
  end
84
+
85
+ # Handy wrapper with optional media-type checking; return the Response object
86
+ def Getter.retrieve(uri, content_type=nil, authent=nil)
87
+
88
+ getter = Getter.new(uri, authent)
89
+ raise(Exception, "Bad URI value #{uri}") if getter.last_error
90
+
91
+ getter.get content_type
92
+ return getter.response
93
+ end
78
94
  end
79
95
  end
80
96
 
@@ -8,12 +8,11 @@ module Ape
8
8
 
9
9
  def initialize(uriString, authent)
10
10
  super uriString, authent
11
- @headers = {}
12
11
  @entry = nil
13
12
  end
14
13
 
15
- def set_header(name, val)
16
- @headers[name] = val
14
+ def authoritative?
15
+ @response['Location'] == @response['Content-Location']
17
16
  end
18
17
 
19
18
  def post(contentType, body, req = nil)
@@ -35,16 +34,16 @@ module Ape
35
34
  return false
36
35
  end
37
36
 
38
- if (!((@response['Content-type'] =~ %r{^application/atom\+xml}) ||
39
- (@response['Content-type'] =~ %r{^application/atom\+xml;type=entry})))
37
+ # XXX how can this happen?
38
+ if (!(@response['Content-type'] =~ %r{^application/atom\+xml(;type=entry)?}))
40
39
  return true
41
40
  end
42
41
 
43
42
  begin
44
- @entry = Entry.new(@response.body)
43
+ @entry = Entry.new(:text => @response.body, :uri => @response['Location'])
45
44
  return true
46
45
  rescue ArgumentError
47
- @last_error = @entry.broken
46
+ @last_error = $!.to_s
48
47
  return false
49
48
  end
50
49
  end
@@ -1,4 +1,4 @@
1
- # Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved
1
+ # Copyright (c) 2006 Sun Microsystems, Inc. All rights reserved
2
2
  # Use is subject to license terms - see file "LICENSE"
3
3
 
4
4
  module Ape
@@ -16,6 +16,7 @@ module Ape
16
16
 
17
17
  AtomMediaType = 'application/atom+xml' unless defined?(AtomMediaType)
18
18
  AtomEntryMediaType = 'application/atom+xml;type=entry' unless defined?(AtomEntryMediaType)
19
+ AtomFeedMediaType = 'application/atom+xml;type=feed' unless defined?(AtomFeedMediaType)
19
20
  AppMediaType = 'application/atomsvc+xml' unless defined?(AppMediaType)
20
21
 
21
22
  end
@@ -23,7 +23,7 @@ module Ape
23
23
 
24
24
  def self.supported_outputs
25
25
  Dir[File.join(File.dirname(__FILE__), 'reporters/*.rb'),
26
- File.join(Ape.home, 'reporters/*.rb')].map { |file|
26
+ File.join(::Ape.home, 'reporters/*.rb')].map { |file|
27
27
  file.gsub(/(.+\/reporters\/)(.+)(_reporter.rb)/, '\2').gsub(/_/, '')
28
28
  }.sort.join(", ").downcase
29
29
  end
@@ -61,8 +61,8 @@ module Ape
61
61
  end
62
62
 
63
63
  def Samples.entry_path(type)
64
- File.exist?(File.join(Ape.home, "/#{type}.eruby"))?
65
- File.join(Ape.home, "/#{type}.eruby") :
64
+ File.exist?(File.join(::Ape.home, "/#{type}.eruby"))?
65
+ File.join(::Ape.home, "/#{type}.eruby") :
66
66
  File.join(File.dirname(__FILE__), "/../../samples/#{type}.eruby")
67
67
  end
68
68
 
@@ -16,7 +16,7 @@ module Ape
16
16
  # * :port - the port number to listen on
17
17
  # * :directory - the ape home directory
18
18
  def self.run(options)
19
- Ape.home = options[:home]
19
+ ::Ape.home = options[:home]
20
20
 
21
21
  mongrel = Mongrel::Configurator.new(:host => options[:host], :port => options[:port]) do
22
22
  log "=> Booting mongrel"
@@ -4,9 +4,26 @@ require 'rexml/xpath'
4
4
 
5
5
  module Ape
6
6
  class Service
7
- def Service.collections(service, uri)
8
- nodes = REXML::XPath.match(service, '//app:collection', Names::XmlNamespaces)
9
- nodes.collect { |n| Collection.new(n, uri) }
7
+ require File.dirname(__FILE__) + '/util.rb'
8
+ include Ape::Util::InstanceMethods
9
+
10
+ attr_accessor :service, :reporter
11
+
12
+ def initialize(opts = {}) #uri = nil, authent = nil)
13
+ @authent = opts[:authent]
14
+ @reporter = opts[:reporter]
15
+ if opts[:uri]
16
+ @uri = opts[:uri]
17
+ resource = check_resource(@uri, 'Service document', Names::AppMediaType, @reporter)
18
+ raise StandardError, "Service document not found at: #{@uri}" unless resource
19
+
20
+ @service = REXML::Document.new(resource.body, { :raw => nil })
21
+ end
22
+ end
23
+
24
+ def collections(uri = @uri)
25
+ nodes = REXML::XPath.match(@service, '//app:collection', Names::XmlNamespaces)
26
+ nodes.collect { |n| CollElement.new(n, uri) }
10
27
  end
11
28
  end
12
29
  end
@@ -1,9 +1,14 @@
1
1
  module Ape
2
2
  module Util
3
- def self.included(base)
4
- base.extend ClassMethods
3
+ def self.included(base)
4
+ base.extend ClassMethods
5
5
  include InstanceMethods
6
6
  end
7
+
8
+ def self.extended(base)
9
+ base.extend InstanceMethods
10
+ base.extend ClassMethods
11
+ end
7
12
 
8
13
  module InstanceMethods
9
14
  =begin
@@ -20,9 +25,9 @@ module Ape
20
25
 
21
26
  # * Get it, make sure it has the right content-type
22
27
  worked = resource.get(content_type)
23
- reporter.save_dialog(name, resource)
28
+ reporter.save_dialog(name, resource) if report
24
29
 
25
- reporter.security_warning(self) if (resource.security_warning)
30
+ reporter.security_warning(self) if (resource.security_warning && report)
26
31
 
27
32
  if !worked
28
33
  # oops, couldn't even get get it
@@ -32,7 +37,6 @@ module Ape
32
37
  elsif resource.last_error
33
38
  # oops, media-type problem
34
39
  reporter.error(self, "#{name}: #{resource.last_error}", name) if report
35
-
36
40
  else
37
41
  # resource fetched and is of right type
38
42
  reporter.success(self, "#{name}: it exists and is served properly.", name) if report
@@ -48,7 +52,7 @@ module Ape
48
52
  resolvers or samples.
49
53
  =end
50
54
  def resolve_plugin(key, dir, suffix, drop_underlines = false)
51
- [File.dirname(__FILE__), Ape.home].each do |path|
55
+ [File.dirname(__FILE__), ::Ape.home].each do |path|
52
56
  Dir[File.join(path, "#{dir}/*.rb")].each do |file|
53
57
  require file
54
58
  plugin_name = file.gsub(/(.+\/#{dir}\/)(.+)(_#{suffix}.rb)/, '\2')
@@ -64,4 +68,4 @@ resolvers or samples.
64
68
  end
65
69
  end
66
70
  end
67
- end
71
+ end
@@ -11,7 +11,7 @@ module Ape
11
11
 
12
12
  def self.custom_validators(reporter, authent)
13
13
  validators = []
14
- Dir[Ape.home + '/validators/*.rb'].each do |v|
14
+ Dir[::Ape.home + '/validators/*.rb'].each do |v|
15
15
  require v
16
16
  class_name = v.gsub(/(.+\/validators\/)(.+)(.rb)/, '\2').gsub(/(^|_)(.)/) { $2.upcase }
17
17
  validator = eval("#{class_name}.new", binding, __FILE__, __LINE__)
@@ -29,7 +29,7 @@ module Ape
29
29
  return
30
30
  end
31
31
 
32
- my_entry = Entry.new(Samples.basic_entry)
32
+ my_entry = Entry.new(:text => Samples.basic_entry)
33
33
 
34
34
  # ask it to use this in the URI
35
35
  slug_num = rand(100000)
@@ -71,7 +71,7 @@ module Ape
71
71
  reporter.info(self, "Examining the new entry as retrieved using Location header in POST response:")
72
72
 
73
73
  begin
74
- new_entry = Entry.new(new_entry.body, location)
74
+ new_entry = Entry.new(:text => new_entry.body, :uri => location)
75
75
  rescue REXML::ParseException
76
76
  prob = $!.to_s.gsub(/\n/, '<br/>')
77
77
  reporter.error(self, "New entry is not well-formed: #{prob}")
@@ -99,7 +99,6 @@ module Ape
99
99
  # * fetch the feed again and check that version
100
100
  from_feed = find_entry(collection_uri, "entry collection", entry_id)
101
101
  if from_feed.class == String
102
- reporter.success(self, "About to check #{collection_uri}")
103
102
  Feed.read(collection_uri, "Can't find entry in collection", reporter)
104
103
  reporter.error(self, "New entry didn't show up in the collections feed.")
105
104
  return
@@ -30,7 +30,7 @@ module Ape
30
30
  return
31
31
  end
32
32
 
33
- ids = entries.map { |e| e.child_content('id)') }
33
+ ids = entries.map { |e| e.child_content('id') }
34
34
 
35
35
  # let's update one of them; have to fetch it first to get the ETag
36
36
  two_media = entries[1].link('edit-media')
@@ -75,4 +75,4 @@ module Ape
75
75
  reporter.success(self, "Entries correctly ordered after update of multi-post.")
76
76
  end
77
77
  end
78
- end
78
+ end
@@ -25,7 +25,6 @@ module Ape
25
25
  slug_re = %r{apix.?#{slug_num}}
26
26
  poster.set_header('Slug', slug)
27
27
 
28
- #poster.set_header('Slug', slug)
29
28
  worked = poster.post('image/jpeg', Samples.picture)
30
29
  reporter.save_dialog(name, poster)
31
30
  if !worked
@@ -50,7 +49,7 @@ module Ape
50
49
 
51
50
  # * See if the <content src= is there and usable
52
51
  begin
53
- media_link_entry = Entry.new(media_link_entry.body, mle_uri)
52
+ media_link_entry = Entry.new(:text => media_link_entry.body, :uri => mle_uri)
54
53
  rescue REXML::ParseException
55
54
  prob = $!.to_s.gsub(/\n/, '<br/>')
56
55
  reporter.error(self, "Media link entry is not well-formed: #{prob}")
@@ -22,7 +22,7 @@ module Ape
22
22
  return unless entry
23
23
 
24
24
  begin
25
- entry = Entry.new(entry.body, location)
25
+ entry = Entry.new(:text => entry.body, :uri => location)
26
26
  rescue REXML::ParseException
27
27
  prob = $!.to_s.gsub(/\n/, '<br/>')
28
28
  reporter.error(self, "New entry is not well-formed: #{prob}")
@@ -6,30 +6,23 @@ module Ape
6
6
 
7
7
  def validate(opts = {})
8
8
  init_service_document(opts[:uri])
9
- raise ValidationError, "service document not found in: #{opts[uri]}" unless @service
10
9
  init_service_collections(opts[:uri])
11
- raise ValidationError unless @entry_collections && @media_collections
12
10
  end
13
11
 
14
12
  def init_service_document(uri)
15
13
  reporter.info(self, "TESTING: Service document and collections.")
16
- name = 'Retrieval of Service Document'
17
- service = check_resource(uri, name, Names::AppMediaType)
18
- return unless service
19
-
20
- # * XML-parse the service doc
21
- text = service.body
14
+
22
15
  begin
23
- @service = REXML::Document.new(text, { :raw => nil })
24
- rescue REXML::ParseException
16
+ @service_document = Service.new(:uri => uri, :reporter => reporter )
17
+ rescue Exception
25
18
  prob = $!.to_s.gsub(/\n/, '<br/>')
26
- reporter.error(self, "Service document not well-formed: #{prob}")
19
+ reporter.error(self, "Service document not usable: #{prob}")
27
20
  return
28
21
  end
29
22
 
30
23
  # RNC-validate the service doc
31
24
  Validator.instance(:schema, @reporter).validate(:schema => Samples.service_RNC,
32
- :title => 'Service doc', :doc => @service)
25
+ :title => 'Service doc', :doc => @service_document.service)
33
26
  end
34
27
 
35
28
  def init_service_collections(uri)
@@ -37,23 +30,20 @@ module Ape
37
30
  # the requested_* arguments are the requested collection titles; if
38
31
  # provided, try to match them, otherwise just pick the first listed
39
32
  #
40
- begin
41
- @service_collections = Service.collections(@service, uri)
42
- rescue Exception
43
- reporter.error(self, "Couldn't read collections from service doc: #{$!}")
44
- return
45
- end
46
-
47
- if @service_collections.length > 0
33
+ collections = @service_document.collections
34
+ if collections.length > 0
35
+
48
36
  reporter.start_list(self, "Found these collections")
49
- @service_collections.each do |collection|
37
+ collections.each do |collection|
50
38
  reporter.list_item("'#{collection.title}' " +
51
- "accepts #{collection.accept.join(', ')}")
39
+ "accepts #{collection.accept.join(', ')}")
52
40
 
53
- if (collection.accept.index(Names::AtomEntryMediaType))
41
+ if collection.accept?(Names::AtomEntryMediaType)
54
42
  @entry_collections ||= []
55
43
  @entry_collections << collection
56
- else
44
+ end
45
+
46
+ if collection.accept?('image/jpeg')
57
47
  @media_collections ||= []
58
48
  @media_collections << collection
59
49
  end
@@ -1,8 +1,8 @@
1
- module Ape
2
- module VERSION
1
+ module Ape #:nodoc:
2
+ module VERSION #:nodoc:
3
3
  MAJOR = 1
4
- MINOR = 5
5
- TINY = 1
4
+ MINOR = 6
5
+ TINY = 0
6
6
 
7
7
  STRING = [MAJOR, MINOR, TINY].join('.')
8
8
  end
@@ -15,7 +15,7 @@ module Writer
15
15
  end
16
16
  end
17
17
  Ape::Invoker.send(:include, Writer)
18
-
18
+
19
19
  module ApeAccessors
20
20
  def service=(service)
21
21
  @service = service
@@ -47,3 +47,26 @@ class ValidatorMock < Ape::Validator
47
47
  deterministic
48
48
  requires_presence_of :entry_collection
49
49
  end
50
+
51
+ def collection(title, accept = ['application/atom+xml;type=entry'])
52
+ collection = "<collection href=\"http://localhost\">" +
53
+ "<atom:title>#{title}</atom:title>"
54
+ accept.each do |a|
55
+ collection += "<accept>#{a}</accept>"
56
+ end
57
+ collection += "</collection>"
58
+ end
59
+
60
+ def service(&block)
61
+ service = "<service xmlns=\"http://www.w3.org/2007/app\"" +
62
+ " xmlns:atom=\"http://www.w3.org/2005/Atom\"><workspace>"
63
+ service += yield
64
+ service += "</workspace></service>"
65
+ REXML::Document.new(service)
66
+ end
67
+
68
+ def collections(&block)
69
+ s = service(&block)
70
+ nodes = REXML::XPath.match(s, '//app:collection', Ape::Names::XmlNamespaces)
71
+ nodes.collect { |n| Ape::CollElement.new(n) }
72
+ end
@@ -10,26 +10,26 @@ class ApeTest < Test::Unit::TestCase
10
10
  end
11
11
 
12
12
  def test_check_manifest_raises_validation_error
13
- @ape.entry_collections = service { collection('Attachments', ['image/jpg']) }
13
+ @ape.media_collections = collections { collection('Attachments', ['image/jpg']) }
14
14
  assert_raise(Ape::ValidationError) {
15
- variables = @ape.check_manifest(ValidatorMock.new)
15
+ @ape.check_manifest(ValidatorMock.new)
16
16
  }
17
17
  end
18
18
 
19
19
  def test_check_manifest_assert_first_entry_collection
20
- @ape.entry_collections = service { collection('Posts') }
20
+ @ape.entry_collections = collections { collection('Posts') }
21
21
  variables = @ape.check_manifest(ValidatorMock.new)
22
22
  assert_equal('Posts', variables[:entry_collection].title)
23
23
  end
24
24
 
25
25
  def test_check_manifest_assert_first_media_collection
26
- @ape.media_collections = service { collection('Attachments', ['image/jpg']) }
26
+ @ape.media_collections = collections { collection('Attachments', ['image/jpg']) }
27
27
  variables = stub_manifest([:media_collection])
28
28
  assert_equal('Attachments', variables[:media_collection].title)
29
29
  end
30
30
 
31
31
  def test_check_manifest_assert_select_last_collection
32
- @ape.entry_collections = service {
32
+ @ape.entry_collections = collections {
33
33
  collection('Posts') +
34
34
  collection('Comments')
35
35
  }
@@ -39,7 +39,7 @@ class ApeTest < Test::Unit::TestCase
39
39
  end
40
40
 
41
41
  def test_select_first_collection_by_type
42
- @ape.entry_collections = service {
42
+ @ape.entry_collections = collections {
43
43
  collection('Posts') +
44
44
  collection('Attachments', ['image/jpg']) +
45
45
  collection('Attachments2', ['image/png'])
@@ -49,7 +49,7 @@ class ApeTest < Test::Unit::TestCase
49
49
  end
50
50
 
51
51
  def test_select_first_collection_by_title
52
- @ape.entry_collections = service {
52
+ @ape.entry_collections = collections {
53
53
  collection('Posts') +
54
54
  collection('Attachments', ['image/jpg'])
55
55
  }
@@ -58,7 +58,7 @@ class ApeTest < Test::Unit::TestCase
58
58
  end
59
59
 
60
60
  def test_select_by_name_raises_validation_error
61
- @ape.entry_collections = service {
61
+ @ape.entry_collections = collections {
62
62
  collection('Posts') +
63
63
  collection('Attachments', ['image/jpg'])
64
64
  }
@@ -73,20 +73,4 @@ class ApeTest < Test::Unit::TestCase
73
73
  @ape.check_manifest(validator)
74
74
  end
75
75
 
76
- def collection(title, accept = ['application/atom+xml;type=entry'])
77
- collection = "<collection href=\"http://localhost\">" +
78
- "<atom:title>#{title}</atom:title>"
79
- accept.each do |a|
80
- collection += "<accept>#{a}</accept>"
81
- end
82
- collection += "</collection>"
83
- end
84
-
85
- def service(&block)
86
- service = "<service xmlns=\"http://www.w3.org/2007/app\"" +
87
- " xmlns:atom=\"http://www.w3.org/2005/Atom\"><workspace>"
88
- service += yield
89
- service += "</workspace></service>"
90
- Ape::Service.collections(REXML::Document.new(service), nil)
91
- end
92
76
  end